Plugin Directory

Changeset 3487719


Ignore:
Timestamp:
03/21/2026 10:35:41 AM (7 days ago)
Author:
andaleplugins
Message:

Release 1.0.1

Location:
smart-content-sync
Files:
4 added
10 deleted
28 edited
1 copied

Legend:

Unmodified
Added
Removed
  • smart-content-sync/tags/1.0.1/composer.json

    r3454742 r3487719  
    2121    "require-dev": {
    2222        "php-stubs/wordpress-stubs": "dev-master",
    23         "php-stubs/woocommerce-stubs": "^3.8"
     23        "php-stubs/woocommerce-stubs": "^3.8",
     24        "wp-cli/wp-cli": "^2.13@dev"
    2425    }
    2526}
  • smart-content-sync/tags/1.0.1/readme.txt

    r3454742 r3487719  
    55Requires at least: 5.8
    66Tested up to: 6.9
    7 Stable tag: 1.0.0
     7Stable tag: 1.0.1
    88License: GPLv3 or later
    99License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    140140
    141141== Changelog ==
     142= 1.0.1 =
     143* Added support for the renamed Gutenberg block registration and migration from the previous block name
     144* Refined SEO integration and editor detection behavior for analysis previews
     145* Added extensibility hooks for settings sections and improved admin/client configuration plumbing
     146* Updated compatibility metadata and release packaging details
     147
    142148= 1.0.0 =
    143149* Initial stable release
  • smart-content-sync/tags/1.0.1/smart-content-sync.php

    r3454742 r3487719  
    44 * Plugin Name: Smart Content Sync
    55 * Description: Stop Copy-Pasting. Create Once. Sync Everywhere.
    6  * Version: 1.0.0
     6 * Version: 1.0.1
    77 * Author: Andale Plugins
    88 * Author: Andale Technologies, SARL
     
    3232define('SMART_CONTENT_SYNC_DIST_URL', plugin_dir_url(__FILE__) . 'dist/');
    3333define('SMART_CONTENT_SYNC_BASENAME', plugin_basename(__FILE__));
    34 define('SMART_CONTENT_SYNC_VERSION', '1.0.0');
     34define('SMART_CONTENT_SYNC_VERSION', '1.0.1');
    3535
    3636// Initialize the plugin
  • smart-content-sync/tags/1.0.1/src/ContentBlocks/Renderer/ContextBuilder.php

    r3454742 r3487719  
    3333    // Post-related context (this block)
    3434    if ($smartContentPost instanceof WP_Post) {
     35      $postAuthorName = '';
     36      $postAuthorId = (int) $smartContentPost->post_author;
     37      if ($postAuthorId > 0) {
     38        $author = get_userdata($postAuthorId);
     39        if ($author instanceof \WP_User) {
     40          $postAuthorName = $author->display_name;
     41        }
     42      }
     43
    3544      $context['post'] = [
    3645        'id' => $smartContentPost->ID,
     
    3948        'excerpt' => $smartContentPost->post_excerpt,
    4049        'url' => get_permalink($smartContentPost),
    41         'type' => $smartContentPost->post_type, // add this
     50        'type' => $smartContentPost->post_type,
     51        'date' => get_the_date('', $smartContentPost),
     52        'author' => $postAuthorName,
     53        'categories' => $this->getJoinedTermNames($smartContentPost->ID, 'category'),
    4254      ];
    4355
     
    107119            'stock_quantity' => $stockQty,
    108120            'is_on_sale' => $isOnSale ? 'yes' : 'no',
     121            'categories' => ($id ? $this->getJoinedTermNames((int) $id, 'product_cat') : ''),
     122            'tags' => ($id ? $this->getJoinedTermNames((int) $id, 'product_tag') : ''),
    109123          ];
    110124        }
     
    182196    return $flat;
    183197  }
     198
     199  /**
     200   * Return a comma-separated list of term names for a given object/taxonomy pair.
     201   *
     202   * @param int $objectId
     203   * @param string $taxonomy
     204   * @return string
     205   */
     206  protected function getJoinedTermNames(int $objectId, string $taxonomy): string
     207  {
     208    if ($objectId <= 0 || $taxonomy === '') {
     209      return '';
     210    }
     211
     212    $terms = get_the_terms($objectId, $taxonomy);
     213    if (is_wp_error($terms) || !is_array($terms) || empty($terms)) {
     214      return '';
     215    }
     216
     217    $names = [];
     218    foreach ($terms as $term) {
     219      if ($term instanceof \WP_Term && $term->name !== '') {
     220        $names[] = $term->name;
     221      }
     222    }
     223
     224    return implode(', ', $names);
     225  }
    184226}
  • smart-content-sync/tags/1.0.1/src/ContentBlocks/SmartContentCustomPostType.php

    r3454742 r3487719  
    3535      'labels' => $labels,
    3636      'public' => false,
     37      // 'publicly_queryable' => true, // needed for REST API access
    3738      'show_ui' => true,
    3839      'show_in_menu' => true,
  • smart-content-sync/tags/1.0.1/src/Domains/AutoInsert/Storage/AutoInsertMetaBox.php

    r3454742 r3487719  
    153153    echo '</p>';
    154154
     155    do_action('smart_content_sync_auto_insert_metabox_before_locations', $post, [
     156      'enabled' => $enabled,
     157      'locations' => $locations,
     158    ]);
     159
    155160    // Default open group: WooCommerce (if active), otherwise WordPress.
    156161    $defaultOpenGroup = $isWooCommerceActive ? 'WooCommerce' : 'WordPress';
     
    242247    }
    243248
     249    do_action('smart_content_sync_auto_insert_metabox_after_locations', $post, [
     250      'enabled' => $enabled,
     251      'locations' => $locations,
     252    ]);
     253
    244254    echo '</div>';
    245255  }
     
    304314    $clean = array_values(array_unique($clean));
    305315    update_post_meta($postId, self::META_LOCATIONS, $clean);
     316
     317    do_action('smart_content_sync_auto_insert_metabox_save', $postId, $post, [
     318      'enabled' => $enabled,   // '1'|'0' as stored
     319      'locations' => $clean,   // validated array
     320    ]);
    306321  }
    307322}
  • smart-content-sync/tags/1.0.1/src/Infrastructure/Admin/Settings/SettingsManager.php

    r3454742 r3487719  
    119119  private function getSections(): array
    120120  {
    121     return [
     121    $sections = [
    122122      new UninstallSettingsSection($this),
    123123    ];
     124
     125    /**
     126     * Allow extensions (e.g. Pro plugin) to add settings sections.
     127     *
     128     * @param array<int, object> $sections
     129     * @param SettingsManager    $manager
     130     */
     131    $sections = (array) apply_filters('smart_content_sync_settings_sections', $sections, $this);
     132
     133    return $sections;
    124134  }
    125135
  • smart-content-sync/tags/1.0.1/src/Infrastructure/Platform/WooCommerce/WooCommerceHelper.php

    r3454742 r3487719  
    1414 *
    1515 * Notes on payload size:
    16  * - Use buildWooCommerceSettingsBasic() for most SmartContentSync needs.
    17  * - Use buildWooCommerceSettingsExtended() only when you truly need currency formatting
     16 * - Use buildWooCommerceClientConfig() for most SmartContentSync needs.
     17 * - Use buildWooCommerceClientConfigExtended() only when you truly need currency formatting
    1818 *   or Store API nonce data.
    1919 *
     
    178178
    179179  /**
    180    * Build a minimal WooCommerce settings array suitable for script localization.
    181    *
    182    * This is the recommended method for SmartContentSync: it exposes only what you
    183    * typically need client-side (presence + basic context), and nothing expensive.
    184    *
    185    * Intended use:
    186    * - wp_localize_script(..., 'smartContentSyncWoo', WooCommerceHelper::buildWooCommerceSettingsBasic())
     180   * Build an extended WooCommerce settings array suitable for script localization.
     181   *
     182   * This includes currency formatting details and (optionally) Store API nonce.
     183   * Use this only for admin UIs or frontend UIs that explicitly need these values.
    187184   *
    188185   * @param array<string, mixed> $overrides Optional overrides merged into the base settings.
    189186   * @return array<string, mixed>
    190187   */
    191   public static function buildWooCommerceSettingsBasic(array $overrides = []): array
     188  public static function buildWooCommerceClientConfigExtended(array $overrides = []): array
    192189  {
    193190    $active = self::isWooCommerceActive();
    194191    $installed = self::isWooCommerceInstalled();
    195192
    196     $settings = [
    197       'active' => $active,
    198       'installed' => $installed,
    199       'isSingleProduct' => $active ? self::isSingleProductPage() : false,
    200       'isWooRest' => $active ? self::isWooCommerceRestRequest() : false,
    201       'currentProductId' => $active ? self::getCurrentProductId() : null,
    202 
    203       // Currency code is small and commonly useful for UI labels.
    204       'currency' => ($active && function_exists('get_woocommerce_currency')) ? (string) get_woocommerce_currency() : '',
    205 
    206       // Keep URLs minimal; add more only when a concrete UI needs them.
    207       'urls' => [
    208         'shop' => ($active && function_exists('wc_get_page_permalink')) ? (string) wc_get_page_permalink('shop') : '',
    209       ],
    210 
    211       'features' => [],
    212     ];
    213 
    214     /**
    215      * Filter the basic WooCommerce settings array.
    216      *
    217      * @param array<string, mixed> $settings   Base settings.
    218      * @param array<string, mixed> $overrides  Caller overrides.
    219      */
    220     $settings = (array) apply_filters('smart_content_sync_woocommerce_settings_basic', $settings, $overrides);
    221 
    222     if (!empty($overrides)) {
    223       $settings = self::mergeDeep($settings, $overrides);
    224     }
    225 
    226     return $settings;
    227   }
    228 
    229   /**
    230    * Build an extended WooCommerce settings array suitable for script localization.
    231    *
    232    * This includes currency formatting details and (optionally) Store API nonce.
    233    * Use this only for admin UIs or frontend UIs that explicitly need these values.
    234    *
    235    * @param array<string, mixed> $overrides Optional overrides merged into the base settings.
    236    * @return array<string, mixed>
    237    */
    238   public static function buildWooCommerceSettingsExtended(array $overrides = []): array
    239   {
    240     $active = self::isWooCommerceActive();
    241     $installed = self::isWooCommerceInstalled();
    242 
    243193    // Start from the minimal base.
    244     $settings = self::buildWooCommerceSettingsBasic();
     194    // DO NOT pass the overrides here because:
     195    //   1- The filter below may override it. So, wait until just before return, and do a deep merge.
     196    //   2- We want to keep the basic payload stable and filterable on its own.
     197    $settings = self::buildWooCommerceClientConfig();
    245198
    246199    if (!$active) {
     
    251204       * @param array<string, mixed> $overrides  Caller overrides.
    252205       */
    253       $settings = (array) apply_filters('smart_content_sync_woocommerce_settings_extended', $settings, $overrides);
     206      $settings = (array) apply_filters('smart_content_sync_woocommerce_client_config_extended', $settings, $overrides);
    254207
    255208      if (!empty($overrides)) {
     
    288241     * @param array<string, mixed> $overrides  Caller overrides.
    289242     */
    290     $settings = (array) apply_filters('smart_content_sync_woocommerce_settings_extended', $settings, $overrides);
     243    $settings = (array) apply_filters('smart_content_sync_woocommerce_client_config_extended', $settings, $overrides);
    291244
    292245    if (!empty($overrides)) {
     
    304257   * Back-compat alias.
    305258   *
    306    * If existing call-sites already use buildWooCommerceSettings(), keep it working
    307    * but return the BASIC payload by default (lean and safe).
     259   * Builds the WooCommerce config payload. Use buildWooCommerceClientConfigExtended() if you need the extra any of the following:
     260   *  - currencySymbol
     261   *  - decimals
     262   *  - decimalSeparator
     263   *  - thousandSeparator
     264   *  - priceFormat.
    308265   *
    309266   * @param array<string, mixed> $overrides Optional overrides.
    310267   * @return array<string, mixed>
    311268   */
    312   public static function buildWooCommerceSettings(array $overrides = []): array
    313   {
    314     $settings = self::buildWooCommerceSettingsBasic($overrides);
    315 
    316     /**
    317      * Filter the WooCommerce settings array (legacy alias).
    318      *
    319      * @param array<string, mixed> $settings   Settings (basic by default).
    320      * @param array<string, mixed> $overrides  Caller overrides.
    321      */
    322     return (array) apply_filters('smart_content_sync_woocommerce_settings', $settings, $overrides);
     269  public static function buildWooCommerceClientConfig(array $overrides = []): array
     270  {
     271    $active = self::isWooCommerceActive();
     272    $installed = self::isWooCommerceInstalled();
     273
     274    $config = [
     275      'active' => $active,
     276      'installed' => $installed,
     277      'isSingleProduct' => $active ? self::isSingleProductPage() : false,
     278      'isWooRest' => $active ? self::isWooCommerceRestRequest() : false,
     279      'currentProductId' => $active ? self::getCurrentProductId() : null,
     280      'currency' => ($active && function_exists('get_woocommerce_currency')) ? (string) get_woocommerce_currency() : '',
     281      'urls' => [
     282        'shop' => ($active && function_exists('wc_get_page_permalink')) ? (string) wc_get_page_permalink('shop') : '',
     283      ],
     284    ];
     285
     286    if (!empty($overrides)) {
     287      $config = self::mergeDeep($config, $overrides);
     288    }
     289
     290    return $config;
    323291  }
    324292
  • smart-content-sync/tags/1.0.1/src/Infrastructure/Platform/WordPress/WordPressHelper.php

    r3454742 r3487719  
    107107   *
    108108   * Intended use:
    109    * - wp_localize_script(..., 'smartContentSyncWp', WordPressHelper::buildWordPressSettings(...))
     109   * - wp_localize_script(..., 'smartContentSyncWp', WordPressHelper::buildWordPressClientConfig(...))
    110110   * - or wp_add_inline_script with JSON.
    111111   *
     
    118118   * @return array<string, mixed>
    119119   */
    120   public static function buildWordPressSettings(array $overrides = []): array
     120  public static function buildWordPressClientConfig(array $overrides = []): array
    121121  {
    122122    $locale = self::resolveLocale();
     
    157157        'canManageOptions' => function_exists('current_user_can') ? (bool) current_user_can('manage_options') : false,
    158158      ],
    159 
    160       // Feature switches / flags you may want client-side.
    161       // Keep these additive and conservative for v1.
    162       'features' => [],
    163159    ];
    164 
    165     /**
    166      * Filter the base WordPress settings array.
    167      *
    168      * @param array<string, mixed> $settings   Base settings.
    169      * @param array<string, mixed> $overrides  Caller overrides.
    170      */
    171     $settings = (array) apply_filters('smart_content_sync_wordpress_settings', $settings, $overrides);
    172160
    173161    if (!empty($overrides)) {
  • smart-content-sync/tags/1.0.1/src/Plugin.php

    r3454742 r3487719  
    1313use AndalePlugins\SmartContentSync\ContentBlocks\Renderer\RenderingGateway;
    1414use AndalePlugins\SmartContentSync\ContentBlocks\SmartContentCustomPostType;
     15use AndalePlugins\SmartContentSync\Infrastructure\Client\ClientConfigBuilder;
    1516use AndalePlugins\SmartContentSync\Domains\AutoInsert\Services\AutoInsertIndex;
    1617use AndalePlugins\SmartContentSync\Domains\AutoInsert\Services\AutoInsertManager;
     
    141142  public function localizeAdminScripts(): void
    142143  {
    143     $data = [
    144       'ajaxUrl' => admin_url('admin-ajax.php'),
    145       'nonce' => wp_create_nonce('smart_content_sync_admin_nonce'),
    146       'wordPress' => WordPressHelper::buildWordPressSettings(),
    147       'wooCommerce' => WooCommerceHelper::buildWooCommerceSettings(),
     144    // $data = [
     145    //   'ajaxUrl' => admin_url('admin-ajax.php'),
     146    //   'nonce' => wp_create_nonce('smart_content_sync_admin_nonce'),
     147    //   'wordPress' => WordPressHelper::buildWordPressClientConfig(),
     148    //   'wooCommerce' => WooCommerceHelper::buildWooCommerceClientConfig(),
     149    //   'localization' => $this->buildLocalizationPayload(),
     150    // ];
     151    // wp_localize_script(
     152    //   'smart-content-sync-admin-script',
     153    //   'smartContentSyncAdminData',
     154    //   $data
     155    // );
     156
     157    $data = ClientConfigBuilder::buildAdminClientConfig([
     158      // This stays here because it is plugin-owned localization,
     159      // not platform context.
    148160      'localization' => $this->buildLocalizationPayload(),
    149     ];
     161    ]);
     162
    150163    wp_localize_script(
    151164      'smart-content-sync-admin-script',
  • smart-content-sync/tags/1.0.1/vendor/autoload.php

    r3454742 r3487719  
    2323require_once __DIR__ . '/composer/autoload_real.php';
    2424
    25 return ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb::getLoader();
     25return ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768::getLoader();
  • smart-content-sync/tags/1.0.1/vendor/composer/autoload_classmap.php

    r3454742 r3487719  
    3333    'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\Sections\\UninstallSettingsSection' => $baseDir . '/src/Infrastructure/Admin/Settings/Sections/UninstallSettingsSection.php',
    3434    'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\SettingsManager' => $baseDir . '/src/Infrastructure/Admin/Settings/SettingsManager.php',
     35    'AndalePlugins\\SmartContentSync\\Infrastructure\\Client\\ClientConfigBuilder' => $baseDir . '/src/Infrastructure/Client/ClientConfigBuilder.php',
    3536    'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WooCommerce\\WooCommerceHelper' => $baseDir . '/src/Infrastructure/Platform/WooCommerce/WooCommerceHelper.php',
    3637    'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WordPress\\WordPressHelper' => $baseDir . '/src/Infrastructure/Platform/WordPress/WordPressHelper.php',
  • smart-content-sync/tags/1.0.1/vendor/composer/autoload_real.php

    r3454742 r3487719  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb
     5class ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768
    66{
    77    private static $loader;
     
    2323        }
    2424
    25         spl_autoload_register(array('ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb', 'loadClassLoader'), true, true);
     25        spl_autoload_register(array('ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768', 'loadClassLoader'), true, true);
    2626        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    27         spl_autoload_unregister(array('ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb', 'loadClassLoader'));
     27        spl_autoload_unregister(array('ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768', 'loadClassLoader'));
    2828
    2929        require __DIR__ . '/autoload_static.php';
    30         call_user_func(\Composer\Autoload\ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::getInitializer($loader));
     30        call_user_func(\Composer\Autoload\ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::getInitializer($loader));
    3131
    3232        $loader->register(true);
  • smart-content-sync/tags/1.0.1/vendor/composer/autoload_static.php

    r3454742 r3487719  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit15c4633b3346ac34866474b910a7bcfb
     7class ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768
    88{
    99    public static $prefixLengthsPsr4 = array (
     
    4848        'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\Sections\\UninstallSettingsSection' => __DIR__ . '/../..' . '/src/Infrastructure/Admin/Settings/Sections/UninstallSettingsSection.php',
    4949        'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\SettingsManager' => __DIR__ . '/../..' . '/src/Infrastructure/Admin/Settings/SettingsManager.php',
     50        'AndalePlugins\\SmartContentSync\\Infrastructure\\Client\\ClientConfigBuilder' => __DIR__ . '/../..' . '/src/Infrastructure/Client/ClientConfigBuilder.php',
    5051        'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WooCommerce\\WooCommerceHelper' => __DIR__ . '/../..' . '/src/Infrastructure/Platform/WooCommerce/WooCommerceHelper.php',
    5152        'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WordPress\\WordPressHelper' => __DIR__ . '/../..' . '/src/Infrastructure/Platform/WordPress/WordPressHelper.php',
     
    6061    {
    6162        return \Closure::bind(function () use ($loader) {
    62             $loader->prefixLengthsPsr4 = ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::$prefixLengthsPsr4;
    63             $loader->prefixDirsPsr4 = ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::$prefixDirsPsr4;
    64             $loader->classMap = ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::$classMap;
     63            $loader->prefixLengthsPsr4 = ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::$prefixLengthsPsr4;
     64            $loader->prefixDirsPsr4 = ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::$prefixDirsPsr4;
     65            $loader->classMap = ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::$classMap;
    6566
    6667        }, null, ClassLoader::class);
  • smart-content-sync/trunk/composer.json

    r3454742 r3487719  
    2121    "require-dev": {
    2222        "php-stubs/wordpress-stubs": "dev-master",
    23         "php-stubs/woocommerce-stubs": "^3.8"
     23        "php-stubs/woocommerce-stubs": "^3.8",
     24        "wp-cli/wp-cli": "^2.13@dev"
    2425    }
    2526}
  • smart-content-sync/trunk/readme.txt

    r3454742 r3487719  
    55Requires at least: 5.8
    66Tested up to: 6.9
    7 Stable tag: 1.0.0
     7Stable tag: 1.0.1
    88License: GPLv3 or later
    99License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    140140
    141141== Changelog ==
     142= 1.0.1 =
     143* Added support for the renamed Gutenberg block registration and migration from the previous block name
     144* Refined SEO integration and editor detection behavior for analysis previews
     145* Added extensibility hooks for settings sections and improved admin/client configuration plumbing
     146* Updated compatibility metadata and release packaging details
     147
    142148= 1.0.0 =
    143149* Initial stable release
  • smart-content-sync/trunk/smart-content-sync.php

    r3454742 r3487719  
    44 * Plugin Name: Smart Content Sync
    55 * Description: Stop Copy-Pasting. Create Once. Sync Everywhere.
    6  * Version: 1.0.0
     6 * Version: 1.0.1
    77 * Author: Andale Plugins
    88 * Author: Andale Technologies, SARL
     
    3232define('SMART_CONTENT_SYNC_DIST_URL', plugin_dir_url(__FILE__) . 'dist/');
    3333define('SMART_CONTENT_SYNC_BASENAME', plugin_basename(__FILE__));
    34 define('SMART_CONTENT_SYNC_VERSION', '1.0.0');
     34define('SMART_CONTENT_SYNC_VERSION', '1.0.1');
    3535
    3636// Initialize the plugin
  • smart-content-sync/trunk/src/ContentBlocks/Renderer/ContextBuilder.php

    r3454742 r3487719  
    3333    // Post-related context (this block)
    3434    if ($smartContentPost instanceof WP_Post) {
     35      $postAuthorName = '';
     36      $postAuthorId = (int) $smartContentPost->post_author;
     37      if ($postAuthorId > 0) {
     38        $author = get_userdata($postAuthorId);
     39        if ($author instanceof \WP_User) {
     40          $postAuthorName = $author->display_name;
     41        }
     42      }
     43
    3544      $context['post'] = [
    3645        'id' => $smartContentPost->ID,
     
    3948        'excerpt' => $smartContentPost->post_excerpt,
    4049        'url' => get_permalink($smartContentPost),
    41         'type' => $smartContentPost->post_type, // add this
     50        'type' => $smartContentPost->post_type,
     51        'date' => get_the_date('', $smartContentPost),
     52        'author' => $postAuthorName,
     53        'categories' => $this->getJoinedTermNames($smartContentPost->ID, 'category'),
    4254      ];
    4355
     
    107119            'stock_quantity' => $stockQty,
    108120            'is_on_sale' => $isOnSale ? 'yes' : 'no',
     121            'categories' => ($id ? $this->getJoinedTermNames((int) $id, 'product_cat') : ''),
     122            'tags' => ($id ? $this->getJoinedTermNames((int) $id, 'product_tag') : ''),
    109123          ];
    110124        }
     
    182196    return $flat;
    183197  }
     198
     199  /**
     200   * Return a comma-separated list of term names for a given object/taxonomy pair.
     201   *
     202   * @param int $objectId
     203   * @param string $taxonomy
     204   * @return string
     205   */
     206  protected function getJoinedTermNames(int $objectId, string $taxonomy): string
     207  {
     208    if ($objectId <= 0 || $taxonomy === '') {
     209      return '';
     210    }
     211
     212    $terms = get_the_terms($objectId, $taxonomy);
     213    if (is_wp_error($terms) || !is_array($terms) || empty($terms)) {
     214      return '';
     215    }
     216
     217    $names = [];
     218    foreach ($terms as $term) {
     219      if ($term instanceof \WP_Term && $term->name !== '') {
     220        $names[] = $term->name;
     221      }
     222    }
     223
     224    return implode(', ', $names);
     225  }
    184226}
  • smart-content-sync/trunk/src/ContentBlocks/SmartContentCustomPostType.php

    r3454742 r3487719  
    3535      'labels' => $labels,
    3636      'public' => false,
     37      // 'publicly_queryable' => true, // needed for REST API access
    3738      'show_ui' => true,
    3839      'show_in_menu' => true,
  • smart-content-sync/trunk/src/Domains/AutoInsert/Storage/AutoInsertMetaBox.php

    r3454742 r3487719  
    153153    echo '</p>';
    154154
     155    do_action('smart_content_sync_auto_insert_metabox_before_locations', $post, [
     156      'enabled' => $enabled,
     157      'locations' => $locations,
     158    ]);
     159
    155160    // Default open group: WooCommerce (if active), otherwise WordPress.
    156161    $defaultOpenGroup = $isWooCommerceActive ? 'WooCommerce' : 'WordPress';
     
    242247    }
    243248
     249    do_action('smart_content_sync_auto_insert_metabox_after_locations', $post, [
     250      'enabled' => $enabled,
     251      'locations' => $locations,
     252    ]);
     253
    244254    echo '</div>';
    245255  }
     
    304314    $clean = array_values(array_unique($clean));
    305315    update_post_meta($postId, self::META_LOCATIONS, $clean);
     316
     317    do_action('smart_content_sync_auto_insert_metabox_save', $postId, $post, [
     318      'enabled' => $enabled,   // '1'|'0' as stored
     319      'locations' => $clean,   // validated array
     320    ]);
    306321  }
    307322}
  • smart-content-sync/trunk/src/Infrastructure/Admin/Settings/SettingsManager.php

    r3454742 r3487719  
    119119  private function getSections(): array
    120120  {
    121     return [
     121    $sections = [
    122122      new UninstallSettingsSection($this),
    123123    ];
     124
     125    /**
     126     * Allow extensions (e.g. Pro plugin) to add settings sections.
     127     *
     128     * @param array<int, object> $sections
     129     * @param SettingsManager    $manager
     130     */
     131    $sections = (array) apply_filters('smart_content_sync_settings_sections', $sections, $this);
     132
     133    return $sections;
    124134  }
    125135
  • smart-content-sync/trunk/src/Infrastructure/Platform/WooCommerce/WooCommerceHelper.php

    r3454742 r3487719  
    1414 *
    1515 * Notes on payload size:
    16  * - Use buildWooCommerceSettingsBasic() for most SmartContentSync needs.
    17  * - Use buildWooCommerceSettingsExtended() only when you truly need currency formatting
     16 * - Use buildWooCommerceClientConfig() for most SmartContentSync needs.
     17 * - Use buildWooCommerceClientConfigExtended() only when you truly need currency formatting
    1818 *   or Store API nonce data.
    1919 *
     
    178178
    179179  /**
    180    * Build a minimal WooCommerce settings array suitable for script localization.
    181    *
    182    * This is the recommended method for SmartContentSync: it exposes only what you
    183    * typically need client-side (presence + basic context), and nothing expensive.
    184    *
    185    * Intended use:
    186    * - wp_localize_script(..., 'smartContentSyncWoo', WooCommerceHelper::buildWooCommerceSettingsBasic())
     180   * Build an extended WooCommerce settings array suitable for script localization.
     181   *
     182   * This includes currency formatting details and (optionally) Store API nonce.
     183   * Use this only for admin UIs or frontend UIs that explicitly need these values.
    187184   *
    188185   * @param array<string, mixed> $overrides Optional overrides merged into the base settings.
    189186   * @return array<string, mixed>
    190187   */
    191   public static function buildWooCommerceSettingsBasic(array $overrides = []): array
     188  public static function buildWooCommerceClientConfigExtended(array $overrides = []): array
    192189  {
    193190    $active = self::isWooCommerceActive();
    194191    $installed = self::isWooCommerceInstalled();
    195192
    196     $settings = [
    197       'active' => $active,
    198       'installed' => $installed,
    199       'isSingleProduct' => $active ? self::isSingleProductPage() : false,
    200       'isWooRest' => $active ? self::isWooCommerceRestRequest() : false,
    201       'currentProductId' => $active ? self::getCurrentProductId() : null,
    202 
    203       // Currency code is small and commonly useful for UI labels.
    204       'currency' => ($active && function_exists('get_woocommerce_currency')) ? (string) get_woocommerce_currency() : '',
    205 
    206       // Keep URLs minimal; add more only when a concrete UI needs them.
    207       'urls' => [
    208         'shop' => ($active && function_exists('wc_get_page_permalink')) ? (string) wc_get_page_permalink('shop') : '',
    209       ],
    210 
    211       'features' => [],
    212     ];
    213 
    214     /**
    215      * Filter the basic WooCommerce settings array.
    216      *
    217      * @param array<string, mixed> $settings   Base settings.
    218      * @param array<string, mixed> $overrides  Caller overrides.
    219      */
    220     $settings = (array) apply_filters('smart_content_sync_woocommerce_settings_basic', $settings, $overrides);
    221 
    222     if (!empty($overrides)) {
    223       $settings = self::mergeDeep($settings, $overrides);
    224     }
    225 
    226     return $settings;
    227   }
    228 
    229   /**
    230    * Build an extended WooCommerce settings array suitable for script localization.
    231    *
    232    * This includes currency formatting details and (optionally) Store API nonce.
    233    * Use this only for admin UIs or frontend UIs that explicitly need these values.
    234    *
    235    * @param array<string, mixed> $overrides Optional overrides merged into the base settings.
    236    * @return array<string, mixed>
    237    */
    238   public static function buildWooCommerceSettingsExtended(array $overrides = []): array
    239   {
    240     $active = self::isWooCommerceActive();
    241     $installed = self::isWooCommerceInstalled();
    242 
    243193    // Start from the minimal base.
    244     $settings = self::buildWooCommerceSettingsBasic();
     194    // DO NOT pass the overrides here because:
     195    //   1- The filter below may override it. So, wait until just before return, and do a deep merge.
     196    //   2- We want to keep the basic payload stable and filterable on its own.
     197    $settings = self::buildWooCommerceClientConfig();
    245198
    246199    if (!$active) {
     
    251204       * @param array<string, mixed> $overrides  Caller overrides.
    252205       */
    253       $settings = (array) apply_filters('smart_content_sync_woocommerce_settings_extended', $settings, $overrides);
     206      $settings = (array) apply_filters('smart_content_sync_woocommerce_client_config_extended', $settings, $overrides);
    254207
    255208      if (!empty($overrides)) {
     
    288241     * @param array<string, mixed> $overrides  Caller overrides.
    289242     */
    290     $settings = (array) apply_filters('smart_content_sync_woocommerce_settings_extended', $settings, $overrides);
     243    $settings = (array) apply_filters('smart_content_sync_woocommerce_client_config_extended', $settings, $overrides);
    291244
    292245    if (!empty($overrides)) {
     
    304257   * Back-compat alias.
    305258   *
    306    * If existing call-sites already use buildWooCommerceSettings(), keep it working
    307    * but return the BASIC payload by default (lean and safe).
     259   * Builds the WooCommerce config payload. Use buildWooCommerceClientConfigExtended() if you need the extra any of the following:
     260   *  - currencySymbol
     261   *  - decimals
     262   *  - decimalSeparator
     263   *  - thousandSeparator
     264   *  - priceFormat.
    308265   *
    309266   * @param array<string, mixed> $overrides Optional overrides.
    310267   * @return array<string, mixed>
    311268   */
    312   public static function buildWooCommerceSettings(array $overrides = []): array
    313   {
    314     $settings = self::buildWooCommerceSettingsBasic($overrides);
    315 
    316     /**
    317      * Filter the WooCommerce settings array (legacy alias).
    318      *
    319      * @param array<string, mixed> $settings   Settings (basic by default).
    320      * @param array<string, mixed> $overrides  Caller overrides.
    321      */
    322     return (array) apply_filters('smart_content_sync_woocommerce_settings', $settings, $overrides);
     269  public static function buildWooCommerceClientConfig(array $overrides = []): array
     270  {
     271    $active = self::isWooCommerceActive();
     272    $installed = self::isWooCommerceInstalled();
     273
     274    $config = [
     275      'active' => $active,
     276      'installed' => $installed,
     277      'isSingleProduct' => $active ? self::isSingleProductPage() : false,
     278      'isWooRest' => $active ? self::isWooCommerceRestRequest() : false,
     279      'currentProductId' => $active ? self::getCurrentProductId() : null,
     280      'currency' => ($active && function_exists('get_woocommerce_currency')) ? (string) get_woocommerce_currency() : '',
     281      'urls' => [
     282        'shop' => ($active && function_exists('wc_get_page_permalink')) ? (string) wc_get_page_permalink('shop') : '',
     283      ],
     284    ];
     285
     286    if (!empty($overrides)) {
     287      $config = self::mergeDeep($config, $overrides);
     288    }
     289
     290    return $config;
    323291  }
    324292
  • smart-content-sync/trunk/src/Infrastructure/Platform/WordPress/WordPressHelper.php

    r3454742 r3487719  
    107107   *
    108108   * Intended use:
    109    * - wp_localize_script(..., 'smartContentSyncWp', WordPressHelper::buildWordPressSettings(...))
     109   * - wp_localize_script(..., 'smartContentSyncWp', WordPressHelper::buildWordPressClientConfig(...))
    110110   * - or wp_add_inline_script with JSON.
    111111   *
     
    118118   * @return array<string, mixed>
    119119   */
    120   public static function buildWordPressSettings(array $overrides = []): array
     120  public static function buildWordPressClientConfig(array $overrides = []): array
    121121  {
    122122    $locale = self::resolveLocale();
     
    157157        'canManageOptions' => function_exists('current_user_can') ? (bool) current_user_can('manage_options') : false,
    158158      ],
    159 
    160       // Feature switches / flags you may want client-side.
    161       // Keep these additive and conservative for v1.
    162       'features' => [],
    163159    ];
    164 
    165     /**
    166      * Filter the base WordPress settings array.
    167      *
    168      * @param array<string, mixed> $settings   Base settings.
    169      * @param array<string, mixed> $overrides  Caller overrides.
    170      */
    171     $settings = (array) apply_filters('smart_content_sync_wordpress_settings', $settings, $overrides);
    172160
    173161    if (!empty($overrides)) {
  • smart-content-sync/trunk/src/Plugin.php

    r3454742 r3487719  
    1313use AndalePlugins\SmartContentSync\ContentBlocks\Renderer\RenderingGateway;
    1414use AndalePlugins\SmartContentSync\ContentBlocks\SmartContentCustomPostType;
     15use AndalePlugins\SmartContentSync\Infrastructure\Client\ClientConfigBuilder;
    1516use AndalePlugins\SmartContentSync\Domains\AutoInsert\Services\AutoInsertIndex;
    1617use AndalePlugins\SmartContentSync\Domains\AutoInsert\Services\AutoInsertManager;
     
    141142  public function localizeAdminScripts(): void
    142143  {
    143     $data = [
    144       'ajaxUrl' => admin_url('admin-ajax.php'),
    145       'nonce' => wp_create_nonce('smart_content_sync_admin_nonce'),
    146       'wordPress' => WordPressHelper::buildWordPressSettings(),
    147       'wooCommerce' => WooCommerceHelper::buildWooCommerceSettings(),
     144    // $data = [
     145    //   'ajaxUrl' => admin_url('admin-ajax.php'),
     146    //   'nonce' => wp_create_nonce('smart_content_sync_admin_nonce'),
     147    //   'wordPress' => WordPressHelper::buildWordPressClientConfig(),
     148    //   'wooCommerce' => WooCommerceHelper::buildWooCommerceClientConfig(),
     149    //   'localization' => $this->buildLocalizationPayload(),
     150    // ];
     151    // wp_localize_script(
     152    //   'smart-content-sync-admin-script',
     153    //   'smartContentSyncAdminData',
     154    //   $data
     155    // );
     156
     157    $data = ClientConfigBuilder::buildAdminClientConfig([
     158      // This stays here because it is plugin-owned localization,
     159      // not platform context.
    148160      'localization' => $this->buildLocalizationPayload(),
    149     ];
     161    ]);
     162
    150163    wp_localize_script(
    151164      'smart-content-sync-admin-script',
  • smart-content-sync/trunk/vendor/autoload.php

    r3454742 r3487719  
    2323require_once __DIR__ . '/composer/autoload_real.php';
    2424
    25 return ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb::getLoader();
     25return ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768::getLoader();
  • smart-content-sync/trunk/vendor/composer/autoload_classmap.php

    r3454742 r3487719  
    3333    'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\Sections\\UninstallSettingsSection' => $baseDir . '/src/Infrastructure/Admin/Settings/Sections/UninstallSettingsSection.php',
    3434    'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\SettingsManager' => $baseDir . '/src/Infrastructure/Admin/Settings/SettingsManager.php',
     35    'AndalePlugins\\SmartContentSync\\Infrastructure\\Client\\ClientConfigBuilder' => $baseDir . '/src/Infrastructure/Client/ClientConfigBuilder.php',
    3536    'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WooCommerce\\WooCommerceHelper' => $baseDir . '/src/Infrastructure/Platform/WooCommerce/WooCommerceHelper.php',
    3637    'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WordPress\\WordPressHelper' => $baseDir . '/src/Infrastructure/Platform/WordPress/WordPressHelper.php',
  • smart-content-sync/trunk/vendor/composer/autoload_real.php

    r3454742 r3487719  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb
     5class ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768
    66{
    77    private static $loader;
     
    2323        }
    2424
    25         spl_autoload_register(array('ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb', 'loadClassLoader'), true, true);
     25        spl_autoload_register(array('ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768', 'loadClassLoader'), true, true);
    2626        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    27         spl_autoload_unregister(array('ComposerAutoloaderInit15c4633b3346ac34866474b910a7bcfb', 'loadClassLoader'));
     27        spl_autoload_unregister(array('ComposerAutoloaderInit645f9213d6e358ccf3bfe148e9b7f768', 'loadClassLoader'));
    2828
    2929        require __DIR__ . '/autoload_static.php';
    30         call_user_func(\Composer\Autoload\ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::getInitializer($loader));
     30        call_user_func(\Composer\Autoload\ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::getInitializer($loader));
    3131
    3232        $loader->register(true);
  • smart-content-sync/trunk/vendor/composer/autoload_static.php

    r3454742 r3487719  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit15c4633b3346ac34866474b910a7bcfb
     7class ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768
    88{
    99    public static $prefixLengthsPsr4 = array (
     
    4848        'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\Sections\\UninstallSettingsSection' => __DIR__ . '/../..' . '/src/Infrastructure/Admin/Settings/Sections/UninstallSettingsSection.php',
    4949        'AndalePlugins\\SmartContentSync\\Infrastructure\\Admin\\Settings\\SettingsManager' => __DIR__ . '/../..' . '/src/Infrastructure/Admin/Settings/SettingsManager.php',
     50        'AndalePlugins\\SmartContentSync\\Infrastructure\\Client\\ClientConfigBuilder' => __DIR__ . '/../..' . '/src/Infrastructure/Client/ClientConfigBuilder.php',
    5051        'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WooCommerce\\WooCommerceHelper' => __DIR__ . '/../..' . '/src/Infrastructure/Platform/WooCommerce/WooCommerceHelper.php',
    5152        'AndalePlugins\\SmartContentSync\\Infrastructure\\Platform\\WordPress\\WordPressHelper' => __DIR__ . '/../..' . '/src/Infrastructure/Platform/WordPress/WordPressHelper.php',
     
    6061    {
    6162        return \Closure::bind(function () use ($loader) {
    62             $loader->prefixLengthsPsr4 = ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::$prefixLengthsPsr4;
    63             $loader->prefixDirsPsr4 = ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::$prefixDirsPsr4;
    64             $loader->classMap = ComposerStaticInit15c4633b3346ac34866474b910a7bcfb::$classMap;
     63            $loader->prefixLengthsPsr4 = ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::$prefixLengthsPsr4;
     64            $loader->prefixDirsPsr4 = ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::$prefixDirsPsr4;
     65            $loader->classMap = ComposerStaticInit645f9213d6e358ccf3bfe148e9b7f768::$classMap;
    6566
    6667        }, null, ClassLoader::class);
Note: See TracChangeset for help on using the changeset viewer.