PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 2.2.0
Page Builder: Pagelayer – Drag and Drop website builder v2.2.0
2.2.1 2.2.0 2.1.9 2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 trunk 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 1.0.0 1.0.2 1.0.3 1.0.4 1.0.5 All 129 releases
← All changes | main/abilitiesregister.php +19 -265 trunk2.2.0 View file →
@@ -69,40 +69,12 @@
69 69 public static function can_edit_posts() {
70 70 return current_user_can('edit_posts');
71 71 }
72 72
73 - public static function can_edit_pages() {
74 - return current_user_can('edit_pages');
75 - }
76 -
77 - public static function can_publish_pages() {
78 - return current_user_can('publish_pages');
79 - }
80 -
81 - public static function can_publish_posts() {
82 - return current_user_can('publish_posts');
83 - }
84 -
85 - public static function can_delete_pages() {
86 - return current_user_can('delete_pages');
87 - }
88 -
89 - public static function can_delete_posts() {
90 - return current_user_can('delete_posts');
91 - }
92 -
93 - public static function can_edit_theme_options() {
94 - return current_user_can('edit_theme_options');
95 - }
96 -
97 73 public static function can_manage_options() {
98 74 return current_user_can('manage_options');
99 75 }
100 76
101 - public static function can_upload_files() {
102 - return current_user_can('upload_files');
103 - }
104 -
105 77 // ------------------------------------------------------------------
106 78 // Shared helpers
107 79 // ------------------------------------------------------------------
108 80
@@ -151,11 +123,8 @@
151 123 return $out;
152 124 }
153 125
154 126 public static function maybe_update_global_styles($input) {
155 - if (!current_user_can('manage_options')) {
156 - return;
157 - }
158 127 if (isset($input['global_colors'])) {
159 128 update_option('pagelayer_global_colors', json_encode(self::normalize_global_map($input['global_colors'])));
160 129 }
161 130 if (isset($input['global_fonts'])) {
@@ -2109,9 +2078,8 @@
2109 2078 'required' => array('title', 'type', 'pagelayer_data'),
2110 2079 'additionalProperties' => false
2111 2080 ),
2112 2081 'execute' => array(__CLASS__, 'execute_create_template'),
2113 - 'perm' => array(__CLASS__, 'can_edit_theme_options'),
2114 2082 ),
2115 2083 'update_template' => array(
2116 2084 'label' => __('Update Template', 'pagelayer'),
2117 2085 'description' => __('Update an existing Pagelayer theme template title, layout data, or display conditions. Same header/footer rules as create_template: Include / Full Site is enforced, and a header needs a Primary Menu widget with a real nav_list.', 'pagelayer'),
@@ -2129,9 +2097,8 @@
2129 2097 'required' => array('template_id'),
2130 2098 'additionalProperties' => false
2131 2099 ),
2132 2100 'execute' => array(__CLASS__, 'execute_update_template'),
2133 - 'perm' => array(__CLASS__, 'can_edit_theme_options'),
2134 2101 ),
2135 2102 'delete_template' => array(
2136 2103 'label' => __('Delete Template', 'pagelayer'),
2137 2104 'description' => __('Delete a Pagelayer theme template by ID.', 'pagelayer'),
@@ -2142,9 +2109,8 @@
2142 2109 'required' => array('template_id'),
2143 2110 'additionalProperties' => false
2144 2111 ),
2145 2112 'execute' => array(__CLASS__, 'execute_delete_template'),
2146 - 'perm' => array(__CLASS__, 'can_edit_theme_options'),
2147 2113 ),
2148 2114 'save_template' => array(
2149 2115 'label' => __('Save Section Template', 'pagelayer'),
2150 2116 'description' => __('Save a specific page section or layout to the local template library.', 'pagelayer'),
@@ -2159,9 +2125,8 @@
2159 2125 'required' => array('name', 'post_id'),
2160 2126 'additionalProperties' => false
2161 2127 ),
2162 2128 'execute' => array(__CLASS__, 'execute_save_template'),
2163 - 'perm' => array(__CLASS__, 'can_edit_theme_options'),
2164 2129 ),
2165 2130 'insert_template' => array(
2166 2131 'label' => __('Insert Template', 'pagelayer'),
2167 2132 'description' => __('Insert a saved template layout structure into a target container on a page.', 'pagelayer'),
@@ -2267,9 +2232,8 @@
2267 2232 'required' => array('site_name', 'pages'),
2268 2233 'additionalProperties' => false
2269 2234 ),
2270 2235 'execute' => array(__CLASS__, 'execute_create_website'),
2271 - 'perm' => array(__CLASS__, 'can_manage_options'),
2272 2236 ),
2273 2237 'create_page' => array(
2274 2238 'label' => __('Create Page', 'pagelayer'),
2275 2239 'description' => __('Create one page with Pagelayer builder data, status and global styles. FASTEST PATH: send section specs ({"section":"hero",...}) instead of hand-written node trees — see fast_path_sections in get_data_structure. Enforced quality gate: rejected unsaved if any widget keeps its placeholder text, uses an attr not in its schema, sets a gated attr without its companion, or uses an unregistered tag. Styling must live in attrs — an inline style attribute or <style> block in rich text is rejected and cannot be bypassed. Missing images are only a warning. Read get_data_structure and get_widget_schema first.', 'pagelayer'),
@@ -2290,9 +2254,8 @@
2290 2254 'required' => array('title', 'pagelayer_data'),
2291 2255 'additionalProperties' => false
2292 2256 ),
2293 2257 'execute' => array(__CLASS__, 'execute_create_page'),
2294 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2295 2258 ),
2296 2259 'update_page' => array(
2297 2260 'label' => __('Update Page', 'pagelayer'),
2298 2261 'description' => __('Update page title, status, or the WHOLE pagelayer_data tree. Sending pagelayer_data REPLACES the entire layout and discards any human edits made in the editor since — to change part of a page use update_element/add_element/change_styles instead, which are far cheaper and non-destructive. Same enforced quality gate as create_page, including the no-inline-CSS-in-rich-text rule.', 'pagelayer'),
@@ -2309,9 +2272,8 @@
2309 2272 'required' => array('post_id'),
2310 2273 'additionalProperties' => false
2311 2274 ),
2312 2275 'execute' => array(__CLASS__, 'execute_update_page'),
2313 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2314 2276 ),
2315 2277 'get_page' => array(
2316 2278 'label' => __('Get Page', 'pagelayer'),
2317 2279 'description' => __('Page details plus a compact outline of its elements (id, tag, text preview) — enough to locate anything you want to edit. Pass element_id for one node in full, or mode:"full" for the whole raw tree (large; only needed to rewrite the entire layout).', 'pagelayer'),
@@ -2352,9 +2314,8 @@
2352 2314 'required' => array('post_id'),
2353 2315 'additionalProperties' => false
2354 2316 ),
2355 2317 'execute' => array(__CLASS__, 'execute_publish_page'),
2356 - 'perm' => array(__CLASS__, 'can_publish_pages'),
2357 2318 ),
2358 2319 'duplicate_page' => array(
2359 2320 'label' => __('Duplicate Page', 'pagelayer'),
2360 2321 'description' => __('Clone an existing page and regenerate all Pagelayer element IDs.', 'pagelayer'),
@@ -2368,9 +2329,8 @@
2368 2329 'required' => array('post_id'),
2369 2330 'additionalProperties' => false
2370 2331 ),
2371 2332 'execute' => array(__CLASS__, 'execute_duplicate_page'),
2372 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2373 2333 ),
2374 2334 'delete_page' => array(
2375 2335 'label' => __('Delete Page', 'pagelayer'),
2376 2336 'description' => __('Trash or delete a page by ID.', 'pagelayer'),
@@ -2384,9 +2344,8 @@
2384 2344 'required' => array('post_id'),
2385 2345 'additionalProperties' => false
2386 2346 ),
2387 2347 'execute' => array(__CLASS__, 'execute_delete_page'),
2388 - 'perm' => array(__CLASS__, 'can_delete_pages'),
2389 2348 ),
2390 2349 'preview_page' => array(
2391 2350 'label' => __('Preview Page', 'pagelayer'),
2392 2351 'description' => __('Retrieve the live view/preview URL for a post or page.', 'pagelayer'),
@@ -2427,9 +2386,8 @@
2427 2386 'required' => array('post_id', 'pagelayer_data'),
2428 2387 'additionalProperties' => false
2429 2388 ),
2430 2389 'execute' => array(__CLASS__, 'execute_create_design_ui'),
2431 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2432 2390 ),
2433 2391 'edit_layout' => array(
2434 2392 'label' => __('Edit Page Layout', 'pagelayer'),
2435 2393 'description' => __('Replace the full layout structure of a Pagelayer page. ENFORCED content-quality gate on the new layout — no placeholder text, no missing images, no unregistered widgets. Pass skip_validation:true to bypass for an intentional draft.', 'pagelayer'),
@@ -2446,9 +2404,8 @@
2446 2404 'required' => array('post_id', 'pagelayer_data'),
2447 2405 'additionalProperties' => false
2448 2406 ),
2449 2407 'execute' => array(__CLASS__, 'execute_edit_layout'),
2450 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2451 2408 ),
2452 2409 'change_styles' => array(
2453 2410 'label' => __('Change Element Styles', 'pagelayer'),
2454 2411 'description' => __('Batch update style properties on page elements by ID or widget tag.', 'pagelayer'),
@@ -2462,9 +2419,8 @@
2462 2419 'required' => array('post_id', 'styles'),
2463 2420 'additionalProperties' => false
2464 2421 ),
2465 2422 'execute' => array(__CLASS__, 'execute_change_styles'),
2466 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2467 2423 ),
2468 2424 'get_data_structure' => array(
2469 2425 'label' => __('Get Data Structure Guide', 'pagelayer'),
2470 2426 'description' => __('How pagelayer_data nodes, global $color tokens and gated attributes work. Default topic covers editing; pass topic:"quality"/"widgets"/"workflow"/"all" when building a page from scratch.', 'pagelayer'),
@@ -2525,9 +2481,8 @@
2525 2481 'required' => array('post_id', 'element_id'),
2526 2482 'additionalProperties' => false
2527 2483 ),
2528 2484 'execute' => array(__CLASS__, 'execute_update_element'),
2529 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2530 2485 ),
2531 2486 'add_element' => array(
2532 2487 'label' => __('Add Element', 'pagelayer'),
2533 2488 'description' => __('Insert a new element node into a parent container at an index. Enforced quality gate on the new element (no placeholder text, valid attrs, registered tag); skip_validation:true bypasses it. Inline CSS in rich text is always rejected.', 'pagelayer'),
@@ -2544,9 +2499,8 @@
2544 2499 'required' => array('post_id', 'element'),
2545 2500 'additionalProperties' => false
2546 2501 ),
2547 2502 'execute' => array(__CLASS__, 'execute_add_element'),
2548 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2549 2503 ),
2550 2504 'delete_element' => array(
2551 2505 'label' => __('Delete Element', 'pagelayer'),
2552 2506 'description' => __('Remove an element from a page by its pagelayer-id.', 'pagelayer'),
@@ -2560,9 +2514,8 @@
2560 2514 'required' => array('post_id', 'element_id'),
2561 2515 'additionalProperties' => false
2562 2516 ),
2563 2517 'execute' => array(__CLASS__, 'execute_delete_element'),
2564 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2565 2518 ),
2566 2519 'move_element' => array(
2567 2520 'label' => __('Move Element', 'pagelayer'),
2568 2521 'description' => __('Relocate an element to a target parent container or index.', 'pagelayer'),
@@ -2578,9 +2531,8 @@
2578 2531 'required' => array('post_id', 'element_id'),
2579 2532 'additionalProperties' => false
2580 2533 ),
2581 2534 'execute' => array(__CLASS__, 'execute_move_element'),
2582 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2583 2535 ),
2584 2536 'duplicate_element' => array(
2585 2537 'label' => __('Duplicate Element', 'pagelayer'),
2586 2538 'description' => __('Clone an element by ID, generating new IDs for all child nodes.', 'pagelayer'),
@@ -2594,9 +2546,8 @@
2594 2546 'required' => array('post_id', 'element_id'),
2595 2547 'additionalProperties' => false
2596 2548 ),
2597 2549 'execute' => array(__CLASS__, 'execute_duplicate_element'),
2598 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2599 2550 ),
2600 2551 'begin_transaction' => array(
2601 2552 'label' => __('Begin Transaction', 'pagelayer'),
2602 2553 'description' => __('Backup page layout state before multi-step modifications.', 'pagelayer'),
@@ -2607,9 +2558,8 @@
2607 2558 'required' => array('post_id'),
2608 2559 'additionalProperties' => false
2609 2560 ),
2610 2561 'execute' => array(__CLASS__, 'execute_begin_transaction'),
2611 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2612 2562 ),
2613 2563 'commit_transaction' => array(
2614 2564 'label' => __('Commit Transaction', 'pagelayer'),
2615 2565 'description' => __('Commit layout changes and delete backup state.', 'pagelayer'),
@@ -2620,9 +2570,8 @@
2620 2570 'required' => array('post_id'),
2621 2571 'additionalProperties' => false
2622 2572 ),
2623 2573 'execute' => array(__CLASS__, 'execute_commit_transaction'),
2624 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2625 2574 ),
2626 2575 'rollback_transaction' => array(
2627 2576 'label' => __('Rollback Transaction', 'pagelayer'),
2628 2577 'description' => __('Restore original page layout state from transaction backup.', 'pagelayer'),
@@ -2633,9 +2582,8 @@
2633 2582 'required' => array('post_id'),
2634 2583 'additionalProperties' => false
2635 2584 ),
2636 2585 'execute' => array(__CLASS__, 'execute_rollback_transaction'),
2637 - 'perm' => array(__CLASS__, 'can_edit_pages'),
2638 2586 ),
2639 2587 );
2640 2588
2641 2589 foreach ($abilities as $id => $def) {
@@ -2666,9 +2614,8 @@
2666 2614 'required' => array('title', 'pagelayer_data'),
2667 2615 'additionalProperties' => false
2668 2616 ),
2669 2617 'execute' => array(__CLASS__, 'execute_create_post'),
2670 - 'perm' => array(__CLASS__, 'can_edit_posts'),
2671 2618 ),
2672 2619 'update_post' => array(
2673 2620 'label' => __('Update Individual Post', 'pagelayer'),
2674 2621 'description' => __('Update an existing blog post title, layout data, categories, tags, excerpt, or status.', 'pagelayer'),
@@ -2688,9 +2635,8 @@
2688 2635 'required' => array('post_id'),
2689 2636 'additionalProperties' => false
2690 2637 ),
2691 2638 'execute' => array(__CLASS__, 'execute_update_post'),
2692 - 'perm' => array(__CLASS__, 'can_edit_posts'),
2693 2639 ),
2694 2640 'get_post' => array(
2695 2641 'label' => __('Get Individual Post', 'pagelayer'),
2696 2642 'description' => __('Retrieve blog post details, categories, tags, excerpt, featured image, and pagelayer_data.', 'pagelayer'),
@@ -2728,9 +2674,8 @@
2728 2674 'required' => array('post_id'),
2729 2675 'additionalProperties' => false
2730 2676 ),
2731 2677 'execute' => array(__CLASS__, 'execute_publish_post'),
2732 - 'perm' => array(__CLASS__, 'can_publish_posts'),
2733 2678 ),
2734 2679 'duplicate_post' => array(
2735 2680 'label' => __('Duplicate Individual Post', 'pagelayer'),
2736 2681 'description' => __('Clone an existing blog post with new Pagelayer element IDs.', 'pagelayer'),
@@ -2744,9 +2689,8 @@
2744 2689 'required' => array('post_id'),
2745 2690 'additionalProperties' => false
2746 2691 ),
2747 2692 'execute' => array(__CLASS__, 'execute_duplicate_post'),
2748 - 'perm' => array(__CLASS__, 'can_edit_posts'),
2749 2693 ),
2750 2694 'delete_post' => array(
2751 2695 'label' => __('Delete Individual Post', 'pagelayer'),
2752 2696 'description' => __('Trash or delete a blog post by ID.', 'pagelayer'),
@@ -2760,9 +2704,8 @@
2760 2704 'required' => array('post_id'),
2761 2705 'additionalProperties' => false
2762 2706 ),
2763 2707 'execute' => array(__CLASS__, 'execute_delete_post'),
2764 - 'perm' => array(__CLASS__, 'can_delete_posts'),
2765 2708 ),
2766 2709 );
2767 2710
2768 2711 foreach ($abilities as $id => $def) {
@@ -2785,9 +2728,8 @@
2785 2728 'required' => array('url'),
2786 2729 'additionalProperties' => false
2787 2730 ),
2788 2731 'execute' => array(__CLASS__, 'execute_upload_media'),
2789 - 'perm' => array(__CLASS__, 'can_upload_files'),
2790 2732 ),
2791 2733 );
2792 2734
2793 2735 foreach ($abilities as $id => $def) {
@@ -3043,12 +2985,8 @@
3043 2985 if (empty($section_id) || !$post_id || !get_post($post_id)) {
3044 2986 return new \WP_Error('invalid_input', __('Valid section_id and post_id are required.', 'pagelayer'));
3045 2987 }
3046 2988
3047 - if (!current_user_can('edit_post', $post_id)) {
3048 - return new \WP_Error('forbidden', __('You are not allowed to edit this post.', 'pagelayer'), array('status' => 403));
3049 - }
3050 -
3051 2989 global $pagelayer;
3052 2990 $license_key = !empty($pagelayer->license['license']) ? $pagelayer->license['license'] : '';
3053 2991 $url = 'https://api.pagelayer.com/library.php?give_id=' . rawurlencode($section_id) . '&license=' . rawurlencode($license_key) . '&url=' . rawurlencode(site_url());
3054 2992
@@ -3106,10 +3044,10 @@
3106 3044 * and its own judgement about layout, matching the requested niche/brand.
3107 3045 */
3108 3046 public static function execute_scrape_website_content($input) {
3109 3047 $url = isset($input['url']) ? esc_url_raw($input['url']) : '';
3110 - if (empty($url) || !wp_http_validate_url($url)) {
3111 - return new \WP_Error('invalid_url', __('A valid public URL is required.', 'pagelayer'));
3048 + if (empty($url)) {
3049 + return new \WP_Error('missing_url', __('URL is required.', 'pagelayer'));
3112 3050 }
3113 3051
3114 3052 $response = wp_remote_get($url, array(
3115 3053 'timeout' => 25,
@@ -3220,11 +3158,8 @@
3220 3158 );
3221 3159 }
3222 3160
3223 3161 public static function execute_update_styles($input) {
3224 - if (!current_user_can('manage_options')) {
3225 - return new \WP_Error('forbidden', __('You do not have permission to update global styles.', 'pagelayer'), array('status' => 403));
3226 - }
3227 3162 self::maybe_update_global_styles($input);
3228 3163 return array('success' => true);
3229 3164 }
3230 3165
@@ -3727,12 +3662,8 @@
3727 3662 unset($node);
3728 3663 }
3729 3664
3730 3665 public static function execute_create_template($input) {
3731 - if (!current_user_can('edit_theme_options')) {
3732 - return new \WP_Error('forbidden', __('You are not allowed to create theme templates.', 'pagelayer'), array('status' => 403));
3733 - }
3734 -
3735 3666 $title = isset($input['title']) ? sanitize_text_field($input['title']) : '';
3736 3667 $type = isset($input['type']) ? sanitize_text_field($input['type']) : 'general';
3737 3668 $p_data = isset($input['pagelayer_data']) && is_array($input['pagelayer_data']) ? $input['pagelayer_data'] : array();
3738 3669
@@ -3838,12 +3769,8 @@
3838 3769 if (!$template_id || get_post_type($template_id) !== 'pagelayer-template') {
3839 3770 return new \WP_Error('invalid_template', __('Template not found.', 'pagelayer'));
3840 3771 }
3841 3772
3842 - if (!current_user_can('edit_theme_options') || !current_user_can('edit_post', $template_id)) {
3843 - return new \WP_Error('forbidden', __('You are not allowed to edit this template.', 'pagelayer'), array('status' => 403));
3844 - }
3845 -
3846 3773 $type = isset($input['type'])
3847 3774 ? sanitize_text_field($input['type'])
3848 3775 : (string) get_post_meta($template_id, 'pagelayer_template_type', true);
3849 3776
@@ -3888,12 +3815,8 @@
3888 3815 if (!$template_id || get_post_type($template_id) !== 'pagelayer-template') {
3889 3816 return new \WP_Error('invalid_template', __('Template not found.', 'pagelayer'));
3890 3817 }
3891 3818
3892 - if (!current_user_can('edit_theme_options') || !current_user_can('delete_post', $template_id)) {
3893 - return new \WP_Error('forbidden', __('You are not allowed to delete this template.', 'pagelayer'), array('status' => 403));
3894 - }
3895 -
3896 3819 $res = wp_delete_post($template_id, true);
3897 3820 return array('success' => (bool)$res);
3898 3821 }
3899 3822
@@ -4029,12 +3952,8 @@
4029 3952 );
4030 3953 }
4031 3954
4032 3955 public static function execute_create_menu($input) {
4033 - if (!current_user_can('manage_options') && !current_user_can('edit_theme_options')) {
4034 - return new \WP_Error('forbidden', __('You are not allowed to manage navigation menus.', 'pagelayer'), array('status' => 403));
4035 - }
4036 -
4037 3956 $name = isset($input['name']) ? sanitize_text_field($input['name']) : '';
4038 3957 if ($name === '') {
4039 3958 return new \WP_Error('missing_name', __('A menu name is required.', 'pagelayer'));
4040 3959 }
@@ -4257,12 +4176,8 @@
4257 4176 return self::serialize_layout_to_blocks(array($node));
4258 4177 }
4259 4178
4260 4179 public static function execute_delete_menu($input) {
4261 - if (!current_user_can('manage_options') && !current_user_can('edit_theme_options')) {
4262 - return new \WP_Error('forbidden', __('You are not allowed to delete navigation menus.', 'pagelayer'), array('status' => 403));
4263 - }
4264 -
4265 4180 $menu = self::resolve_menu(isset($input['menu']) ? sanitize_text_field($input['menu']) : '');
4266 4181 if (!$menu) {
4267 4182 return new \WP_Error('invalid_menu', __('Navigation menu not found.', 'pagelayer'));
4268 4183 }
@@ -4289,16 +4204,8 @@
4289 4204 if (!$post_id || get_post_type($post_id) !== 'page') {
4290 4205 return new \WP_Error('invalid_page', __('Page not found.', 'pagelayer'));
4291 4206 }
4292 4207
4293 - if (!current_user_can('edit_post', $post_id)) {
4294 - return new \WP_Error('forbidden', __('You are not allowed to edit this page.', 'pagelayer'), array('status' => 403));
4295 - }
4296 -
4297 - if (isset($input['status']) && $input['status'] === 'publish' && !current_user_can('publish_pages')) {
4298 - return new \WP_Error('forbidden', __('You are not allowed to publish pages.', 'pagelayer'), array('status' => 403));
4299 - }
4300 -
4301 4208 if (isset($input['title'])) {
4302 4209 wp_update_post(array('ID' => $post_id, 'post_title' => sanitize_text_field($input['title'])));
4303 4210 }
4304 4211 if (isset($input['status'])) {
@@ -4399,18 +4306,12 @@
4399 4306 }
4400 4307
4401 4308 public static function execute_publish_page($input) {
4402 4309 $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
4403 - $post = get_post($post_id);
4404 - if (!$post_id || !$post) {
4310 + if (!$post_id || !get_post($post_id)) {
4405 4311 return new \WP_Error('invalid_post', __('Post or page not found.', 'pagelayer'));
4406 4312 }
4407 4313
4408 - $cap = ($post->post_type === 'page') ? 'publish_pages' : 'publish_posts';
4409 - if (!current_user_can('edit_post', $post_id) || !current_user_can($cap)) {
4410 - return new \WP_Error('forbidden', __('You are not allowed to publish this item.', 'pagelayer'), array('status' => 403));
4411 - }
4412 -
4413 4314 wp_update_post(array('ID' => $post_id, 'post_status' => 'publish'));
4414 4315 return array('success' => true, 'url' => get_permalink($post_id));
4415 4316 }
4416 4317
@@ -4420,17 +4321,8 @@
4420 4321 if (!$post) {
4421 4322 return new \WP_Error('invalid_post', __('Post or page not found.', 'pagelayer'));
4422 4323 }
4423 4324
4424 - if (!current_user_can('edit_post', $post_id)) {
4425 - return new \WP_Error('forbidden', __('You are not allowed to duplicate this item.', 'pagelayer'), array('status' => 403));
4426 - }
4427 -
4428 - $cap = ($post->post_type === 'page') ? 'edit_pages' : 'edit_posts';
4429 - if (!current_user_can($cap)) {
4430 - return new \WP_Error('forbidden', __('You are not allowed to create this item.', 'pagelayer'), array('status' => 403));
4431 - }
4432 -
4433 4325 $title = isset($input['title']) ? sanitize_text_field($input['title']) : $post->post_title . ' (Copy)';
4434 4326
4435 4327 $new_id = wp_insert_post(array(
4436 4328 'post_title' => $title,
@@ -4480,12 +4372,8 @@
4480 4372 if (!$post_id || get_post_type($post_id) !== 'page') {
4481 4373 return new \WP_Error('invalid_page', __('Page not found.', 'pagelayer'));
4482 4374 }
4483 4375
4484 - if (!current_user_can('delete_post', $post_id)) {
4485 - return new \WP_Error('forbidden', __('You are not allowed to delete this page.', 'pagelayer'), array('status' => 403));
4486 - }
4487 -
4488 4376 $res = wp_delete_post($post_id, $force);
4489 4377 return array('success' => (bool)$res);
4490 4378 }
4491 4379
@@ -5270,16 +5158,8 @@
5270 5158 if (!$post || $post->post_type !== 'post') {
5271 5159 return new \WP_Error('invalid_post', __('Blog post not found.', 'pagelayer'));
5272 5160 }
5273 5161
5274 - if (!current_user_can('edit_post', $post_id)) {
5275 - return new \WP_Error('forbidden', __('You are not allowed to edit this post.', 'pagelayer'), array('status' => 403));
5276 - }
5277 -
5278 - if (isset($input['status']) && $input['status'] === 'publish' && !current_user_can('publish_posts')) {
5279 - return new \WP_Error('forbidden', __('You are not allowed to publish posts.', 'pagelayer'), array('status' => 403));
5280 - }
5281 -
5282 5162 if (isset($input['title'])) {
5283 5163 wp_update_post(array('ID' => $post_id, 'post_title' => sanitize_text_field($input['title'])));
5284 5164 }
5285 5165 if (isset($input['status'])) {
@@ -5411,12 +5291,8 @@
5411 5291 if (!$post_id || get_post_type($post_id) !== 'post') {
5412 5292 return new \WP_Error('invalid_post', __('Blog post not found.', 'pagelayer'));
5413 5293 }
5414 5294
5415 - if (!current_user_can('delete_post', $post_id)) {
5416 - return new \WP_Error('forbidden', __('You are not allowed to delete this post.', 'pagelayer'), array('status' => 403));
5417 - }
5418 -
5419 5295 $res = wp_delete_post($post_id, $force);
5420 5296 return array('success' => (bool)$res);
5421 5297 }
5422 5298
@@ -5429,24 +5305,8 @@
5429 5305 $title = isset($input['title']) ? sanitize_text_field($input['title']) : '';
5430 5306 $post_type = isset($input['post_type']) ? sanitize_text_field($input['post_type']) : 'page';
5431 5307 $status = isset($input['status']) ? sanitize_text_field($input['status']) : 'publish';
5432 5308
5433 - if ($post_type === 'page') {
5434 - if (!current_user_can('edit_pages')) {
5435 - return new \WP_Error('forbidden', __('You are not allowed to create pages.', 'pagelayer'), array('status' => 403));
5436 - }
5437 - if ($status === 'publish' && !current_user_can('publish_pages')) {
5438 - $status = 'draft';
5439 - }
5440 - } else {
5441 - if (!current_user_can('edit_posts')) {
5442 - return new \WP_Error('forbidden', __('You are not allowed to create posts.', 'pagelayer'), array('status' => 403));
5443 - }
5444 - if ($status === 'publish' && !current_user_can('publish_posts')) {
5445 - $status = 'draft';
5446 - }
5447 - }
5448 -
5449 5309 if (empty($title)) {
5450 5310 return new \WP_Error('missing_title', __('A title is required.', 'pagelayer'));
5451 5311 }
5452 5312
@@ -5535,13 +5395,13 @@
5535 5395 set_post_thumbnail($post_id, $img_id);
5536 5396 }
5537 5397 }
5538 5398
5539 - if (!empty($input['is_homepage']) && current_user_can('manage_options')) {
5399 + if (!empty($input['is_homepage'])) {
5540 5400 update_option('show_on_front', 'page');
5541 5401 update_option('page_on_front', $post_id);
5542 5402 }
5543 - if (!empty($input['is_posts_page']) && current_user_can('manage_options')) {
5403 + if (!empty($input['is_posts_page'])) {
5544 5404 update_option('page_for_posts', $post_id);
5545 5405 }
5546 5406
5547 5407 return array(
@@ -5893,11 +5753,8 @@
5893 5753 $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
5894 5754 if (!$post_id || !get_post($post_id)) {
5895 5755 return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
5896 5756 }
5897 - if (!current_user_can('edit_post', $post_id)) {
5898 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
5899 - }
5900 5757
5901 5758 if (!isset($input['pagelayer_data']) || !is_array($input['pagelayer_data'])) {
5902 5759 return new \WP_Error('missing_pagelayer_data', __('pagelayer_data is required.', 'pagelayer'));
5903 5760 }
@@ -5946,11 +5803,8 @@
5946 5803 $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
5947 5804 if (!$post_id || !get_post($post_id)) {
5948 5805 return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
5949 5806 }
5950 - if (!current_user_can('edit_post', $post_id)) {
5951 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
5952 - }
5953 5807
5954 5808 if (isset($input['pagelayer_data']) && is_array($input['pagelayer_data'])) {
5955 5809 $inline_css = self::inline_css_gate($input['pagelayer_data']);
5956 5810 if (is_wp_error($inline_css)) {
@@ -5982,11 +5836,8 @@
5982 5836 $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
5983 5837 if (!$post_id || !get_post($post_id)) {
5984 5838 return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
5985 5839 }
5986 - if (!current_user_can('edit_post', $post_id)) {
5987 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
5988 - }
5989 5840
5990 5841 $styles = isset($input['styles']) && is_array($input['styles']) ? $input['styles'] : array();
5991 5842 if (empty($styles)) {
5992 5843 return new \WP_Error('no_styles', __('No style changes provided.', 'pagelayer'));
@@ -6131,17 +5982,9 @@
6131 5982 );
6132 5983 }
6133 5984
6134 5985 public static function execute_find_elements($input) {
6135 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6136 - $post = get_post($post_id);
6137 - if (!$post) {
6138 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6139 - }
6140 - if ('publish' !== $post->post_status && !current_user_can('edit_post', $post_id)) {
6141 - return new \WP_Error('unauthorized', __('You do not have permission to view this post.', 'pagelayer'));
6142 - }
6143 -
5986 + $post_id = (int) $input['post_id'];
6144 5987 $data = get_post_meta($post_id, 'pagelayer-data', true);
6145 5988 if (!is_array($data)) {
6146 5989 return array('elements' => array());
6147 5990 }
@@ -6409,17 +6252,9 @@
6409 6252 return $id === null ? $ref : $id;
6410 6253 }
6411 6254
6412 6255 public static function execute_navigator($input) {
6413 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6414 - $post = get_post($post_id);
6415 - if (!$post) {
6416 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6417 - }
6418 - if ('publish' !== $post->post_status && !current_user_can('edit_post', $post_id)) {
6419 - return new \WP_Error('unauthorized', __('You do not have permission to view this post.', 'pagelayer'));
6420 - }
6421 -
6256 + $post_id = (int) $input['post_id'];
6422 6257 $data = get_post_meta($post_id, 'pagelayer-data', true);
6423 6258 if (!is_array($data)) {
6424 6259 return array('outline' => array());
6425 6260 }
@@ -6431,16 +6266,9 @@
6431 6266 );
6432 6267 }
6433 6268
6434 6269 public static function execute_update_element($input) {
6435 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6436 - if (!$post_id || !get_post($post_id)) {
6437 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6438 - }
6439 - if (!current_user_can('edit_post', $post_id)) {
6440 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6441 - }
6442 -
6270 + $post_id = (int) $input['post_id'];
6443 6271 $element_id = self::resolve_element_ref($post_id, sanitize_text_field($input['element_id']));
6444 6272 $data = get_post_meta($post_id, 'pagelayer-data', true);
6445 6273 if (!is_array($data)) {
6446 6274 return new \WP_Error('no_data', __('Page has no Pagelayer data.', 'pagelayer'));
@@ -6517,16 +6345,9 @@
6517 6345 return array('success' => true);
6518 6346 }
6519 6347
6520 6348 public static function execute_add_element($input) {
6521 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6522 - if (!$post_id || !get_post($post_id)) {
6523 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6524 - }
6525 - if (!current_user_can('edit_post', $post_id)) {
6526 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6527 - }
6528 -
6349 + $post_id = (int) $input['post_id'];
6529 6350 $parent_id = isset($input['parent_id']) ? self::resolve_element_ref($post_id, sanitize_text_field($input['parent_id'])) : '';
6530 6351
6531 6352 $inline_css_found = array();
6532 6353 self::scrub_node_inline_css($input['element'], $inline_css_found);
@@ -6597,16 +6418,9 @@
6597 6418 return new \WP_Error('parent_not_found', __('Parent element not found.', 'pagelayer'));
6598 6419 }
6599 6420
6600 6421 public static function execute_delete_element($input) {
6601 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6602 - if (!$post_id || !get_post($post_id)) {
6603 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6604 - }
6605 - if (!current_user_can('edit_post', $post_id)) {
6606 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6607 - }
6608 -
6422 + $post_id = (int) $input['post_id'];
6609 6423 $element_id = self::resolve_element_ref($post_id, sanitize_text_field($input['element_id']));
6610 6424 $data = get_post_meta($post_id, 'pagelayer-data', true);
6611 6425 if (!is_array($data)) {
6612 6426 return new \WP_Error('no_data', __('Page has no Pagelayer data.', 'pagelayer'));
@@ -6656,16 +6470,9 @@
6656 6470 return new \WP_Error('not_found', __('Element not found.', 'pagelayer'));
6657 6471 }
6658 6472
6659 6473 public static function execute_move_element($input) {
6660 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6661 - if (!$post_id || !get_post($post_id)) {
6662 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6663 - }
6664 - if (!current_user_can('edit_post', $post_id)) {
6665 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6666 - }
6667 -
6474 + $post_id = (int) $input['post_id'];
6668 6475 $element_id = self::resolve_element_ref($post_id, sanitize_text_field($input['element_id']));
6669 6476 $parent_id = isset($input['parent_id']) ? self::resolve_element_ref($post_id, sanitize_text_field($input['parent_id'])) : '';
6670 6477 $index = isset($input['index']) ? (int) $input['index'] : -1;
6671 6478
@@ -6760,16 +6567,9 @@
6760 6567 return new \WP_Error('parent_not_found', __('Target parent not found.', 'pagelayer'));
6761 6568 }
6762 6569
6763 6570 public static function execute_duplicate_element($input) {
6764 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6765 - if (!$post_id || !get_post($post_id)) {
6766 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6767 - }
6768 - if (!current_user_can('edit_post', $post_id)) {
6769 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6770 - }
6771 -
6571 + $post_id = (int) $input['post_id'];
6772 6572 $element_id = self::resolve_element_ref($post_id, sanitize_text_field($input['element_id']));
6773 6573 $data = get_post_meta($post_id, 'pagelayer-data', true);
6774 6574 if (!is_array($data)) {
6775 6575 return new \WP_Error('no_data', __('Page has no Pagelayer data.', 'pagelayer'));
@@ -6840,18 +6640,15 @@
6840 6640 return new \WP_Error('not_found', __('Element to duplicate not found.', 'pagelayer'));
6841 6641 }
6842 6642
6843 6643 public static function execute_begin_transaction($input) {
6844 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6644 + $post_id = (int) $input['post_id'];
6645 + $data = get_post_meta($post_id, 'pagelayer-data', true);
6845 6646 $post = get_post($post_id);
6846 6647 if (!$post) {
6847 6648 return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6848 6649 }
6849 - if (!current_user_can('edit_post', $post_id)) {
6850 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6851 - }
6852 6650
6853 - $data = get_post_meta($post_id, 'pagelayer-data', true);
6854 6651 $backup = array(
6855 6652 'data' => $data,
6856 6653 'content' => $post->post_content
6857 6654 );
@@ -6859,29 +6656,15 @@
6859 6656 return array('success' => true);
6860 6657 }
6861 6658
6862 6659 public static function execute_commit_transaction($input) {
6863 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6864 - if (!$post_id || !get_post($post_id)) {
6865 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6866 - }
6867 - if (!current_user_can('edit_post', $post_id)) {
6868 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6869 - }
6870 -
6660 + $post_id = (int) $input['post_id'];
6871 6661 delete_option('pagelayer_tx_backup_' . $post_id);
6872 6662 return array('success' => true);
6873 6663 }
6874 6664
6875 6665 public static function execute_rollback_transaction($input) {
6876 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6877 - if (!$post_id || !get_post($post_id)) {
6878 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6879 - }
6880 - if (!current_user_can('edit_post', $post_id)) {
6881 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6882 - }
6883 -
6666 + $post_id = (int) $input['post_id'];
6884 6667 $backup = get_option('pagelayer_tx_backup_' . $post_id);
6885 6668 if (!$backup) {
6886 6669 return new \WP_Error('no_backup', __('No active transaction to rollback.', 'pagelayer'));
6887 6670 }
@@ -6895,21 +6678,10 @@
6895 6678 return array('success' => true);
6896 6679 }
6897 6680
6898 6681 public static function execute_save_template($input) {
6899 - if (!current_user_can('edit_theme_options') && !current_user_can('manage_options')) {
6900 - return new \WP_Error('unauthorized', __('You do not have permission to save templates.', 'pagelayer'));
6901 - }
6902 -
6903 6682 $template_name = sanitize_text_field($input['name']);
6904 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6905 - if (!$post_id || !get_post($post_id)) {
6906 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6907 - }
6908 - if (!current_user_can('edit_post', $post_id)) {
6909 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6910 - }
6911 -
6683 + $post_id = (int) $input['post_id'];
6912 6684 $element_id = isset($input['element_id']) ? self::resolve_element_ref($post_id, sanitize_text_field($input['element_id'])) : '';
6913 6685
6914 6686 $data = get_post_meta($post_id, 'pagelayer-data', true);
6915 6687 if (!is_array($data)) {
@@ -6951,17 +6723,10 @@
6951 6723 return array('templates' => array_keys($library));
6952 6724 }
6953 6725
6954 6726 public static function execute_insert_template($input) {
6955 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6956 - if (!$post_id || !get_post($post_id)) {
6957 - return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
6958 - }
6959 - if (!current_user_can('edit_post', $post_id)) {
6960 - return new \WP_Error('unauthorized', __('You do not have permission to edit this post.', 'pagelayer'));
6961 - }
6962 -
6963 6727 $template_name = sanitize_text_field($input['name']);
6728 + $post_id = (int) $input['post_id'];
6964 6729 $parent_id = isset($input['parent_id']) ? sanitize_text_field($input['parent_id']) : '';
6965 6730 $index = isset($input['index']) ? (int) $input['index'] : -1;
6966 6731
6967 6732 $library = get_option('pagelayer_template_library', array());
@@ -7038,17 +6803,9 @@
7038 6803 return new \WP_Error('parent_not_found', __('Parent not found.', 'pagelayer'));
7039 6804 }
7040 6805
7041 6806 public static function execute_upload_media($input) {
7042 - if (!current_user_can('upload_files')) {
7043 - return new \WP_Error('unauthorized', __('You do not have permission to upload files.', 'pagelayer'));
7044 - }
7045 -
7046 6807 $url = esc_url_raw($input['url']);
7047 - if (!wp_http_validate_url($url)) {
7048 - return new \WP_Error('invalid_url', __('Invalid media URL provided.', 'pagelayer'));
7049 - }
7050 -
7051 6808 $desc = isset($input['alt_text']) ? sanitize_text_field($input['alt_text']) : '';
7052 6809
7053 6810 require_once(ABSPATH . 'wp-admin/includes/image.php');
7054 6811 require_once(ABSPATH . 'wp-admin/includes/file.php');
@@ -7080,15 +6837,12 @@
7080 6837 );
7081 6838 }
7082 6839
7083 6840 public static function execute_get_preview($input) {
7084 - $post_id = isset($input['post_id']) ? (int) $input['post_id'] : 0;
6841 + $post_id = (int) $input['post_id'];
7085 6842 $post = get_post($post_id);
7086 6843 if (!$post) {
7087 6844 return new \WP_Error('invalid_post', __('Post not found.', 'pagelayer'));
7088 - }
7089 - if ('publish' !== $post->post_status && !current_user_can('edit_post', $post_id)) {
7090 - return new \WP_Error('unauthorized', __('You do not have permission to preview this post.', 'pagelayer'));
7091 6845 }
7092 6846 $url = ('publish' === $post->post_status)
7093 6847 ? get_permalink($post_id)
7094 6848 : get_preview_post_link($post_id);