Plugin Directory

Changeset 3481417


Ignore:
Timestamp:
03/12/2026 06:51:05 PM (3 weeks ago)
Author:
rankauthority
Message:

Release 1.0.33: handle updating post with elementor or other theme

Location:
rank-authority
Files:
9 added
2 edited

Legend:

Unmodified
Added
Removed
  • rank-authority/trunk/rank-authority.php

    r3481398 r3481417  
    44 * Plugin URI: https://rankauthority.com/plugins/rankauthority
    55 * Description: Secure API connector to publish posts / overwrite posts from the RA Dashboard to WordPress. Token reset now available to all administrators.
    6  * Version: 1.0.32
     6 * Version: 1.0.33
    77 * Author: Rank Authority
    88 * Author URI: https://rankauthority.com
     
    13641364    }
    13651365
     1366    /**
     1367     * Get allowed builder meta keys (for restore validation).
     1368     */
     1369    private function get_builder_meta_keys() {
     1370        $builders = [
     1371            'elementor' => [
     1372                '_elementor_data',
     1373                '_elementor_edit_mode',
     1374                '_elementor_css',
     1375                '_elementor_page_settings',
     1376                '_elementor_template_type',
     1377                '_elementor_version',
     1378            ],
     1379            'wpbakery' => [
     1380                '_wpb_shortcodes_custom_css',
     1381                '_wpb_post_custom_css',
     1382                '_wpb_js_composer_shortcodes',
     1383            ],
     1384            'divi' => [
     1385                '_et_pb_use_builder',
     1386                '_et_pb_old_content',
     1387                '_et_pb_built_for_post',
     1388            ],
     1389            'beaver_builder' => [
     1390                '_fl_builder_data',
     1391                '_fl_builder_draft',
     1392                '_fl_builder_enabled',
     1393            ],
     1394            'bricks' => [
     1395                '_bricks_page_content',
     1396                '_bricks_page_content_2',
     1397                '_bricks_page_content_4',
     1398            ],
     1399        ];
     1400        return apply_filters('rank_authority_page_builder_meta_keys', $builders);
     1401    }
     1402
     1403    /**
     1404     * Detect which page builder was used on a post and clear its meta
     1405     * so the frontend uses post_content instead of builder data.
     1406     *
     1407     * @param int $post_id Post ID
     1408     * @return array{cleared: string|null, meta: array} Cleared builder name and meta data (for restore)
     1409     */
     1410    private function clear_page_builder_meta($post_id) {
     1411        $cleared = null;
     1412        $cleared_meta = [];
     1413        $builders = $this->get_builder_meta_keys();
     1414
     1415        foreach ($builders as $builder => $meta_keys) {
     1416            $has_builder = false;
     1417            foreach ($meta_keys as $key) {
     1418                if (metadata_exists('post', $post_id, $key)) {
     1419                    $has_builder = true;
     1420                    break;
     1421                }
     1422            }
     1423            if ($has_builder) {
     1424                foreach ($meta_keys as $key) {
     1425                    $val = get_post_meta($post_id, $key, true);
     1426                    if ($val !== '' && $val !== false) {
     1427                        $cleared_meta[$key] = $val;
     1428                    }
     1429                    delete_post_meta($post_id, $key);
     1430                }
     1431                if ($builder === 'elementor') {
     1432                    $this->clear_elementor_css_file($post_id);
     1433                }
     1434                if ($cleared === null) {
     1435                    $cleared = $builder;
     1436                }
     1437                do_action('rank_authority_page_builder_meta_cleared', $post_id, $builder);
     1438            }
     1439        }
     1440        return ['cleared' => $cleared, 'meta' => $cleared_meta];
     1441    }
     1442
     1443    /**
     1444     * Restore page builder meta from previously saved data.
     1445     *
     1446     * @param int $post_id Post ID
     1447     * @param array $builder_meta Assoc array of meta_key => value (e.g. from cleared_builder_meta)
     1448     * @return bool True if any meta was set
     1449     */
     1450    private function restore_page_builder_meta($post_id, $builder_meta) {
     1451        if (empty($builder_meta) || !is_array($builder_meta)) {
     1452            return false;
     1453        }
     1454        $allowed = [];
     1455        foreach ($this->get_builder_meta_keys() as $keys) {
     1456            $allowed = array_merge($allowed, $keys);
     1457        }
     1458        $allowed = array_flip($allowed);
     1459        $set = false;
     1460        foreach ($builder_meta as $key => $value) {
     1461            if (isset($allowed[$key])) {
     1462                update_post_meta($post_id, $key, $value);
     1463                $set = true;
     1464            }
     1465        }
     1466        return $set;
     1467    }
     1468
     1469    /**
     1470     * Update arbitrary post meta. Blocklist prevents overwriting sensitive WordPress keys.
     1471     *
     1472     * @param int $post_id Post ID
     1473     * @param array $meta Assoc array of meta_key => value
     1474     */
     1475    private function update_post_meta_safe($post_id, $meta) {
     1476        $blocklist = [
     1477            '_edit_lock',
     1478            '_edit_last',
     1479            '_wp_old_slug',
     1480            '_thumbnail_id',
     1481            '_wp_trash_meta',
     1482            '_wp_desired_post_slug',
     1483            '_wp_page_template',
     1484        ];
     1485        $blocklist = apply_filters('rank_authority_post_meta_blocklist', $blocklist);
     1486
     1487        foreach ($meta as $key => $value) {
     1488            $key = sanitize_key($key);
     1489            if (empty($key) || in_array($key, $blocklist, true)) {
     1490                continue;
     1491            }
     1492            if ($value === null || $value === '') {
     1493                delete_post_meta($post_id, $key);
     1494            } else {
     1495                update_post_meta($post_id, $key, $value);
     1496            }
     1497        }
     1498    }
     1499
     1500    /** Delete Elementor CSS file for a single post to avoid orphaned CSS loading */
     1501    private function clear_elementor_css_file($post_id) {
     1502        $upload_dir = wp_upload_dir();
     1503        if (!empty($upload_dir['error'])) {
     1504            return;
     1505        }
     1506        $css_dir = $upload_dir['basedir'] . '/elementor/css/';
     1507        $css_file = $css_dir . 'post-' . $post_id . '.css';
     1508        if (file_exists($css_file)) {
     1509            @unlink($css_file);
     1510        }
     1511    }
     1512
    13661513    /** Publish post */
    13671514    public function publish_post($request) {
     
    17661913        }
    17671914
    1768         if (!empty($params['content'])) {
     1915        $is_updating_content = !empty($params['content']);
     1916        if ($is_updating_content) {
    17691917            $post_data['post_content'] = wp_kses_post($params['content']);
    17701918        }
     
    17881936        // Clear post cache so public view shows new content immediately
    17891937        $this->clear_post_cache($updated_id);
     1938
     1939        // When updating content: restore builder meta if provided, otherwise clear it.
     1940        $cleared_builder = null;
     1941        $cleared_builder_meta = null;
     1942        $builder_meta = $params['builder_meta'] ?? null;
     1943
     1944        if (!empty($builder_meta) && is_array($builder_meta)) {
     1945            $this->restore_page_builder_meta($updated_id, $builder_meta);
     1946        } elseif ($is_updating_content) {
     1947            $result = $this->clear_page_builder_meta($updated_id);
     1948            $cleared_builder = $result['cleared'];
     1949            $cleared_builder_meta = !empty($result['meta']) ? $result['meta'] : null;
     1950        }
     1951
     1952        // Update arbitrary post meta if provided (blocklist protects sensitive keys)
     1953        $post_meta = $params['post_meta'] ?? null;
     1954        if (!empty($post_meta) && is_array($post_meta)) {
     1955            $this->update_post_meta_safe($updated_id, $post_meta);
     1956        }
    17901957
    17911958        // Update featured image if provided (by media ID)
     
    19522119
    19532120        $response = [
    1954             'success' => true,
    1955             'post_id' => $updated_id,
    1956             'url'     => $permalink,
    1957             'URL'     => $permalink,  // Xano compatibility
    1958             'ID'      => $updated_id  // Xano compatibility
     2121            'success'             => true,
     2122            'post_id'             => $updated_id,
     2123            'url'                 => $permalink,
     2124            'URL'                 => $permalink,  // Xano compatibility
     2125            'ID'                  => $updated_id,  // Xano compatibility
     2126            'cleared_builder'     => $cleared_builder,
     2127            'cleared_builder_meta' => $cleared_builder_meta,
    19592128        ];
    19602129        if (isset($params['schema']) && !empty($params['schema'])) {
  • rank-authority/trunk/readme.txt

    r3481398 r3481417  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.32
     7Stable tag: 1.0.33
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    137137
    138138== Changelog ==
     139
     140= 1.0.33 =
     141* PUT update: Page builder meta (Elementor, WPBakery, Divi, Beaver Builder, Bricks) now cleared when updating content so frontend uses post_content
     142* PUT response includes cleared_builder and cleared_builder_meta (saved builder data for restore)
     143* PUT accepts builder_meta to restore page builder layout (send cleared_builder_meta back to re-apply)
     144* PUT accepts post_meta for arbitrary post meta updates (blocklist protects sensitive keys)
     145* Elementor CSS file (post-{id}.css) deleted when clearing Elementor meta to avoid orphaned CSS loading
     146* Filters: rank_authority_page_builder_meta_keys, rank_authority_post_meta_blocklist
    139147
    140148= 1.0.32 =
     
    329337== Upgrade Notice ==
    330338
     339= 1.0.33 =
     340PUT now clears page builder meta when updating content (Elementor, WPBakery, Divi, etc.) so changes appear on frontend. Response includes builder data for restore; send builder_meta to re-apply. Added post_meta param for custom meta updates.
     341
    331342= 1.0.32 =
    332343GEO page top padding increased to 10rem for better compatibility with themes that use tall fixed headers.
Note: See TracChangeset for help on using the changeset viewer.