<?php /** * Theme functions and definitions * * @package HelloElementorChild */ /** * Load child theme css and optional scripts * * @return void */ function hello_elementor_child_enqueue_scripts() { wp_enqueue_style( 'hello-elementor-child-style', get_stylesheet_directory_uri() . '/style.css', [ 'hello-elementor-theme-style', ], '1.0.0' ); } add_action( 'wp_enqueue_scripts', 'hello_elementor_child_enqueue_scripts', 20 ); // Allow SVG add_filter( 'wp_check_filetype_and_ext', function($data, $file, $filename, $mimes) { global $wp_version; if ( $wp_version !== '4.7.1' ) { return $data; } $filetype = wp_check_filetype( $filename, $mimes ); return [ 'ext' => $filetype['ext'], 'type' => $filetype['type'], 'proper_filename' => $data['proper_filename'] ]; }, 10, 4 ); function cc_mime_types( $mimes ){ $mimes['svg'] = 'image/svg+xml'; return $mimes; } add_filter( 'upload_mimes', 'cc_mime_types' ); function fix_svg() { echo '<style type="text/css"> .attachment-266x266, .thumbnail img { width: 100% !important; height: auto !important; } </style>'; } add_action( 'admin_head', 'fix_svg' ); /*reading time*/ function reading_time() { $content = get_post_field( 'post_content', $post->ID ); $word_count = str_word_count( strip_tags( $content ) ); $readingtime = ceil($word_count / 260); if ($readingtime == 1) { $timer = " minute read"; } else { $timer = " minutes read"; } $totalreadingtime = $readingtime . $timer; return $totalreadingtime; } add_shortcode('wpbread', 'reading_time'); // Add Categories and Tags to Pages function wpse_add_tags_categories_to_pages() { register_taxonomy_for_object_type('post_tag', 'page'); register_taxonomy_for_object_type('category', 'page'); } add_action( 'init', 'wpse_add_tags_categories_to_pages' ); /*add excerpt to wp poststs*/ add_post_type_support( 'page', 'excerpt' ); // Disable XML-RPC add_filter('xmlrpc_enabled', '__return_false'); // Elementor description meta tag function remove_hello_elementor_description_meta_tag() { remove_action( 'wp_head', 'hello_elementor_add_description_meta_tag' ); } add_action( 'after_setup_theme', 'remove_hello_elementor_description_meta_tag' ); add_filter('flying_press_js_delay_timeout', function(){ return 60;}); //Edit something add_action('elementor/editor/before_enqueue_scripts', function() { wp_add_inline_script('elementor-editor', ' window.addEventListener("DOMContentLoaded", function() { const originalEntries = Object.entries; Object.entries = function(obj) { if (obj === null || obj === undefined) { return []; } return originalEntries.call(this, obj); }; }); ', 'before'); }, 5); // Fix Cloudflare Turnstile not loading in Elementor popups // The plugin uses native addEventListener for 'elementor/popup/show' // but Elementor fires it via jQuery. This patch bridges the gap. function cft_turnstile_popup_fix() { ?> <script> (function() { if (typeof jQuery === 'undefined') return; jQuery(document).on('elementor/popup/show', function(event, id, instance) { setTimeout(function() { var settings = window.cfturnstileElementorSettings || {}; if (settings.mode && settings.mode !== 'turnstile') return; if (!window.turnstile) return; // First, process any unprocessed forms in the popup var popupForms = document.querySelectorAll('.elementor-popup-modal .elementor-form:not(.cft-processed)'); popupForms.forEach(function(form, index) { var submitButton = form.querySelector('button[type="submit"]'); if (submitButton && settings.sitekey) { var turnstileDiv = document.createElement('div'); turnstileDiv.className = 'elementor-turnstile-field cf-turnstile'; turnstileDiv.id = 'cf-turnstile-popup-fix-' + id + '-' + index; turnstileDiv.style.cssText = 'display: block; margin: 10px 0 15px 0; width: 100%;'; submitButton.parentNode.insertBefore(turnstileDiv, submitButton); form.classList.add('cft-processed'); } }); // Clean up any stale/failed turnstile children first var popupTurnstile = document.querySelectorAll('.elementor-popup-modal .cf-turnstile'); popupTurnstile.forEach(function(el) { // Remove old failed widget content while (el.firstChild) { el.removeChild(el.firstChild); } try { turnstile.remove('#' + el.id); } catch(e) {} turnstile.render('#' + el.id, { sitekey: settings.sitekey, theme: settings.theme || 'auto', callback: function(token) { if (typeof turnstileElementorCallback === 'function') { turnstileElementorCallback(token); } } }); }); }, 1500); }); })(); </script> <?php } add_action('wp_footer', 'cft_turnstile_popup_fix', 999); add_action('wp_ajax_nopriv_custom_knotweed_form', 'handle_knotweed_form_submission'); add_action('wp_ajax_custom_knotweed_form', 'handle_knotweed_form_submission'); function handle_knotweed_form_submission() { if (!isset($_POST['name'], $_POST['phone'], $_POST['postcode'])) { wp_send_json_error('Required fields are missing'); } $form_fields = [ 'name' => sanitize_text_field($_POST['name']), 'phone' => sanitize_text_field($_POST['phone']), 'postcode' => sanitize_text_field($_POST['postcode']), 'service' => sanitize_text_field($_POST['service'] ?? 'Not selected'), 'email' => sanitize_email($_POST['email'] ?? ''), ]; $uploaded_file_url = ''; $attachment = []; if (!empty($_FILES['photo']['name'])) { require_once(ABSPATH . 'wp-admin/includes/file.php'); $upload = wp_handle_upload($_FILES['photo'], ['test_form' => false]); if (isset($upload['file']) && !empty($upload['file'])) { $uploaded_file_url = $upload['url']; $attachment[] = $upload['file']; $form_fields['photo'] = $uploaded_file_url; } } if (class_exists('\ElementorPro\Modules\Forms\Classes\Record')) { $record = new \ElementorPro\Modules\Forms\Classes\Record([ 'form_name' => 'Hero Knotweed Quote Form', 'form_id' => 'hero_knotweed_form', 'post_id' => get_the_ID(), 'fields' => $form_fields, 'uploaded_files' => !empty($uploaded_file_url) ? ['photo' => ['url' => $uploaded_file_url]] : [], ]); $record->add_submission(); } $to_email = 'expert@environetuk.com'; $subject = 'New Knotweed Quote Request - ' . $form_fields['name']; $message = "New quote request received:\n\n"; $message .= "Name: " . $form_fields['name'] . "\n"; $message .= 'Email: ' . (isset($form_fields['email']) ? $form_fields['email'] : 'N/A') . "\n"; $message .= "Phone: " . $form_fields['phone'] . "\n"; $message .= "Postcode: " . $form_fields['postcode'] . "\n"; $message .= "Service: " . $form_fields['service'] . "\n"; if (!empty($uploaded_file_url)) { $message .= "\nPhoto: " . $uploaded_file_url . "\n"; } $headers = ['Content-Type: text/plain; charset=UTF-8']; wp_mail($to_email, $subject, $message, $headers, $attachment); // Lead prosto do Azure CRM (zamiennik martwego n8n) environet_push_to_crm(array( 'Name' => $form_fields['name'], 'Email' => isset($form_fields['email']) ? $form_fields['email'] : '', 'Telephone' => $form_fields['phone'], 'Postcode' => $form_fields['postcode'], 'Message' => isset($form_fields['service']) ? $form_fields['service'] : '', 'File' => !empty($uploaded_file_url) ? $uploaded_file_url : 'NONE', 'form_id' => 'hero_knotweed_form', 'form_name' => 'Knotweed PPC Form', )); wp_send_json_success('Success'); } /* ========================================================================= * Environet: formularze -> Azure CRM (zamiennik automatyzacji n8n) * ========================================================================= */ /** * Wspolny helper - wysyla zmapowanego leada prosto do funkcji Azure. * Endpoint Azure jest tylko tutaj, w jednym miejscu. */ function environet_push_to_crm( array $body ) { $body = wp_parse_args( $body, array( 'Name' => '', 'Email' => '', 'Telephone' => '', 'Postcode' => '', 'Message' => '', 'File' => 'NONE', 'Terms' => 'I accept the terms and conditions', 'Date' => date_i18n( 'F j, Y' ), 'Time' => date_i18n( 'g:i a' ), 'Page URL' => isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( $_SERVER['HTTP_REFERER'] ) : '', 'form_id' => 'unknown', 'form_name' => 'Unknown Form', ) ); // Koperta w formacie ktorego oczekuje funkcja Azure: tablica z jednym obiektem $payload = array( array( 'headers' => array( 'host' => isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : '', 'user-agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '', ), 'params' => new stdClass(), 'query' => new stdClass(), 'body' => $body, 'webhookUrl' => '', 'executionMode' => 'production', ), ); $url = 'https://prod-webhookjsontolead-http.azurewebsites.net/api/Function1?code=NJLEOVYNWw/1ZBcRkMCqc/hG4x3OyFaXECwiaALkKsao9cp7Ufejaw=='; $response = wp_remote_post( $url, array( 'method' => 'POST', 'timeout' => 20, 'headers' => array( 'Content-Type' => 'application/json', 'Accept' => '*/*', ), 'body' => wp_json_encode( $payload ), ) ); // Log do debugowania - wlacz WP_DEBUG / WP_DEBUG_LOG w wp-config.php if ( is_wp_error( $response ) ) { error_log( 'Environet CRM error: ' . $response->get_error_message() ); } else { error_log( 'Environet CRM -> ' . wp_remote_retrieve_response_code( $response ) . ' ' . wp_remote_retrieve_body( $response ) ); } return $response; } /** * Formularze Elementor PRO (widget Form). Odpala sie na kazdy submit. * Domyslnie dla KAZDEJ formy - tak jak mialeś webhook wszedzie. * Jesli niektore formy nie maja isc do CRM, wpisz ID tych ktore MAJA isc w $allowed_forms. */ add_action( 'elementor_pro/forms/new_record', 'environet_form_to_crm', 10, 2 ); /** * Environet CRM Integration — Elementor Forms * Sends all Elementor form submissions directly to Dynamics 365 via Azure Function. * Replaces the broken n8n.hyroes.com webhook. * Fixed by IT MATES DIGITAL — 2026-06-17 */ function environet_form_to_crm( $record, $handler ) { $azure_url = 'https://prod-webhookjsontolead-http.azurewebsites.net/api/Function1'; $azure_code = 'NJLEOVYNWw/1ZBcRkMCqc/hG4x3OyFaXECwiaALkKsao9cp7Ufejaw=='; $form_name = $record->get_form_settings( 'form_name' ); $form_id = $record->get_form_settings( 'id' ); $raw_fields = $record->get( 'fields' ); $meta = $record->get( 'meta' ); $f = []; foreach ( $raw_fields as $id => $field ) { $f[ $id ] = sanitize_text_field( $field['value'] ?? '' ); } $body = [ 'Name' => $f['name'] ?? $f['full_name'] ?? '', 'Email' => $f['email'] ?? $f['email_address'] ?? '', 'Telephone' => $f['phone'] ?? $f['telephone'] ?? '', 'Postcode' => $f['postcode'] ?? $f['post_code'] ?? $f['zip'] ?? '', 'Message' => $f['message'] ?? $f['comments'] ?? $f['description'] ?? '', 'File' => $f['files'] ?? $f['file'] ?? 'NONE', 'Terms' => 'I accept the terms and conditions', 'Date' => $meta['date'] ?? wp_date( 'F j, Y' ), 'Time' => $meta['time'] ?? wp_date( 'g:i a' ), 'Page URL' => $meta['page_url'] ?? '', 'form_id' => $form_id, 'form_name' => $form_name, ]; $payload = [ [ 'headers' => [ 'host' => 'www.environetuk.com', 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . home_url(), ], 'params' => new \stdClass(), 'query' => new \stdClass(), 'body' => $body, 'webhookUrl' => home_url(), 'executionMode' => 'production', ], ]; wp_remote_post( add_query_arg( 'code', $azure_code, $azure_url ), [ 'timeout' => 15, 'blocking' => false, 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => '*/*', ], 'body' => wp_json_encode( $payload ), ] ); } /** * Naprawia bledny atrybut pattern w polach telefonu (Elementor formy). * Pod flaga v w nowych przegladarkach wzorzec z myslnikiem w srodku klasy * jest nieprawidlowy (traktowany jako zakres). Przepisujemy na wersje * z myslnikiem na koncu klasy. Dziala dla WSZYSTKICH form na stronie. */ add_action( 'wp_footer', 'environet_fix_phone_pattern', 99 ); function environet_fix_phone_pattern() { ?> <script> (function () { var BAD = "[0-9()#&+*-=.]+"; var GOOD = "[0-9\\(\\)#&+*=.\\-]+"; function fix() { document.querySelectorAll('input[pattern]').forEach(function (el) { if (el.getAttribute('pattern') === BAD) { el.setAttribute('pattern', GOOD); } }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', fix); } else { fix(); } document.addEventListener('submit', fix, true); })(); </script> <?php } Environet UK
It seems we can't find what you're looking for.

Start fixing your invasive plant problem today by requesting a survey

Rest assured, where invasive species are identified at an early stage and tackled correctly, problems can usually be avoided. Our specialist consultants complete thorough surveys to identify the extent of the problem. Our plans aren’t one-size-fits-all; they’re customised to tackle the invasive species at your property effectively, taking account of all of your requirements. 

GET IN TOUCH

Our team of experts is available between 9am and 5:30pm, Monday to Friday to answer your enquiries and advise you on the next steps

Want a survey?

If you already know you have an invasive plant problem, you can request a survey online in less than two minutes by providing a few brief details. A member of the team will swiftly come back to you with further information and our availability.

Need quick plant identification?

Simply upload a few images of your problem plant to our identification form and one of our invasive plant experts will take a look and let you know, free of charge what you are dealing with. We’ll also be there to help with next steps where necessary.