diff --git a/.github/instructions/php.instructions.md b/.github/instructions/php.instructions.md index 76df1cf7..b2143ee2 100644 --- a/.github/instructions/php.instructions.md +++ b/.github/instructions/php.instructions.md @@ -111,6 +111,7 @@ All PHP lives in `inc/` and is loaded via `functions.php`. Each file handles **o | `analytics-ga4.php` | GA4 registration + output | | `analytics-leadfeeder.php` | Leadfeeder registration + output | | `analytics-cookiebot.php` | CookieBot registration + output | +| `analytics-linkedin.php` | LinkedIn Insight Tag registration + output | | `theme-settings.php` | Settings page + sections | | `theme-settings-footer.php` | Footer content fields | diff --git a/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 00000000..93759f37 --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,8 @@ +{ + "servers": { + "shaders": { + "type": "http", + "url": "https://shaders.com/mcp" + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index d7a80cfd..14a84e17 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Each file handles **one concern**: | `analytics-ga4.php` | GA4 registration + output | | `analytics-leadfeeder.php` | Leadfeeder registration + output | | `analytics-cookiebot.php` | CookieBot registration + output | +| `analytics-linkedin.php` | LinkedIn Insight Tag registration + output | All functions are **fully typed** (parameter + return types). PHPStan runs at level 5 in CI to prevent type regressions. diff --git a/blocks/card-contact-form/block.json b/blocks/card-contact-form/block.json index 5f6c8718..e71353dd 100644 --- a/blocks/card-contact-form/block.json +++ b/blocks/card-contact-form/block.json @@ -19,9 +19,5 @@ "editorScript": "file:../../build/index.js", "editorStyle": "file:../../build/index.css", "viewStyle": ["file:card-contact-form.css"], - "example": { - "attributes": { - "formUrl": "https://forms.zohopublic.eu/Observata/form/Contactusforwebsite/formperma/WZY4ixkroGhjj-TNFSI45yFNmi5QFNBVWTdBcPxWMTE" - } - } + "example": {} } diff --git a/blocks/card-contact-form/card-contact-form.css b/blocks/card-contact-form/card-contact-form.css index dd9bcd7b..3ff4ab24 100644 --- a/blocks/card-contact-form/card-contact-form.css +++ b/blocks/card-contact-form/card-contact-form.css @@ -10,7 +10,7 @@ } .iframe-contact-form { - height: 699px; + height: 762px; @media (width >=64rem) { height: 600px; diff --git a/functions.php b/functions.php index cb69b037..3dd20929 100644 --- a/functions.php +++ b/functions.php @@ -14,6 +14,7 @@ require get_template_directory() . '/inc/analytics-ga4.php'; require get_template_directory() . '/inc/analytics-leadfeeder.php'; require get_template_directory() . '/inc/analytics-cookiebot.php'; +require get_template_directory() . '/inc/analytics-linkedin.php'; require get_template_directory() . '/inc/theme-settings.php'; require get_template_directory() . '/inc/theme-settings-footer.php'; require get_template_directory() . '/inc/image-optimization.php'; diff --git a/inc/analytics-linkedin.php b/inc/analytics-linkedin.php new file mode 100644 index 00000000..57c492ae --- /dev/null +++ b/inc/analytics-linkedin.php @@ -0,0 +1,109 @@ +. + */ + +add_action( 'admin_init', 'observata_linkedin_register_setting' ); +add_action( 'wp_head', 'observata_output_linkedin_script', 100 ); + +// ───────────────────────────────────────────────────────────────── + +// Register the LinkedIn Partner ID setting and admin field. +function observata_linkedin_register_setting(): void { + register_setting( + 'observata_settings', + 'observata_linkedin_id', + array( + 'type' => 'string', + 'sanitize_callback' => 'observata_sanitize_linkedin_id', + 'default' => '', + ) + ); + + add_settings_field( + 'observata_linkedin_id', + __( 'LinkedIn Partner ID', 'observata' ), + 'observata_linkedin_id_field', + 'observata-settings', + 'observata_analytics_section' + ); +} + +// Sanitize and validate the LinkedIn Partner ID format. +function observata_sanitize_linkedin_id( string $value ): string { + $value = sanitize_text_field( $value ); + + if ( $value && ! preg_match( '/^[0-9]+$/', $value ) ) { + add_settings_error( + 'observata_linkedin_id', + 'invalid-linkedin-id', + __( 'Invalid LinkedIn Partner ID. Expected digits only.', 'observata' ) + ); + + return ''; + } + + return $value; +} + +// Render the LinkedIn Partner ID input field. +function observata_linkedin_id_field(): void { + $value = get_option( 'observata_linkedin_id', '' ); + + printf( + '', + esc_attr( $value ) + ); + + printf( + '
%s
', + esc_html__( 'Enter your LinkedIn Partner ID (Insight Tag). Leave blank to disable.', 'observata' ) + ); +} + +// Output the consent-gated LinkedIn Insight Tag snippet in . +function observata_output_linkedin_script(): void { + if ( ! observata_is_production() ) { + return; + } + + $linkedin_id = get_option( 'observata_linkedin_id', '' ); + + if ( empty( $linkedin_id ) ) { + return; + } + + if ( is_admin() || wp_doing_ajax() ) { + return; + } + + // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript -- consent-gated via CookieBot + printf( + ' + + + ', + esc_js( $linkedin_id ), + esc_attr( $linkedin_id ) + ); + // phpcs:enable +} diff --git a/phpcs.xml b/phpcs.xml index a165d345..74bb22d2 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -57,6 +57,7 @@- Zoho Contact Form — preview not available in editor -
+ <> ++ Zoho Contact Form — preview not available in editor +
+ {formUrl && ( ++ + {formUrl} + +
+ )} +