From c3c046153539a9c1fc91c3146db6d2389bc1ddb5 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Wed, 18 Dec 2024 16:36:47 +0530 Subject: [PATCH] Move 'themeisle-content-forms' folder --- composer.json | 6 +- composer.lock | 721 ++++++++- .../content-forms/assets/content-forms.css | 111 ++ .../content-forms/assets/content-forms.js | 202 +++ obfx_modules/content-forms/form_manager.php | 212 +++ .../content-forms/includes/rest/server.php | 124 ++ .../beaver/beaver_widget_base.php | 991 ++++++++++++ .../beaver/beaver_widget_manager.php | 39 + ...themeisle-content-forms-beaver-contact.php | 151 ++ ...meisle-content-forms-beaver-newsletter.php | 140 ++ ...isle-content-forms-beaver-registration.php | 128 ++ .../beaver/includes/frontend.css.php | 218 +++ .../beaver/includes/frontend.php | 21 + .../widgets-admin/elementor/contact_admin.php | 205 +++ .../elementor/elementor_widget_base.php | 1343 +++++++++++++++++ .../elementor/elementor_widget_manager.php | 143 ++ .../elementor/newsletter_admin.php | 373 +++++ .../elementor/registration_admin.php | 180 +++ .../widgets-public/contact_public.php | 195 +++ .../widgets-public/newsletter_public.php | 295 ++++ .../widgets-public/registration_public.php | 106 ++ .../widgets-public/widget_actions_base.php | 176 +++ obfx_modules/content-forms/load.php | 8 + phpcs.xml | 1 + 24 files changed, 6048 insertions(+), 41 deletions(-) create mode 100644 obfx_modules/content-forms/assets/content-forms.css create mode 100644 obfx_modules/content-forms/assets/content-forms.js create mode 100644 obfx_modules/content-forms/form_manager.php create mode 100644 obfx_modules/content-forms/includes/rest/server.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_base.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_manager.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-contact.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-newsletter.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-registration.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.css.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/elementor/contact_admin.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_base.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_manager.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/elementor/newsletter_admin.php create mode 100644 obfx_modules/content-forms/includes/widgets-admin/elementor/registration_admin.php create mode 100644 obfx_modules/content-forms/includes/widgets-public/contact_public.php create mode 100644 obfx_modules/content-forms/includes/widgets-public/newsletter_public.php create mode 100644 obfx_modules/content-forms/includes/widgets-public/registration_public.php create mode 100644 obfx_modules/content-forms/includes/widgets-public/widget_actions_base.php create mode 100644 obfx_modules/content-forms/load.php diff --git a/composer.json b/composer.json index db2f7a78..92c1d5c7 100644 --- a/composer.json +++ b/composer.json @@ -32,13 +32,13 @@ "require": { "codeinwp/full-width-page-templates": "master", "codeinwp/themeisle-sdk": "^3.3", - "codeinwp/themeisle-content-forms": "dev-master", - "enshrined/svg-sanitize": "^0.19.0" + "enshrined/svg-sanitize": "^0.19.0", + "mailerlite/mailerlite-api-v2-php-sdk": "^0.2.3" }, "autoload": { "files": [ "vendor/codeinwp/themeisle-sdk/load.php", - "vendor/codeinwp/themeisle-content-forms/load.php", + "obfx_modules/content-forms/load.php", "obfx_modules/elementor-extra-widgets/load.php" ] }, diff --git a/composer.lock b/composer.lock index a9712af9..396c7e55 100644 --- a/composer.lock +++ b/composer.lock @@ -4,62 +4,88 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "546aea6b36d85bb230e554ad6bbf9576", + "content-hash": "a5901a219e53451f0aa0c4ae62edd951", "packages": [ { - "name": "codeinwp/full-width-page-templates", - "version": "dev-master", + "name": "clue/stream-filter", + "version": "v1.7.0", "source": { "type": "git", - "url": "https://github.com/Codeinwp/full-width-page-templates.git", - "reference": "ac15bbb1295d39baf28978c7d9c04fed21ea3429" + "url": "https://github.com/clue/stream-filter.git", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/full-width-page-templates/zipball/ac15bbb1295d39baf28978c7d9c04fed21ea3429", - "reference": "ac15bbb1295d39baf28978c7d9c04fed21ea3429", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7", "shasum": "" }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, "type": "library", "autoload": { "files": [ - "load.php" - ] + "src/functions_include.php" + ], + "psr-4": { + "Clue\\StreamFilter\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0-or-later" + "MIT" ], "authors": [ { - "name": "ThemeIsle team", - "email": "friends@themeisle.com", - "homepage": "https://themeisle.com" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "description": "A WordPress library to create full width page templates.", - "homepage": "https://github.com/Codeinwp/full-width-page-templates", - "time": "2019-04-02T11:34:00+00:00" + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "support": { + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.7.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2023-12-20T15:40:13+00:00" }, { - "name": "codeinwp/themeisle-content-forms", + "name": "codeinwp/full-width-page-templates", "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/Codeinwp/themeisle-content-forms.git", - "reference": "5489008fb3354940e878cc4db5f0300a4853fa39" + "url": "https://github.com/Codeinwp/full-width-page-templates.git", + "reference": "ac15bbb1295d39baf28978c7d9c04fed21ea3429" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/themeisle-content-forms/zipball/5489008fb3354940e878cc4db5f0300a4853fa39", - "reference": "5489008fb3354940e878cc4db5f0300a4853fa39", + "url": "https://api.github.com/repos/Codeinwp/full-width-page-templates/zipball/ac15bbb1295d39baf28978c7d9c04fed21ea3429", + "reference": "ac15bbb1295d39baf28978c7d9c04fed21ea3429", "shasum": "" }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", - "wptrt/wpthemereview": "*" - }, - "default-branch": true, "type": "library", "autoload": { "files": [ @@ -68,22 +94,18 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-3.0-or-later" + "GPL-2.0-or-later" ], "authors": [ { - "name": "ThemeIsle", + "name": "ThemeIsle team", "email": "friends@themeisle.com", "homepage": "https://themeisle.com" } ], - "description": "ThemeIsle Content Forms.", - "homepage": "https://github.com/Codeinwp/themeisle-content-forms", - "support": { - "issues": "https://github.com/Codeinwp/themeisle-content-forms/issues", - "source": "https://github.com/Codeinwp/themeisle-content-forms/tree/master" - }, - "time": "2024-03-05T15:01:05+00:00" + "description": "A WordPress library to create full width page templates.", + "homepage": "https://github.com/Codeinwp/full-width-page-templates", + "time": "2019-04-02T11:34:00+00:00" }, { "name": "codeinwp/themeisle-sdk", @@ -170,6 +192,631 @@ "source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.19.0" }, "time": "2024-06-18T10:27:15+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-04-17T16:00:37+00:00" + }, + { + "name": "mailerlite/mailerlite-api-v2-php-sdk", + "version": "0.2.3", + "source": { + "type": "git", + "url": "https://github.com/mailerlite/mailerlite-api-v2-php-sdk.git", + "reference": "2bae0aac12c4588bc0197d2e2dde5a55429b9e44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mailerlite/mailerlite-api-v2-php-sdk/zipball/2bae0aac12c4588bc0197d2e2dde5a55429b9e44", + "reference": "2bae0aac12c4588bc0197d2e2dde5a55429b9e44", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "~1.2", + "php": "^5.5|^7.0", + "php-http/curl-client": "^1.4", + "php-http/httplug": "^1.0", + "php-http/message": "^1.2" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "php-http/guzzle6-adapter": "^1.0", + "phpunit/phpunit": "5.3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MailerLiteApi\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "MailerLite API v2 PHP SDK", + "homepage": "https://github.com/mailerlite/mailerlite-api-v2-php-sdk", + "keywords": [ + "email", + "mailerlite", + "marketing", + "sdk" + ], + "support": { + "issues": "https://github.com/mailerlite/mailerlite-api-v2-php-sdk/issues", + "source": "https://github.com/mailerlite/mailerlite-api-v2-php-sdk/tree/master" + }, + "time": "2019-01-31T13:14:26+00:00" + }, + { + "name": "php-http/curl-client", + "version": "v1.7.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/curl-client.git", + "reference": "6341a93d00e5d953fc868a3928b5167e6513f2b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/curl-client/zipball/6341a93d00e5d953fc868a3928b5167e6513f2b6", + "reference": "6341a93d00e5d953fc868a3928b5167e6513f2b6", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": "^5.5 || ^7.0", + "php-http/discovery": "^1.0", + "php-http/httplug": "^1.0", + "php-http/message": "^1.2", + "php-http/message-factory": "^1.0.2" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0" + }, + "require-dev": { + "guzzlehttp/psr7": "^1.0", + "php-http/client-integration-tests": "^0.6", + "phpunit/phpunit": "^4.8.27", + "zendframework/zend-diactoros": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\Curl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Михаил Красильников", + "email": "m.krasilnikov@yandex.ru" + } + ], + "description": "cURL client for PHP-HTTP", + "homepage": "http://php-http.org", + "keywords": [ + "curl", + "http" + ], + "support": { + "issues": "https://github.com/php-http/curl-client/issues", + "source": "https://github.com/php-http/curl-client/tree/v1.7.1" + }, + "time": "2018-03-26T19:21:48+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "684855f2c2e9d0a61868b8f8d6bd0295c8a4b651" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/684855f2c2e9d0a61868b8f8d6bd0295c8a4b651", + "reference": "684855f2c2e9d0a61868b8f8d6bd0295c8a4b651", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" + }, + "require-dev": { + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^2.4", + "puli/composer-plugin": "1.0.0-beta10" + }, + "suggest": { + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories", + "puli/composer-plugin": "Sets up Puli which is recommended for Discovery to work. Check http://docs.php-http.org/en/latest/discovery.html for more details." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/master" + }, + "time": "2019-02-23T07:42:53+00:00" + }, + { + "name": "php-http/httplug", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "1c6381726c18579c4ca2ef1ec1498fdae8bdf018" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/1c6381726c18579c4ca2ef1ec1498fdae8bdf018", + "reference": "1c6381726c18579c4ca2ef1ec1498fdae8bdf018", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "php-http/promise": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/master" + }, + "time": "2016-08-31T08:30:17+00:00" + }, + { + "name": "php-http/message", + "version": "1.7.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "b159ffe570dffd335e22ef0b91a946eacb182fa1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/b159ffe570dffd335e22ef0b91a946eacb182fa1", + "reference": "b159ffe570dffd335e22ef0b91a946eacb182fa1", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.4", + "php": "^5.4 || ^7.0", + "php-http/message-factory": "^1.0.2", + "psr/http-message": "^1.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "akeneo/phpspec-skip-example-extension": "^1.0", + "coduo/phpspec-data-provider-extension": "^1.0", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0", + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4", + "slim/slim": "^3.0", + "zendframework/zend-diactoros": "^1.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation", + "zendframework/zend-diactoros": "Used with Diactoros Factories" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "files": [ + "src/filters.php" + ], + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "support": { + "issues": "https://github.com/php-http/message/issues", + "source": "https://github.com/php-http/message/tree/master" + }, + "time": "2018-11-01T09:32:41+00:00" + }, + { + "name": "php-http/message-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/4d8778e1c7d405cbb471574821c1ff5b68cc8f57", + "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/1.1.0" + }, + "abandoned": "psr/http-factory", + "time": "2023-04-14T14:16:17+00:00" + }, + { + "name": "php-http/promise", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/dc494cdc9d7160b9a09bd5573272195242ce7980", + "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980", + "shasum": "" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + }, + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/master" + }, + "time": "2016-01-26T13:27:02+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" } ], "packages-dev": [ @@ -554,9 +1201,7 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "codeinwp/themeisle-content-forms": 20 - }, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": [], diff --git a/obfx_modules/content-forms/assets/content-forms.css b/obfx_modules/content-forms/assets/content-forms.css new file mode 100644 index 00000000..4cc6e907 --- /dev/null +++ b/obfx_modules/content-forms/assets/content-forms.css @@ -0,0 +1,111 @@ +.ti-cf-module label { + display: block; + margin-top: 20px; +} +.ti-cf-module .content-form-field-hidden{ + display: none; +} +.ti-cf-module input:not([type="checkbox"]), +.ti-cf-module textarea { + width: 100%; + display: block; + border: 1px solid #cccccc; + border-radius: 3px; +} +.ti-cf-module label.checkbox-input{ + position: relative; + padding-left: 20px; +} + +.ti-cf-module label.checkbox-input input[type="checkbox"]{ + position: absolute; + left: 0; + top: 50%; + transform: translateY( -50% ); +} + +.ti-cf-module select{ + height: auto; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.ti-cf-module.content-form-newsletter select.country{ + width: 100%; + line-height: inherit; +} +.ti-cf-module fieldset { + border: none; + margin: 0; + flex-wrap: wrap; +} +.ti-cf-module .content-forms-required{ + width: 100%; +} + +.ti-cf-module .content-form-loading { + opacity: .5; + pointer-events: none; +} +.ti-cf-module .content-form-notice { + font-size: 18px; + padding: 5px; +} + +.ti-cf-module .content-form-notice-wrapper { + display: flex; + width: 100%; +} + +.ti-cf-module .content-form-success { + color: #53a813; + border: 2px solid #53a813; +} +.ti-cf-module .content-form-error { + color: #d5521a; + border: 2px solid #d5521a; +} + +.ti-cf-module.content-form { + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; +} + +.ti-cf-module.content-form .submit-form { + width: 100%; +} + +.ti-cf-module .form-control { + height: auto; +} + +.ti-cf-module.content-form-newsletter { + align-items: flex-end; +} + +.ti-cf-module.content-form-newsletter button { + margin: 0; +} + +.ti-cf-module.content-form-newsletter fieldset { + margin-bottom: 0; + padding-bottom: 0; +} + +.ti-cf-module.content-form-newsletter > .form-group .form-control { + margin-bottom: 0; + +} +.ti-cf-module.content-form-newsletter .elementor-column:not(.elementor-col-100) + .submit-form { + display: flex; width: auto; +} + +.ti-cf-module .elementor-button-icon svg{ + height: initial; +} diff --git a/obfx_modules/content-forms/assets/content-forms.js b/obfx_modules/content-forms/assets/content-forms.js new file mode 100644 index 00000000..035e7565 --- /dev/null +++ b/obfx_modules/content-forms/assets/content-forms.js @@ -0,0 +1,202 @@ +/*! +SerializeJSON jQuery plugin. +https://github.com/marioizquierdo/jquery.serializeJSON +version 2.8.1 (Dec, 2016) + +Copyright (c) 2012, 2017 Mario Izquierdo +Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) +and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. +*/ +!function (a) { + if ("function" == typeof define && define.amd) define(["jquery"], a); else if ("object" == typeof exports) { + var b = require("jquery"); + module.exports = a(b) + } else a(window.jQuery || window.Zepto || window.$) +}(function (a) { + "use strict"; + a.fn.serializeJSON = function (b) { + var c, d, e, f, g, h, i, j, k, l, m, n, o; + return c = a.serializeJSON, d = this, e = c.setupOpts(b), f = d.serializeArray(), c.readCheckboxUncheckedValues(f, e, d), g = {}, a.each(f, function (a, b) { + h = b.name, i = b.value, k = c.extractTypeAndNameWithNoType(h), l = k.nameWithNoType, m = k.type, m || (m = c.attrFromInputWithName(d, h, "data-value-type")), c.validateType(h, m, e), "skip" !== m && (n = c.splitInputNameIntoKeysArray(l), j = c.parseValue(i, h, m, e), o = !j && c.shouldSkipFalsy(d, h, l, m, e), o || c.deepSet(g, n, j, e)) + }), g + }, a.serializeJSON = { + defaultOptions: { + checkboxUncheckedValue: void 0, + parseNumbers: !1, + parseBooleans: !1, + parseNulls: !1, + parseAll: !1, + parseWithFunction: null, + skipFalsyValuesForTypes: [], + skipFalsyValuesForFields: [], + customTypes: {}, + defaultTypes: { + string: function (a) { + return String(a) + }, number: function (a) { + return Number(a) + }, boolean: function (a) { + var b = ["false", "null", "undefined", "", "0"]; + return b.indexOf(a) === -1 + }, null: function (a) { + var b = ["false", "null", "undefined", "", "0"]; + return b.indexOf(a) === -1 ? a : null + }, array: function (a) { + return JSON.parse(a) + }, object: function (a) { + return JSON.parse(a) + }, auto: function (b) { + return a.serializeJSON.parseValue(b, null, null, { + parseNumbers: !0, + parseBooleans: !0, + parseNulls: !0 + }) + }, skip: null + }, + useIntKeysAsArrayIndex: !1 + }, setupOpts: function (b) { + var c, d, e, f, g, h; + h = a.serializeJSON, null == b && (b = {}), e = h.defaultOptions || {}, d = ["checkboxUncheckedValue", "parseNumbers", "parseBooleans", "parseNulls", "parseAll", "parseWithFunction", "skipFalsyValuesForTypes", "skipFalsyValuesForFields", "customTypes", "defaultTypes", "useIntKeysAsArrayIndex"]; + for (c in b) if (d.indexOf(c) === -1) throw new Error("serializeJSON ERROR: invalid option '" + c + "'. Please use one of " + d.join(", ")); + return f = function (a) { + return b[a] !== !1 && "" !== b[a] && (b[a] || e[a]) + }, g = f("parseAll"), { + checkboxUncheckedValue: f("checkboxUncheckedValue"), + parseNumbers: g || f("parseNumbers"), + parseBooleans: g || f("parseBooleans"), + parseNulls: g || f("parseNulls"), + parseWithFunction: f("parseWithFunction"), + skipFalsyValuesForTypes: f("skipFalsyValuesForTypes"), + skipFalsyValuesForFields: f("skipFalsyValuesForFields"), + typeFunctions: a.extend({}, f("defaultTypes"), f("customTypes")), + useIntKeysAsArrayIndex: f("useIntKeysAsArrayIndex") + } + }, parseValue: function (b, c, d, e) { + var f, g; + return f = a.serializeJSON, g = b, e.typeFunctions && d && e.typeFunctions[d] ? g = e.typeFunctions[d](b) : e.parseNumbers && f.isNumeric(b) ? g = Number(b) : !e.parseBooleans || "true" !== b && "false" !== b ? e.parseNulls && "null" == b && (g = null) : g = "true" === b, e.parseWithFunction && !d && (g = e.parseWithFunction(g, c)), g + }, isObject: function (a) { + return a === Object(a) + }, isUndefined: function (a) { + return void 0 === a + }, isValidArrayIndex: function (a) { + return /^[0-9]+$/.test(String(a)) + }, isNumeric: function (a) { + return a - parseFloat(a) >= 0 + }, optionKeys: function (a) { + if (Object.keys) return Object.keys(a); + var b, c = []; + for (b in a) c.push(b); + return c + }, readCheckboxUncheckedValues: function (b, c, d) { + var e, f, g, h, i; + null == c && (c = {}), i = a.serializeJSON, e = "input[type=checkbox][name]:not(:checked):not([disabled])", f = d.find(e).add(d.filter(e)), f.each(function (d, e) { + if (g = a(e), h = g.attr("data-unchecked-value"), null == h && (h = c.checkboxUncheckedValue), null != h) { + if (e.name && e.name.indexOf("[][") !== -1) throw new Error("serializeJSON ERROR: checkbox unchecked values are not supported on nested arrays of objects like '" + e.name + "'. See https://github.com/marioizquierdo/jquery.serializeJSON/issues/67"); + b.push({name: e.name, value: h}) + } + }) + }, extractTypeAndNameWithNoType: function (a) { + var b; + return (b = a.match(/(.*):([^:]+)$/)) ? {nameWithNoType: b[1], type: b[2]} : {nameWithNoType: a, type: null} + }, shouldSkipFalsy: function (b, c, d, e, f) { + var g = a.serializeJSON, h = g.attrFromInputWithName(b, c, "data-skip-falsy"); + if (null != h) return "false" !== h; + var i = f.skipFalsyValuesForFields; + if (i && (i.indexOf(d) !== -1 || i.indexOf(c) !== -1)) return !0; + var j = f.skipFalsyValuesForTypes; + return null == e && (e = "string"), !(!j || j.indexOf(e) === -1) + }, attrFromInputWithName: function (a, b, c) { + var d, e, f; + return d = b.replace(/(:|\.|\[|\]|\s)/g, "\\$1"), e = '[name="' + d + '"]', f = a.find(e).add(a.filter(e)), f.attr(c) + }, validateType: function (b, c, d) { + var e, f; + if (f = a.serializeJSON, e = f.optionKeys(d ? d.typeFunctions : f.defaultOptions.defaultTypes), c && e.indexOf(c) === -1) throw new Error("serializeJSON ERROR: Invalid type " + c + " found in input name '" + b + "', please use one of " + e.join(", ")); + return !0 + }, splitInputNameIntoKeysArray: function (b) { + var c, d; + return d = a.serializeJSON, c = b.split("["), c = a.map(c, function (a) { + return a.replace(/\]/g, "") + }), "" === c[0] && c.shift(), c + }, deepSet: function (b, c, d, e) { + var f, g, h, i, j, k; + if (null == e && (e = {}), k = a.serializeJSON, k.isUndefined(b)) throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined"); + if (!c || 0 === c.length) throw new Error("ArgumentError: param 'keys' expected to be an array with least one element"); + f = c[0], 1 === c.length ? "" === f ? b.push(d) : b[f] = d : (g = c[1], "" === f && (i = b.length - 1, j = b[i], f = k.isObject(j) && (k.isUndefined(j[g]) || c.length > 2) ? i : i + 1), "" === g ? !k.isUndefined(b[f]) && a.isArray(b[f]) || (b[f] = []) : e.useIntKeysAsArrayIndex && k.isValidArrayIndex(g) ? !k.isUndefined(b[f]) && a.isArray(b[f]) || (b[f] = []) : !k.isUndefined(b[f]) && k.isObject(b[f]) || (b[f] = {}), h = c.slice(1), k.deepSet(b[f], h, d, e)) + } + } +}); + +(function ($) { + /** + * Watch for all the content forms and listen for a submit action + */ + $(document).on('submit', 'form.content-form', function (e) { + e.preventDefault(); + + var $form = $(this), + serialized = $form.serializeJSON(), + postData = { + form_type: serialized['form-type'], + form_id: serialized['form-id'], + post_id: serialized['post-id'], + form_builder: serialized['form-builder'], + data: serialized.data, + nonce: serialized['_wpnonce_' + serialized['form-type']], + }; + + $form.addClass('content-form-loading'); + + window.jQuery.ajax({ + url: contentFormsSettings.restUrl + `submit`, + dataType: 'json', + method: 'POST', + data: postData, + beforeSend: function (xhr) { + xhr.setRequestHeader('X-WP-Nonce', window.contentFormsSettings.nonce); + }, + success: function (data) { + $form.removeClass('content-form-loading'); + + var status = 'error'; + + if (typeof data.success !== "undefined" && data.success) { + status = 'success'; + } + + addContentFormNotice(data, status, $form); + }, + error: function (e) { + $form.removeClass('content-form-loading'); + + addContentFormNotice(e, 'error', $form); + + console.error(e) + } + }); + }); + + /** + * Handle Form notices + * @param notice + * @param type + * @param $form + */ + var addContentFormNotice = function (notice, type, $form) { + var noticeStatus = 'content-form-success'; + var $currentNotice = $form.find('.content-form-notice-wrapper'); + if (notice.success === false || (notice.status >= 400 && notice.status < 500) ) { + noticeStatus = 'content-form-error'; + } + var noticeData = typeof notice.responseText !== 'undefined' ? jQuery.parseJSON(notice.responseText) : notice; + var noticeText = noticeData.message; + var style = typeof formStyle !== 'undefined' && formStyle.formStyle !== '' ? formStyle.formStyle : ''; + + var noticeEl = '

' + noticeText + '

'; + + if ($currentNotice.length > 0) { + $currentNotice.replaceWith(noticeEl) + } else { + $form.prepend(noticeEl); + } + } +})(jQuery); diff --git a/obfx_modules/content-forms/form_manager.php b/obfx_modules/content-forms/form_manager.php new file mode 100644 index 00000000..e4ed2d06 --- /dev/null +++ b/obfx_modules/content-forms/form_manager.php @@ -0,0 +1,212 @@ +load_hooks(); + $this->make(); + } + + /** + * Load hooks and filters. + */ + private function load_hooks() { + // Enqueue scripts and styles + add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + + // Register the actions that forms do + add_action( 'rest_api_init', array( $this, 'register_widgets_actions' ) ); + + require_once 'includes/rest/server.php'; + $rest_server = new Server(); + $rest_server->register_hooks(); + } + + /** + * Register Elementor Widgets actions. + */ + public function register_widgets_actions() { + foreach ( self::$forms as $form ) { + require_once TI_CONTENT_FORMS_PATH . '/includes/widgets-public/' . $form . '_public.php'; + $admin_class = '\ThemeIsle\ContentForms\Includes\Widgets_Public\\' . ucwords( $form ) . '_Public'; + $admin = new $admin_class(); + $admin->init(); + } + } + + + + /** + * Enqueue scripts and styles. + */ + public function enqueue_scripts() { + + wp_register_script( 'content-forms', plugins_url( '/assets/content-forms.js', TI_CONTENT_FORMS_FILE ), array( 'jquery' ), TI_CONTENT_FORMS_VERSION, true ); + + wp_localize_script( + 'content-forms', + 'contentFormsSettings', + array( + 'restUrl' => esc_url_raw( rest_url() . 'content-forms/v1/' ), + 'nonce' => wp_create_nonce( 'wp_rest' ), + ) + ); + + wp_register_style( 'content-forms', plugins_url( '/assets/content-forms.css', __FILE__ ), array(), TI_CONTENT_FORMS_VERSION ); + + /** + * Use this filter to force the js loading on all pages. + * Otherwise, it will be loaded only if a content form is present + */ + if ( apply_filters( 'themeisle_content_forms_force_js_enqueue', false ) ) { + wp_enqueue_script( 'content-forms' ); + } + + /** + * Every theme with a better form style can disable the default content forms styles by returning a false + * to this filter `themeisle_content_forms_register_default_style`. + */ + if ( true === apply_filters( 'themeisle_content_forms_register_default_style', true ) ) { + wp_register_style( 'content-forms', plugins_url( '/assets/content-forms.css', TI_CONTENT_FORMS_FILE ), array(), TI_CONTENT_FORMS_VERSION ); + } + } + + /** + * Load Elementor, Beaver or other widgets manager class. + */ + private function make() { + if ( defined( 'ELEMENTOR_PATH' ) && class_exists( 'Elementor\Widget_Base' ) ) { + require_once 'includes/widgets-admin/elementor/elementor_widget_manager.php'; + $elementor_manager = new Elementor_Widget_Manager(); + $elementor_manager->init(); + } + + if ( class_exists( '\FLBuilderModel' ) ) { + require_once 'includes/widgets-admin/beaver/beaver_widget_manager.php'; + $beaver_manager = new Beaver_Widget_Manager(); + $beaver_manager->register_beaver_module(); + } + } + + /** + * Get the field key based on form attributes. + * + * @param array $field Field data. + * + * @return string + */ + public static function get_field_key_name( $field ) { + if ( array_key_exists( 'field_map', $field ) && ! empty( $field['field_map'] ) ) { + return strtoupper( $field['field_map'] ); + } + + if ( array_key_exists( 'key', $field ) && ! empty( $field['key'] ) ) { + return $field['key']; + } + + if ( ! empty( $field['label'] ) ) { + return sanitize_title( $field['label'] ); + } + + if ( ! empty( $field['placeholder'] ) ) { + return sanitize_title( $field['placeholder'] ); + } + + return 'field_' . $field['_id']; + } + + /** + * Get user roles. + * + * @return array + */ + public static function get_user_roles() { + global $wp_roles; + $all_roles = $wp_roles->roles; + $roles = array(); + foreach ( $all_roles as $role_key => $role_data ) { + $roles[ $role_key ] = $role_data['name']; + } + return $roles; + } + + /** + * @static + * @since 1.0.0 + * @access public + * @return Form_Manager + */ + public static function instance() { + if ( null === self::$instance ) { + self::$instance = new self(); + self::$instance->init(); + } + + return self::$instance; + } + + /** + * Throw error on object clone + * + * The whole idea of the singleton design pattern is that there is a single + * object therefore, we don't want the object to be cloned. + * + * @access public + * @since 1.0.0 + * @return void + */ + public function __clone() { + // Cloning instances of the class is forbidden. + _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'textdomain' ), '1.0.0' ); + } + + /** + * Disable unserializing of the class + * + * @access public + * @since 1.0.0 + * @return void + */ + public function __wakeup() { + // Unserializing instances of the class is forbidden. + _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'textdomain' ), '1.0.0' ); + } +} diff --git a/obfx_modules/content-forms/includes/rest/server.php b/obfx_modules/content-forms/includes/rest/server.php new file mode 100644 index 00000000..022ed655 --- /dev/null +++ b/obfx_modules/content-forms/includes/rest/server.php @@ -0,0 +1,124 @@ + \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'submit_form' ), + 'args' => array( + 'form_type' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'What type of form is submitted.', 'textdomain' ), + ), + 'nonce' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'The security key', 'textdomain' ), + ), + 'data' => array( + 'type' => 'json', + 'required' => true, + 'description' => __( 'The form must have data', 'textdomain' ), + ), + 'form_id' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'The form identifier.', 'textdomain' ), + ), + 'post_id' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'The form identifier.', 'textdomain' ), + ), + 'form_builder' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'Form builder.', 'textdomain' ), + ), + ), + 'permission_callback' => '__return_true', + ) + ); + } + + /** + * @param \WP_REST_Request $request + * + * @return mixed|\WP_REST_Response + */ + public function submit_form( $request ) { + $nonce = $request->get_param( 'nonce' ); + $form_id = $request->get_param( 'form_id' ); + + if ( ! wp_verify_nonce( $nonce, 'content-form-' . $form_id ) ) { + return new \WP_REST_Response( + array( + 'success' => false, + 'message' => esc_html__( 'Invalid nonce', 'textdomain' ), + ), + 400 + ); + + } + + $data = $request->get_param( 'data' ); + if ( empty( $data[ $form_id ] ) ) { + return new \WP_REST_Response( + array( + 'success' => false, + 'message' => esc_html__( 'Invalid Data ', 'textdomain' ) . $form_id, + ), + 400 + ); + } + + $data = $data[ $form_id ]; + $post_id = $request->get_param( 'post_id' ); + $form_type = $request->get_param( 'form_type' ); + $form_builder = $request->get_param( 'form_builder' ); + $return = array( + 'success' => false, + 'message' => esc_html__( 'Something went wrong', 'textdomain' ), + ); + + /** + * Each form type should be able to provide its own process of submitting data. + * Must return the success status and a message. + */ + $return = apply_filters( 'content_forms_submit_' . $form_type, $return, $data, $form_id, $post_id, $form_builder ); + $status = 200; + if ( $return['success'] === false ) { + $status = 400; + } + return new \WP_REST_Response( + $return, + $status + ); + } + +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_base.php b/obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_base.php new file mode 100644 index 00000000..0222843b --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_base.php @@ -0,0 +1,991 @@ +field_types = array( + 'text' => esc_html__( 'Text', 'textdomain' ), + 'email' => esc_html__( 'Email', 'textdomain' ), + 'textarea' => esc_html__( 'Textarea', 'textdomain' ), + 'password' => esc_html__( 'Password', 'textdomain' ), + ); + + $this->run_hooks(); + + $this->default_data = $this->widget_default_values(); + $this->module_settings = $this->get_module_settings(); + + parent::__construct( $data ); + } + + /** + * Enqueue scripts and styles + */ + public function enqueue_scripts() { + parent::enqueue_scripts(); + $this->add_js( 'content-forms' ); + $this->add_css( 'content-forms' ); + } + + /** + * Run hooks and filters. + */ + public function run_hooks() { + add_filter( 'fl_builder_register_settings_form', array( $this, 'filter_widget_settings' ), 10, 2 ); + add_filter( $this->get_type() . '_repeater_fields', array( $this, 'add_widget_repeater_fields' ) ); + add_filter( $this->get_type() . '_controls_fields', array( $this, 'add_widget_specific_controls' ) ); + } + + + /** + * Filter the form settings. + * + * @param array $form Form settings + * @param static $slug Form slug + * + * @return array + */ + public function filter_widget_settings( $form, $slug ) { + $form_widgets = array( 'class-themeisle-content-forms-beaver-newsletter', 'class-themeisle-content-forms-beaver-contact', 'class-themeisle-content-forms-beaver-registration' ); + if ( in_array( $slug, $form_widgets, true ) ) { + return $this->module_settings; + } + + return $form; + } + + /** + * Beaver Widget style settings. + * + * @param array $args Settings array. + * + * @return array + */ + private function get_style_settings( $args ) { + $args['style']['sections'] = array( + 'spacing' => array( + 'title' => esc_html__( 'Spacing', 'textdomain' ), + 'fields' => array( + 'column_gap' => array( + 'responsive' => true, + 'type' => 'unit', + 'units' => array( 'px' ), + 'label' => __( 'Columns Gap', 'textdomain' ), + 'slider' => array( + 'min' => 0, + 'max' => 60, + 'step' => 1, + ), + 'preview' => array( + 'type' => 'css', + 'rules' => array( + array( + 'selector' => '.content-form-' . $this->get_type() . ' fieldset', + 'property' => 'padding-right', + ), + array( + 'selector' => '.content-form-' . $this->get_type() . ' fieldset', + 'property' => 'padding-left', + ), + ), + ), + ), + 'row_gap' => array( + 'responsive' => true, + 'type' => 'unit', + 'units' => array( 'px' ), + 'label' => __( 'Rows Gap', 'textdomain' ), + 'slider' => array( + 'min' => 0, + 'max' => 60, + 'step' => 1, + ), + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset', + 'property' => 'margin-bottom', + ), + ), + ), + ), + 'label' => array( + 'title' => esc_html__( 'Label', 'textdomain' ), + 'fields' => array( + 'label_color' => array( + 'type' => 'color', + 'label' => __( 'Text Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset label', + 'property' => 'color', + ), + + ), + 'mark_required_color' => array( + 'type' => 'color', + 'label' => __( 'Mark Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset label .required-mark', + 'property' => 'color', + ), + ), + 'label_typography' => array( + 'type' => 'typography', + 'label' => __( 'Label Typography', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset label', + ), + ), + ), + ), + 'field' => array( + 'title' => esc_html__( 'Field', 'textdomain' ), + 'fields' => array( + 'field_text_color' => array( + 'type' => 'color', + 'label' => __( 'Text Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset input, .content-form-' . $this->get_type() . ' fieldset textarea, .content-form-' . $this->get_type() . ' fieldset select, .content-form-' . $this->get_type() . ' fieldset input::placeholder, .content-form-' . $this->get_type() . ' fieldset textarea::placeholder, .content-form-' . $this->get_type() . ' fieldset select::placeholder', + 'property' => 'color', + ), + ), + 'field_background_color' => array( + 'type' => 'color', + 'label' => __( 'Background Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset input, .content-form-' . $this->get_type() . ' fieldset textarea, .content-form-' . $this->get_type() . ' fieldset select', + 'property' => 'background-color', + ), + ), + 'field_typography' => array( + 'type' => 'typography', + 'label' => __( 'Field Typography', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset input, .content-form-' . $this->get_type() . ' fieldset select, .content-form-' . $this->get_type() . ' fieldset textarea', + ), + ), + 'field_border' => array( + 'type' => 'border', + 'label' => __( 'Border', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset input, .content-form-' . $this->get_type() . ' fieldset textarea, .content-form-' . $this->get_type() . ' fieldset select', + ), + ), + ), + ), + 'button' => array( + 'title' => esc_html__( 'Submit Button', 'textdomain' ), + 'fields' => array( + 'button_width' => array( + 'responsive' => 'true', + 'type' => 'unit', + 'label' => __( 'Width', 'textdomain' ), + 'units' => array( 'px', 'vw', '%' ), + 'default_unit' => 'px', // Optional + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + 'property' => 'width', + ), + ), + 'button_height' => array( + 'responsive' => 'true', + 'type' => 'unit', + 'label' => __( 'Height', 'textdomain' ), + 'units' => array( 'px', 'vw', '%' ), + 'default_unit' => 'px', // Optional + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + 'property' => 'height', + ), + ), + 'button_background_color' => array( + 'type' => 'color', + 'label' => __( 'Button Background Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + 'property' => 'background-color', + ), + ), + 'button_text_color' => array( + 'type' => 'color', + 'label' => __( 'Button Text Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + 'property' => 'color', + ), + ), + 'button_typography' => array( + 'type' => 'typography', + 'label' => __( 'Typography', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + ), + ), + 'button_border' => array( + 'type' => 'border', + 'label' => __( 'Border', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + ), + ), + ), + ), + 'button_hover' => array( + 'title' => esc_html__( 'Submit Button Hover', 'textdomain' ), + 'fields' => array( + 'button_background_color_hover' => array( + 'type' => 'color', + 'label' => __( 'Button Background Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]:hover', + 'property' => 'background-color', + ), + ), + 'button_text_color_hover' => array( + 'type' => 'color', + 'label' => __( 'Button Text Color', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]:hover', + 'property' => 'color', + ), + ), + 'button_typography_hover' => array( + 'type' => 'typography', + 'label' => __( 'Typography', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]:hover', + ), + ), + 'button_border_hover' => array( + 'type' => 'border', + 'label' => __( 'Border Hover', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]:hover', + ), + ), + ), + ), + 'notification' => array( + 'title' => esc_html__( 'Notification', 'textdomain' ), + 'fields' => array( + 'notification_margin' => array( + 'type' => 'dimension', + 'label' => __( 'Margin', 'textdomain' ), + 'description' => 'px', + ), + 'notification_text_padding' => array( + 'type' => 'dimension', + 'label' => __( 'Padding', 'textdomain' ), + 'description' => 'px', + ), + 'notification_width' => array( + 'type' => 'unit', + 'label' => __( 'Width', 'textdomain' ), + 'slider' => array( + 'min' => 0, + 'max' => 100, + 'step' => 1, + ), + ), + 'notification_typography' => array( + 'type' => 'typography', + 'label' => __( 'Typography', 'textdomain' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-notice', + ), + ), + 'notification_box_shadow' => array( + 'type' => 'shadow', + 'label' => __( 'Box Shadow', 'textdomain' ), + 'show_spread' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-notice', + 'property' => 'box-shadow', + ), + ), + 'notification_alignment' => array( + 'type' => 'align', + 'label' => __( 'alignment', 'textdomain' ), + 'default' => 'left', + ), + ), + ), + 'notification_success' => array( + 'title' => esc_html__( 'Notification Success', 'textdomain' ), + 'fields' => array( + 'notification_success_background_color' => array( + 'type' => 'color', + 'label' => __( 'Background', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-success', + 'property' => 'background-color', + ), + ), + 'notification_success_text_color' => array( + 'type' => 'color', + 'label' => __( 'Text', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-success', + 'property' => 'color', + ), + ), + 'notification_success_border' => array( + 'type' => 'border', + 'label' => __( 'Border', 'textdomain' ), + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-success', + ), + ), + ), + ), + 'notification_error' => array( + 'title' => esc_html__( 'Notification Error', 'textdomain' ), + 'fields' => array( + 'notification_error_background_color' => array( + 'type' => 'color', + 'label' => __( 'Background', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-error', + 'property' => 'background-color', + ), + ), + 'notification_error_text_color' => array( + 'type' => 'color', + 'label' => __( 'Text', 'textdomain' ), + 'show_reset' => true, + 'show_alpha' => false, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-error', + 'property' => 'color', + ), + ), + 'notification_error_border' => array( + 'type' => 'border', + 'label' => __( 'Border', 'textdomain' ), + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-error', + ), + ), + ), + ), + ); + return $args; + } + + /** + * Beaver Widget form settings. + * + * @param array $args Settings array. + * + * @return array + */ + private function get_form_settings( $args ) { + $args['general']['sections']['settings'] = array( + 'title' => esc_html__( 'Fields', 'textdomain' ), + 'fields' => array( + 'fields' => array( + 'multiple' => true, + 'type' => 'form', + 'label' => esc_html__( 'Field', 'textdomain' ), + 'form' => $this->get_type() . '_field', + 'preview_text' => 'label', + 'default' => $this->get_default( 'fields' ), + ), + 'hide_label' => array( + 'type' => 'select', + 'label' => __( 'Hide Label', 'textdomain' ), + 'default' => 'show', + 'options' => array( + 'hide' => esc_html__( 'Hide', 'textarea' ), + 'show' => esc_html__( 'Show', 'textarea' ), + ), + ), + ), + ); + + $fields_type = $this->get_specific_field_types(); + $repeater_fields = array( + 'label' => array( + 'type' => 'text', + 'label' => esc_html__( 'Label', 'textdomain' ), + ), + 'placeholder' => array( + 'type' => 'text', + 'label' => esc_html__( 'Placeholder', 'textdomain' ), + ), + 'type' => array( + 'type' => 'select', + 'label' => esc_html__( 'Type', 'textdomain' ), + 'options' => $fields_type, + 'toggle' => array( + 'password' => array( + 'fields' => array( 'placeholder', 'field_width', 'required', 'label' ), + ), + 'textarea' => array( + 'fields' => array( 'placeholder', 'field_width', 'required', 'label' ), + ), + 'email' => array( + 'fields' => array( 'placeholder', 'field_width', 'required', 'label' ), + ), + 'text' => array( + 'fields' => array( 'placeholder', 'field_width', 'required', 'label' ), + ), + 'hidden' => array( + 'fields' => array( 'hidden_value', 'label' ), + ), + 'checkbox' => array( + 'fields' => array( 'field_width', 'required', 'label' ), + ), + ), + ), + 'field_width' => array( + 'type' => 'select', + 'label' => esc_html__( 'Field Width', 'textdomain' ), + 'options' => array( + '100' => '100%', + '75' => '75%', + '66' => '66%', + '50' => '50%', + '33' => '33%', + '25' => '25%', + ), + 'responsive' => true, + ), + 'required' => array( + 'type' => 'select', + 'label' => esc_html__( 'Is required?', 'textdomain' ), + 'options' => array( + 'required' => esc_html__( 'Required', 'textdomain' ), + 'optional' => esc_html__( 'Optional', 'textdomain' ), + ), + ), + ); + + \FLBuilder::register_settings_form( + $this->get_type() . '_field', + array( + 'title' => esc_html__( 'Field', 'textdomain' ), + 'tabs' => array( + 'general' => array( + 'title' => esc_html__( 'Field', 'textdomain' ), + 'sections' => array( + 'fields' => array( + 'title' => esc_html__( 'Field', 'textdomain' ), + 'fields' => apply_filters( $this->get_type() . '_repeater_fields', $repeater_fields ), + ), + ), + ), + ), + ) + ); + + return $args; + } + + /** + * Beaver Widget controls settings. + * + * @param array $args Settings array. + * + * @return array + */ + private function get_control_settings( $args ) { + $args['general']['sections']['controls'] = apply_filters( + $this->get_type() . '_controls_fields', + array( + 'title' => esc_html__( 'Form Settings', 'textdomain' ), + 'fields' => array( + 'submit_label' => array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'textdomain' ), + 'default' => $this->get_default( 'submit_label' ), + 'description' => esc_html__( 'The Call To Action label', 'textdomain' ), + ), + 'submit_display' => array( + 'type' => 'select', + 'label' => __( 'Submit Display', 'textdomain' ), + 'options' => array( + 'inline' => esc_html__( 'Inline', 'textarea' ), + 'block' => esc_html__( 'Block', 'textarea' ), + ), + 'toggle' => array( + 'block' => array( + 'fields' => array( 'submit_position' ), + ), + ), + ), + 'submit_position' => array( + 'type' => 'align', + 'label' => esc_html__( 'Alignment', 'textdomain' ), + 'default' => 'left', + ), + ), + ) + ); + return $args; + } + + /** + * Set module settings. + */ + private function get_module_settings() { + + $args = array( + 'general' => array( + 'title' => $this->get_widget_name(), + 'sections' => array(), + ), + 'style' => array( + 'title' => esc_html__( 'Style', 'textdomain' ), + 'sections' => array(), + ), + ); + + $args = $this->get_style_settings( $args ); + $args = $this->get_form_settings( $args ); + $args = $this->get_control_settings( $args ); + + return $args; + } + + /** + * Get default config data. + * + * @param string $field Field to retrieve. + * @return array | string | bool + */ + public function get_default( $field ) { + if ( ! array_key_exists( $field, $this->default_data ) ) { + return false; + } + return $this->default_data[ $field ]; + } + + /** + * Render the preview of form notifications. + * + * @return bool + */ + private function maybe_render_form_notification() { + if ( ! \FLBuilderModel::is_builder_active() ) { + return false; + } + + $style = '';//$this->get_notice_style(); + + echo '
'; + echo '

' . __( 'This is a preview of how the success notification will look', 'textdomain' ) . '

'; + echo '
'; + + echo '
'; + echo '

' . __( 'This is a preview of how the error notification will look', 'textdomain' ) . '

'; + echo '
'; + + return true; + } + /** + * Render the header of the form based on the block id(for JS identification) + * + * @param $id + */ + public function render_form_header( $id ) { + $url = admin_url( 'admin-post.php' ); + echo '
'; + $this->maybe_render_form_notification(); + wp_nonce_field( 'content-form-' . $id, '_wpnonce_' . $this->get_type() ); + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + /** + * Render form errors. + * + * @return bool + */ + public function maybe_render_form_errors( $widget_id ) { + $has_error = false; + if ( ! current_user_can( 'manage_options' ) ) { + return $has_error; + } + $widget = $this->get_type(); + + require_once TI_CONTENT_FORMS_PATH . '/includes/widgets-public/widget_actions_base.php'; + $widget_settings = Widget_Actions_Base::get_beaver_module_settings_by_id( $widget_id, get_the_ID() ); + + if ( $widget === 'newsletter' ) { + + echo '
'; + + if ( array_key_exists( 'access_key', (array) $widget_settings ) && empty( $widget_settings['access_key'] ) ) { + echo '

'; + printf( + esc_html__( 'The %s setting is required!', 'textdomain' ), + '' . esc_html__( 'Access Key', 'textdomain' ) . '' + ); + echo '

'; + $has_error = true; + } + + if ( array_key_exists( 'list_id', (array) $widget_settings ) && empty( $widget_settings['list_id'] ) ) { + echo '

'; + printf( + esc_html__( 'The %s setting is required!', 'textdomain' ), + '' . esc_html__( 'List id', 'textdomain' ) . '' + ); + echo '

'; + $has_error = true; + } + + $form_fields = $widget_settings['fields']; + $mapping = array(); + foreach ( (array) $form_fields as $field ) { + $field_map = $field->field_map; + if ( in_array( $field_map, $mapping, true ) ) { + echo '

'; + printf( + esc_html__( 'The %s field is mapped to multiple form fields. Please check your field settings.', 'textdomain' ), + '' . $field_map . '' + ); + echo '

'; + $has_error = true; + } + array_push( $mapping, $field_map ); + } + + echo '
'; + + return $has_error; + } + + if ( $widget === 'contact' ) { + if ( array_key_exists( 'to_send_email', (array) $widget_settings ) && empty( $widget_settings['to_send_email'] ) ) { + echo '

'; + printf( + esc_html__( 'The %s setting is required!', 'textdomain' ), + '' . esc_html__( 'Send to Email Address', 'textdomain' ) . '' + ); + echo '

'; + $has_error = true; + } + } + + return $has_error; + } + + /** + * Render form fields + */ + public function render_form_field( $field, $label_visibility ) { + $key = Form_Manager::get_field_key_name( $field ); + $key = $key === 'ADDRESS' ? $key = 'ADDRESS[addr1]' : $key; + $form_id = $this->node; + $field_name = 'data[' . $form_id . '][' . $key . ']'; + $required = $field['required'] === 'required' ? 'required="required"' : ''; + $placeholder = array_key_exists( 'placeholder', (array) $field ) && ! empty( $field['placeholder'] ) ? 'placeholder="' . esc_attr( $field['placeholder'] ) . '"' : ''; + $width = array_key_exists( 'field_width', (array) $field ) && ! empty( $field['field_width'] ) ? 'style="width:' . $field['field_width'] . '%"' : ''; + + echo '
'; + if ( $label_visibility === 'show' ) { + $this->maybe_render_field_label( $field_name, $field ); + } + + switch ( $field['type'] ) { + case 'textarea': + echo ''; + break; + case 'password': + echo ''; + break; + case 'hidden': + echo ''; + break; + case 'checkbox': + $label = $field['label']; + if ( ! empty( $label ) ) { + echo ''; + } + break; + default: + echo ''; + break; + } + + echo '
'; + + } + + /** + * @param $field + * @param $label_visibility + * @param $widget_id + * + * @return bool + */ + public function maybe_render_newsletter_address( $field, $widget_id ) { + require_once TI_CONTENT_FORMS_PATH . '/includes/widgets-public/widget_actions_base.php'; + $widget_settings = Widget_Actions_Base::get_beaver_module_settings_by_id( $widget_id, get_the_ID() ); + if ( ! is_array( $widget_settings ) ) { + return false; + } + if ( ! array_key_exists( 'provider', (array) $widget_settings ) || $widget_settings['provider'] !== 'mailchimp' ) { + return false; + } + + if ( ! array_key_exists( 'field_map', (array) $field ) || strtolower( $field['field_map'] ) !== 'address' ) { + return false; + } + + $display_label = $widget_settings['hide_label']; + $required = $field['required'] === 'required' ? 'required="required"' : ''; + $width = array_key_exists( 'field_width', (array) $field ) ? 'style="width:' . $field['field_width'] . '%"' : ''; + $address_fields = array( + 'addr2' => __( 'Address Line 2', 'textdomain' ), + 'city' => __( 'City', 'textdomain' ), + 'state' => __( 'State/Province/Region', 'textdomain' ), + 'zip' => __( 'Postal / Zip Code', 'textdomain' ), + 'country' => __( 'Country', 'textdomain' ), + ); + foreach ( $address_fields as $address_item => $item_label ) { + $placeholder = array_key_exists( 'placeholder', (array) $field ) && ! empty( $field['placeholder'] ) ? 'placeholder="' . esc_attr( $item_label ) . '"' : ''; + $field_name = 'data[' . $widget_id . '][ADDRESS[' . $address_item . ']]'; + echo '
'; + + if ( $display_label !== 'hide' ) { + echo ''; + } + + if ( $address_item === 'country' ) { + echo '
'; + echo ''; + echo '
'; + } else { + echo ''; + } + + echo '
'; + } + return true; + } + + /** + * @param $field_name + * @param $field + * @return bool + */ + private function maybe_render_field_label( $field_name, $field ) { + if ( $field['type'] === 'hidden' || $field['type'] === 'checkbox' ) { + return false; + } + $label = $field['label']; + if ( empty( $label ) ) { + return false; + } + + echo ''; + + return true; + } + + /** + * Check numeric css property in frontend.css.php + * + * @param Object $settings Settings object. + * @param string $property_name Property name. + * + * @return bool + */ + public function check_numeric_property( $settings, $property_name ) { + return property_exists( $settings, $property_name ) && is_numeric( $settings->$property_name ); + } + + /** + * Check color css property in frontend.css.php + * + * @param Object $settings Settings object. + * @param string $property_name Property name. + * + * @return bool + */ + public function check_color_property( $settings, $property_name ) { + return property_exists( $settings, $property_name ) && ctype_xdigit( $settings->$property_name ) && strlen( $settings->$property_name ) === 6; + } + + /** + * Check if not empty property in frontend.css.php + * + * @param Object $settings Settings object. + * @param string $property_name Property name. + * + * @return bool + */ + public function check_not_empty_property( $settings, $property_name ) { + return property_exists( $settings, $property_name ) && ! empty( $settings->$property_name ); + } + + /** + * Render form footer. + */ + public function render_form_footer() { + echo '
'; + } + + /** + * Get form type. + * @return string + */ + abstract function get_type(); + + /** + * Get widget name. + * + * @return string + */ + abstract function get_widget_name(); + + /** + * Add widget specific repeater fields. + * + * @param array $fields Repeater fields. + * @return mixed + */ + abstract function add_widget_repeater_fields( $fields ); + + /** + * Add widget specific controls. + * + * @param array $fields Widget fields. + * @return mixed + */ + abstract function add_widget_specific_controls( $fields ); + + /** + * Set default values for registration widget. + * + * @return array + */ + abstract function widget_default_values(); + + /** + * Get allowed field types. + * + * @return array + */ + abstract function get_specific_field_types(); +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_manager.php b/obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_manager.php new file mode 100644 index 00000000..b20d14cd --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/beaver/beaver_widget_manager.php @@ -0,0 +1,39 @@ + array( + array( + 'key' => 'name', + 'label' => esc_html__( 'Name', 'textdomain' ), + 'placeholder' => esc_html__( 'Name', 'textdomain' ), + 'type' => 'text', + 'field_width' => '100', + 'required' => 'required', + ), + array( + 'key' => 'email', + 'label' => esc_html__( 'Email', 'textdomain' ), + 'placeholder' => esc_html__( 'Email', 'textdomain' ), + 'type' => 'email', + 'field_width' => '100', + 'required' => 'required', + ), + array( + 'key' => 'phone', + 'label' => esc_html__( 'Phone', 'textdomain' ), + 'placeholder' => esc_html__( 'Phone', 'textdomain' ), + 'type' => 'number', + 'field_width' => '100', + 'required' => 'optional', + ), + array( + 'key' => 'message', + 'label' => esc_html__( 'Message', 'textdomain' ), + 'placeholder' => esc_html__( 'Message', 'textdomain' ), + 'type' => 'textarea', + 'field_width' => '100', + 'required' => 'required', + ), + ), + 'submit_label' => esc_html__( 'Submit', 'textdomain' ), + 'success_message' => esc_html__( 'Your message has been sent!', 'textdomain' ), + 'error_message' => esc_html__( 'Oops! I cannot send this email!', 'textdomain' ), + ); + } + + /** + * Contact_Admin constructor. + */ + public function __construct() { + parent::__construct( + array( + 'name' => esc_html__( 'Contact', 'textdomain' ), + 'description' => esc_html__( 'A contact form.', 'textdomain' ), + 'category' => esc_html__( 'Orbit Fox Modules', 'textdomain' ), + 'dir' => dirname( __FILE__ ), + 'url' => plugin_dir_url( __FILE__ ), + ) + ); + } + + /** + * Add map field for Contact field + * @param array $fields Repeater fields. + * @return array + */ + public function add_widget_repeater_fields( $fields ) { + $fields['hidden_value'] = array( + 'type' => 'textarea', + 'label' => esc_html__( 'Value', 'textdomain' ), + 'description' => __( 'You can use the following magic tags to get additional information: {current_url}, {username}, {user_nice_name}, {user_type}, {user_email}', 'textdomain' ), + ); + return $fields; + } + + /** + * Add specific controls for this type of widget. + * + * @param array $fields Fields config. + * + * @return array + */ + public function add_widget_specific_controls( $fields ) { + $fields['fields'] = array( + 'success_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Success message', 'textdomain' ), + 'default' => $this->get_default( 'success_message' ), + ), + 'error_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'textdomain' ), + 'default' => $this->get_default( 'error_message' ), + ), + 'to_send_email' => array( + 'type' => 'text', + 'label' => esc_html__( 'Send to', 'textdomain' ), + 'description' => esc_html__( 'Where should we send the email?', 'textdomain' ), + 'default' => get_bloginfo( 'admin_email' ), + ), + ) + $fields['fields']; + return $fields; + } + + /** + * Get specific field types. + * + * @return array + */ + function get_specific_field_types() { + $field_types = $this->field_types; + $field_types['checkbox'] = esc_html__( 'Checkbox', 'textdomain' ); + $field_types['hidden'] = esc_html__( 'Hidden', 'textdomain' ); + return $field_types; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-newsletter.php b/obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-newsletter.php new file mode 100644 index 00000000..5f476e32 --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-newsletter.php @@ -0,0 +1,140 @@ + array( + array( + 'key' => 'email', + 'label' => esc_html__( 'Email', 'textdomain' ), + 'placeholder' => esc_html__( 'Email', 'textdomain' ), + 'type' => 'email', + 'required' => 'required', + 'field_map' => 'email', + 'field_width' => '75', + ), + ), + 'submit_label' => esc_html__( 'Join Newsletter', 'textdomain' ), + 'success_message' => esc_html__( 'Welcome to our newsletter!', 'textdomain' ), + 'error_message' => esc_html__( 'Action failed!', 'textdomain' ), + ); + } + + /** + * Newsletter_Admin constructor. + */ + public function __construct() { + parent::__construct( + array( + 'name' => esc_html__( 'Newsletter', 'textdomain' ), + 'description' => esc_html__( 'A simple newsletter form.', 'textdomain' ), + 'category' => esc_html__( 'Orbit Fox Modules', 'textdomain' ), + 'dir' => dirname( __FILE__ ), + 'url' => plugin_dir_url( __FILE__ ), + ) + ); + } + + /** + * Add map field for Newsletter field + * @param array $fields Repeater fields. + * @return array + */ + public function add_widget_repeater_fields( $fields ) { + + $fields['field_map'] = array( + 'label' => __( 'Map field to', 'textdomain' ), + 'type' => 'text', + ); + return $fields; + } + + /** + * Add specific controls for this type of widget. + * + * @param array $fields Fields config. + * @return array + */ + public function add_widget_specific_controls( $fields ) { + $providers = array( + 'mailchimp' => esc_html__( 'MailChimp', 'textdomain' ), + 'sendinblue' => esc_html__( 'Sendinblue ', 'textdomain' ), + ); + if ( version_compare( '7.1', phpversion() ) !== 1 ) { + $providers['mailerlite'] = esc_html__( 'MailerLite', 'textdomain' ); + } + $fields['fields'] = array( + 'provider' => array( + 'type' => 'select', + 'label' => esc_html__( 'Subscribe to', 'textdomain' ), + 'options' => $providers, + ), + 'access_key' => array( + 'type' => 'text', + 'label' => esc_html__( 'Access Key', 'textdomain' ), + ), + 'list_id' => array( + 'type' => 'text', + 'label' => esc_html__( 'List ID', 'textdomain' ), + ), + 'success_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Success message', 'textdomain' ), + 'default' => $this->get_default( 'success_message' ), + ), + 'error_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'textdomain' ), + 'default' => $this->get_default( 'error_message' ), + ), + ) + $fields['fields']; + + return $fields; + } + + /** + * Get specific field types. + * + * @return array + */ + function get_specific_field_types() { + return $this->field_types; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-registration.php b/obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-registration.php new file mode 100644 index 00000000..15bb4cc2 --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/beaver/class-themeisle-content-forms-beaver-registration.php @@ -0,0 +1,128 @@ + array( + array( + 'key' => 'username', + 'label' => esc_html__( 'User Name', 'textdomain' ), + 'placeholder' => esc_html__( 'User Name', 'textdomain' ), + 'type' => 'text', + 'required' => 'required', + 'field_map' => 'user_login', + 'field_width' => '100', + ), + array( + 'key' => 'email', + 'label' => esc_html__( 'Email', 'textdomain' ), + 'placeholder' => esc_html__( 'Email', 'textdomain' ), + 'type' => 'email', + 'required' => 'required', + 'field_map' => 'user_email', + 'field_width' => '100', + ), + array( + 'key' => 'password', + 'label' => esc_html__( 'Password', 'textdomain' ), + 'placeholder' => esc_html__( 'Password', 'textdomain' ), + 'type' => 'password', + 'required' => 'required', + 'field_map' => 'user_pass', + 'field_width' => '100', + ), + ), + 'submit_label' => esc_html__( 'Register', 'textdomain' ), + ); + } + + /** + * Registration_Admin constructor. + */ + public function __construct() { + parent::__construct( + array( + 'name' => esc_html__( 'Registration', 'textdomain' ), + 'description' => esc_html__( 'A sign up form.', 'textdomain' ), + 'category' => esc_html__( 'Orbit Fox Modules', 'textdomain' ), + 'dir' => dirname( __FILE__ ), + 'url' => plugin_dir_url( __FILE__ ), + ) + ); + } + + /** + * Add widget repeater fields specific for contact widget. + * + * @param array $fields Widget fields. + * + * @return array + */ + function add_widget_repeater_fields( $fields ) { + $field_types = array( + 'first_name' => __( 'First Name', 'textdomain' ), + 'last_name' => __( 'Last Name', 'textdomain' ), + 'user_pass' => __( 'Password', 'textdomain' ), + 'user_login' => __( 'Username', 'textdomain' ), + 'user_email' => __( 'Email', 'textdomain' ), + 'display_name' => __( 'Display Name', 'textdomain' ), + ); + + $fields['field_map'] = array( + 'label' => __( 'Map field to', 'textdomain' ), + 'type' => 'select', + 'options' => $field_types, + ); + return $fields; + } + + /** + * Add specific controls for this type of widget. + * + * @param array $fields Fields config. + * + * @return array + */ + function add_widget_specific_controls( $fields ) { + return $fields; + } + + /** + * Get specific field types. + * + * @return array + */ + function get_specific_field_types() { + return $this->field_types; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.css.php b/obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.css.php new file mode 100644 index 00000000..1b718e21 --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.css.php @@ -0,0 +1,218 @@ +get_type(); + +$fieldset_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset'; +echo $fieldset_selector . '{'; + echo $module->check_numeric_property( $settings, 'column_gap' ) ? 'padding: 0 ' . $settings->column_gap . 'px 0 ' . $settings->column_gap . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'row_gap' ) ? 'margin-bottom:' . $settings->row_gap . 'px;' : ''; +echo '}'; + +$fieldset_label_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset label'; +echo $fieldset_label_selector . '{'; + echo $module->check_color_property( $settings, 'label_color' ) ? 'color: #' . $settings->label_color : ''; +echo '}'; + +$required_mark_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset label .required-mark'; +echo $required_mark_selector . '{'; + echo $module->check_color_property( $settings, 'mark_required_color' ) ? 'color: #' . $settings->mark_required_color . ';' : ''; +echo '}'; + +if ( property_exists( $settings, 'label_typography' ) ) { + FLBuilderCSS::typography_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'label_typography', + 'selector' => $fieldset_label_selector, + ) + ); +} + +$input_field_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset input'; +$textarea_field_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset textarea'; +$select_field_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset select'; + +if ( property_exists( $settings, 'field_typography' ) ) { + FLBuilderCSS::typography_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'field_typography', + 'selector' => $input_field_selector . ',' . $textarea_field_selector . ',' . $select_field_selector, + ) + ); +} + +echo $input_field_selector . ',' . $input_field_selector . '::placeholder,' . $textarea_field_selector . ',' . $textarea_field_selector . '::placeholder,' . $select_field_selector . ',' . $select_field_selector . '::placeholder{'; + echo $module->check_color_property( $settings, 'field_text_color' ) ? 'color: #' . $settings->field_text_color . ';' : ''; +echo '}'; + +echo $input_field_selector . ',' . $textarea_field_selector . ',' . $select_field_selector . '{'; + echo $module->check_color_property( $settings, 'field_background_color' ) ? 'background-color: #' . $settings->field_background_color . ';' : ''; +echo '}'; + +if ( property_exists( $settings, 'field_border' ) ) { + FLBuilderCSS::border_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'field_border', + 'selector' => $input_field_selector . ',' . $textarea_field_selector . ',' . $select_field_selector, + ) + ); +} + +$fieldset_button_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset.submit-field'; +$button_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset button[name="submit"]'; +$button_hover_selector = '.fl-node-' . $id . ' .content-form-' . $module_type . ' fieldset button[name="submit"]:hover'; + +echo $button_selector . '{'; + echo $module->check_numeric_property( $settings, 'button_width' ) ? 'width: ' . $settings->button_width . $settings->button_width_unit . ';' : ''; + echo $module->check_numeric_property( $settings, 'button_height' ) ? 'height: ' . $settings->button_height . $settings->button_height_unit . ';' : ''; +echo '}'; + +echo $fieldset_button_selector . '{'; + echo $module->check_not_empty_property( $settings, 'submit_position' ) ? 'text-align: ' . $settings->submit_position . ';' : ''; +echo '}'; + +echo $button_selector . '{'; + echo $module->check_color_property( $settings, 'button_background_color' ) ? 'background-color: #' . $settings->button_background_color . ';' : ''; + echo $module->check_color_property( $settings, 'button_text_color' ) ? 'color: #' . $settings->button_text_color . ';' : ''; +echo '}'; + +echo $button_hover_selector . '{'; + echo $module->check_color_property( $settings, 'button_background_color_hover' ) ? 'background-color: #' . $settings->button_background_color_hover . ';' : ''; + echo $module->check_color_property( $settings, 'button_text_color_hover' ) ? 'color: #' . $settings->button_text_color_hover . ';' : ''; +echo '}'; + +if ( property_exists( $settings, 'button_typography' ) ) { + FLBuilderCSS::typography_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'button_typography', + 'selector' => $button_selector, + ) + ); +} + +if ( property_exists( $settings, 'button_typography_hover' ) ) { + FLBuilderCSS::typography_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'button_typography_hover', + 'selector' => $button_hover_selector, + ) + ); +} + +if ( property_exists( $settings, 'button_border' ) ) { + FLBuilderCSS::border_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'button_border', + 'selector' => $button_selector, + ) + ); +} + +if ( property_exists( $settings, 'button_border_hover' ) ) { + FLBuilderCSS::border_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'button_border_hover', + 'selector' => $button_hover_selector, + ) + ); +} + +$notification_selector = '.fl-node-' . $id . ' .ti-cf-module .content-form-notice'; +$notification_success_selector = '.fl-node-' . $id . ' .ti-cf-module .content-form-success'; +$notification_error_selector = '.fl-node-' . $id . ' .ti-cf-module .content-form-error'; +echo $notification_selector . '{'; + echo $module->check_numeric_property( $settings, 'notification_margin_top' ) ? 'margin-top: ' . $settings->notification_margin_top . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_margin_bottom' ) ? 'margin-bottom: ' . $settings->notification_margin_bottom . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_margin_left' ) ? 'margin-left: ' . $settings->notification_margin_left . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_margin_right' ) ? 'margin-right: ' . $settings->notification_margin_right . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_text_padding_top' ) ? 'padding-top: ' . $settings->notification_text_padding_top . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_text_padding_bottom' ) ? 'padding-bottom: ' . $settings->notification_text_padding_bottom . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_text_padding_left' ) ? 'padding-left: ' . $settings->notification_text_padding_left . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_text_padding_right' ) ? 'padding-right: ' . $settings->notification_text_padding_right . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'notification_width' ) ? 'width: ' . $settings->notification_width . '%;' : ''; +if ( property_exists( $settings, 'notification_box_shadow' ) ) { + echo 'box-shadow:' . FLBuilderColor::shadow( $settings->notification_box_shadow ) . ';'; +} +echo '}'; + +echo $notification_success_selector . '{'; + echo $module->check_color_property( $settings, 'notification_success_background_color' ) ? 'background-color: #' . $settings->notification_success_background_color . ';' : ''; + echo $module->check_color_property( $settings, 'notification_success_text_color' ) ? 'color: #' . $settings->notification_success_text_color . ';' : ''; +echo '}'; + +echo $notification_error_selector . '{'; + echo $module->check_color_property( $settings, 'notification_error_background_color' ) ? 'background-color: #' . $settings->notification_error_background_color . ';' : ''; + echo $module->check_color_property( $settings, 'notification_error_text_color' ) ? 'color: #' . $settings->notification_error_text_color . ';' : ''; +echo '}'; + +if ( property_exists( $settings, 'notification_error_border' ) ) { + FLBuilderCSS::border_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'notification_error_border', + 'selector' => $notification_error_selector, + ) + ); +} + +if ( property_exists( $settings, 'notification_success_border' ) ) { + FLBuilderCSS::border_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'notification_success_border', + 'selector' => $notification_success_selector, + ) + ); +} + +if ( property_exists( $settings, 'notification_alignment' ) ) { + $style = 'margin-left:0; margin-right:auto;'; + if ( $settings->notification_alignment === 'center' ) { + $style = 'margin-left:auto; margin-right:auto;'; + } + if ( $settings->notification_alignment === 'right' ) { + $style = 'margin-left:auto; margin-right:0;'; + } + echo $notification_selector . '{'; + echo $style; + echo '}'; +} + + +if ( property_exists( $settings, 'notification_typography' ) ) { + FLBuilderCSS::typography_field_rule( + array( + 'settings' => $settings, + 'setting_name' => 'notification_typography', + 'selector' => $notification_selector, + ) + ); +} + +echo '@media (max-width: 1024px) {'; +echo $fieldset_selector . '{'; + echo $module->check_numeric_property( $settings, 'column_gap_medium' ) ? 'padding: 0 ' . $settings->column_gap_medium . 'px 0 ' . $settings->column_gap_medium . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'row_gap_medium' ) ? 'margin-bottom:' . $settings->row_gap_medium . 'px;' : ''; +echo '}'; + +echo $button_selector . '{'; + echo $module->check_numeric_property( $settings, 'button_width_medium' ) ? 'width: ' . $settings->button_width_medium . $settings->button_width_medium_unit . ';' : ''; + echo $module->check_numeric_property( $settings, 'button_height_medium' ) ? 'height: ' . $settings->button_height_medium . $settings->button_height_medium_unit . ';' : ''; +echo '}'; +echo '}'; + +echo '@media (max-width: 768px) {'; +echo $fieldset_selector . '{'; + echo $module->check_numeric_property( $settings, 'column_gap_responsive' ) ? 'padding: 0 ' . $settings->column_gap_responsive . 'px 0 ' . $settings->column_gap_responsive . 'px;' : ''; + echo $module->check_numeric_property( $settings, 'row_gap_responsive' ) ? 'margin-bottom:' . $settings->row_gap_responsive . 'px;' : ''; +echo '}'; +echo $button_selector . '{'; + echo $module->check_numeric_property( $settings, 'button_width_responsive' ) ? 'width: ' . $settings->button_width_responsive . $settings->button_width_responsive_unit . ';' : ''; + echo $module->check_numeric_property( $settings, 'button_height_responsive' ) ? 'height: ' . $settings->button_height_responsive . $settings->button_height_responsive_unit . ';' : ''; +echo '}'; +echo '}'; diff --git a/obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.php b/obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.php new file mode 100644 index 00000000..e5b9a03d --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/beaver/includes/frontend.php @@ -0,0 +1,21 @@ +render_form_header( $module->node ); +$has_error = $module->maybe_render_form_errors( $module->node ); +$fields = $settings->fields; +$label_visibility = property_exists( $settings, 'hide_label' ) ? $settings->hide_label : 'show'; +foreach ( $fields as $key => $field ) { + $field = (array) $field; + $field['_id'] = $key; + $module->render_form_field( $field, $label_visibility ); + $module->maybe_render_newsletter_address( $field, $module->node ); +} + +$btn_label = ! empty( $settings->submit_label ) ? $settings->submit_label : esc_html__( 'Submit', 'textdomain' ); +$submit_class = property_exists( $settings, 'submit_display' ) && $settings->submit_display === 'block' ? 'class="submit-field submit-form ' . esc_attr( $module->get_type() ) . '"' : 'class="submit-field"'; +echo '
'; +echo ''; +echo '
'; + +$module->render_form_footer(); diff --git a/obfx_modules/content-forms/includes/widgets-admin/elementor/contact_admin.php b/obfx_modules/content-forms/includes/widgets-admin/elementor/contact_admin.php new file mode 100644 index 00000000..18e7e702 --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/elementor/contact_admin.php @@ -0,0 +1,205 @@ + 'name', + 'type' => 'text', + 'label' => esc_html__( 'Name', 'textdomain' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Name', 'textdomain' ), + 'field_width' => '100', + ), + array( + 'key' => 'email', + 'type' => 'email', + 'label' => esc_html__( 'Email', 'textdomain' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Email', 'textdomain' ), + 'field_width' => '100', + ), + array( + 'key' => 'phone', + 'type' => 'number', + 'label' => esc_html__( 'Phone', 'textdomain' ), + 'requirement' => 'optional', + 'placeholder' => esc_html__( 'Phone', 'textdomain' ), + 'field_width' => '100', + ), + array( + 'key' => 'message', + 'type' => 'textarea', + 'label' => esc_html__( 'Message', 'textdomain' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Message', 'textdomain' ), + 'field_width' => '100', + ), + ); + } + + /** + * No other required fields for this widget. + * + * @return bool + */ + function add_specific_form_fields() { + return false; + } + + /** + * Add specific settings for Contact Widget. + */ + function add_specific_settings_controls() { + + $this->add_control( + 'success_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Success message', 'textdomain' ), + 'default' => esc_html__( 'Your message has been sent!', 'textdomain' ), + ) + ); + + $this->add_control( + 'error_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'textdomain' ), + 'default' => esc_html__( 'Oops! I cannot send this email!', 'textdomain' ), + ) + ); + + $this->add_control( + 'to_send_email', + array( + 'type' => 'text', + 'label' => esc_html__( 'Send to', 'textdomain' ), + 'default' => get_bloginfo( 'admin_email' ), + 'description' => esc_html__( 'Where should we send the email?', 'textdomain' ), + ) + ); + + $this->add_control( + 'submit_label', + array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'textdomain' ), + 'default' => esc_html__( 'Submit', 'textdomain' ), + ) + ); + + $this->add_responsive_control( + 'align_submit', + array( + 'label' => __( 'Alignment', 'textdomain' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'textdomain' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'textdomain' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'textdomain' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'selectors' => array( + '{{WRAPPER}} .content-form .submit-form' => 'text-align: {{VALUE}};', + ), + ) + ); + } + + /** + * Add specific widget settings. + */ + function add_widget_specific_settings() { + return false; + } + + /** + * Add repeater specific fields. + * + * @param Object $repeater Repeater instance. + * @return bool + */ + function add_repeater_specific_fields( $repeater ) { + $repeater->add_control( + 'hidden_value', + array( + 'label' => __( 'Value', 'textdomain' ), + 'description' => __( 'You can use the following magic tags to get additional information: {current_url}, {username}, {user_nice_name}, {user_type}, {user_email}', 'textdomain' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => '', + 'condition' => array( + 'type' => 'hidden', + ), + ) + ); + } + + /** + * Specific field types for Contact form. + * + * @return array + */ + function get_specific_field_types() { + $field_types = $this->field_types; + $field_types['checkbox'] = esc_html__( 'Checkbox', 'textdomain' ); + $field_types['hidden'] = esc_html__( 'Hidden', 'textdomain' ); + return $field_types; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_base.php b/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_base.php new file mode 100644 index 00000000..ac07375c --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_base.php @@ -0,0 +1,1343 @@ +field_types = array( + 'text' => __( 'Text', 'textdomain' ), + 'password' => __( 'Password', 'textdomain' ), + 'email' => __( 'Email', 'textdomain' ), + 'textarea' => __( 'Textarea', 'textdomain' ), + ); + + $this->register_form_fields(); + $this->register_settings_controls(); + $this->register_style_controls(); + $this->add_widget_specific_settings(); + } + + /** + * This function registers the Repeater Control that adds fields in the form. + */ + private function register_form_fields() { + + $this->start_controls_section( + $this->get_widget_type() . '_form_fields', + array( + 'label' => __( 'Fields', 'textdomain' ), + ) + ); + $repeater = new Repeater(); + + $repeater->add_control( + 'requirement', + array( + 'label' => __( 'Required', 'textdomain' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'required', + 'default' => '', + 'condition' => array( + 'type!' => 'hidden', + ), + ) + ); + + $field_types = $this->get_specific_field_types(); + $repeater->add_control( + 'type', + array( + 'label' => __( 'Type', 'textdomain' ), + 'type' => Controls_Manager::SELECT, + 'options' => $field_types, + 'default' => 'text', + ) + ); + + $repeater->add_control( + 'key', + array( + 'label' => __( 'Key', 'textdomain' ), + 'type' => Controls_Manager::HIDDEN, + ) + ); + + $repeater->add_responsive_control( + 'field_width', + array( + 'label' => __( 'Field Width', 'textdomain' ), + 'type' => Controls_Manager::SELECT, + 'options' => array( + '100' => '100%', + '75' => '75%', + '66' => '66%', + '50' => '50%', + '33' => '33%', + '25' => '25%', + ), + 'default' => '100', + 'condition' => array( + 'type!' => 'hidden', + ), + ) + ); + + $repeater->add_control( + 'label', + array( + 'label' => __( 'Label', 'textdomain' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + ) + ); + + $repeater->add_control( + 'placeholder', + array( + 'label' => __( 'Placeholder', 'textdomain' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'condition' => array( + 'type!' => array( 'hidden', 'checkbox' ), + ), + ) + ); + + $this->add_repeater_specific_fields( $repeater ); + + $default_fields = $this->get_default_config(); + $this->add_control( + 'form_fields', + array( + 'label' => __( 'Form Fields', 'textdomain' ), + 'type' => Controls_Manager::REPEATER, + 'show_label' => false, + 'separator' => 'before', + 'fields' => $repeater->get_controls(), + 'default' => $default_fields, + 'title_field' => '{{{ label }}}', + ) + ); + + $this->add_control( + 'hide_label', + array( + 'type' => Controls_Manager::SWITCHER, + 'label' => __( 'Hide Label', 'textdomain' ), + 'return_value' => 'hide', + 'default' => '', + 'separator' => 'before', + ) + ); + $this->end_controls_section(); + $this->add_specific_form_fields(); + } + + /** + * Register form setting controls. + */ + private function register_settings_controls() { + + $this->start_controls_section( + 'contact_form_settings', + array( + 'label' => __( 'Form Settings', 'textdomain' ), + ) + ); + + $this->add_specific_settings_controls(); + + $this->end_controls_section(); + } + + /** + * Add style controls. + * + * @access protected + * @return void + * @since 1.0,0 + */ + protected function register_style_controls() { + $this->start_controls_section( + 'section_form_style', + array( + 'label' => __( 'Form', 'textdomain' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_control( + 'column_gap', + array( + 'label' => __( 'Columns Gap', 'textdomain' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 10, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 60, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .elementor-column' => 'padding-right: calc( {{SIZE}}{{UNIT}}/2 ); padding-left: calc( {{SIZE}}{{UNIT}}/2 );', + '{{WRAPPER}} .content-form .submit-form' => 'padding-right: calc( {{SIZE}}{{UNIT}}/2 ); padding-left: calc( {{SIZE}}{{UNIT}}/2 );', + ), + ) + ); + + $this->add_control( + 'row_gap', + array( + 'label' => __( 'Rows Gap', 'textdomain' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 10, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 60, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .elementor-column' => 'margin-bottom: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .content-form .submit-form' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'heading_label', + array( + 'label' => __( 'Label', 'textdomain' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'label_spacing', + array( + 'label' => __( 'Spacing', 'textdomain' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 0, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 60, + ), + ), + 'selectors' => array( + 'body.rtl {{WRAPPER}} fieldset > label' => 'padding-left: {{SIZE}}{{UNIT}};', + // for the label position = inline option + 'body:not(.rtl) {{WRAPPER}} fieldset > label' => 'padding-right: {{SIZE}}{{UNIT}};', + // for the label position = inline option + 'body {{WRAPPER}} fieldset > label' => 'padding-bottom: {{SIZE}}{{UNIT}};', + // for the label position = above option + ), + ) + ); + + $this->add_control( + 'label_color', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > label, {{WRAPPER}} .elementor-field-subgroup label' => 'color: {{VALUE}};', + ), + 'global' => array( + 'default' => Global_Colors::COLOR_TEXT, + ), + ) + ); + + $this->add_control( + 'mark_required_color', + array( + 'label' => __( 'Mark Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => array( + '{{WRAPPER}} .required-mark' => 'color: {{COLOR}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'label_typography', + 'selector' => '{{WRAPPER}} fieldset > label', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ), + ) + ); + $this->end_controls_section(); + + $this->start_controls_section( + 'section_field_style', + array( + 'label' => __( 'Field', 'textdomain' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'field_typography', + 'selector' => '{{WRAPPER}} fieldset > input, {{WRAPPER}} fieldset select, {{WRAPPER}} fieldset > textarea, {{WRAPPER}} fieldset > button', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ), + ) + ); + + $this->add_responsive_control( + 'align_field_text', + array( + 'label' => __( 'Text alignment', 'textdomain' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'textdomain' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'textdomain' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'textdomain' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'text-align: {{VALUE}}', + '{{WRAPPER}} fieldset select' => 'text-align: {{VALUE}}', + '{{WRAPPER}} fieldset > textarea' => 'text-align: {{VALUE}}', + ), + ) + ); + + $this->add_responsive_control( + 'field-text-padding', + array( + 'label' => __( 'Text Padding', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset select' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset > textarea' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->start_controls_tabs( 'tabs_field_style' ); + + $this->start_controls_tab( + 'tab_field_normal', + array( + 'label' => __( 'Normal', 'textdomain' ), + ) + ); + + $this->add_control( + 'field_text_color', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset > input::placeholder' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset select' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset select::placeholder' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea::placeholder' => 'color: {{VALUE}};', + ), + 'global' => array( + 'default' => Global_Colors::COLOR_TEXT, + ), + ) + ); + + $this->add_control( + 'field_background_color', + array( + 'label' => __( 'Background Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'background-color: {{VALUE}};', + '{{WRAPPER}} fieldset select' => 'background-color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea' => 'background-color: {{VALUE}};', + ), + 'separator' => 'before', + ) + ); + + $this->add_control( + 'field_border_color', + array( + 'label' => __( 'Border Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'border-color: {{VALUE}};', + '{{WRAPPER}} fieldset select' => 'border-color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea' => 'border-color: {{VALUE}};', + ), + 'separator' => 'before', + ) + ); + + $this->add_control( + 'field_border_style', + array( + 'label' => _x( 'Border Type', 'Border Control', 'textdomain' ), + 'type' => Controls_Manager::SELECT, + 'options' => array( + '' => __( 'None', 'textdomain' ), + 'solid' => _x( 'Solid', 'Border Control', 'textdomain' ), + 'double' => _x( 'Double', 'Border Control', 'textdomain' ), + 'dotted' => _x( 'Dotted', 'Border Control', 'textdomain' ), + 'dashed' => _x( 'Dashed', 'Border Control', 'textdomain' ), + 'groove' => _x( 'Groove', 'Border Control', 'textdomain' ), + ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'border-style: {{VALUE}};', + '{{WRAPPER}} fieldset select' => 'border-style: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea' => 'border-style: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'field_border_width', + array( + 'label' => __( 'Border Width', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'placeholder' => '', + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset select' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset > textarea' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'field_border_radius', + array( + 'label' => __( 'Border Radius', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset select' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset > textarea' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_field_focus', + array( + 'label' => __( 'Focus', 'textdomain' ), + ) + ); + + $this->add_control( + 'field_focus_text_color', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > input:focus' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset > input::placeholder:focus' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset select:focus' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset select::placeholder:focus' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea:focus' => 'color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea::placeholder:focus' => 'color: {{VALUE}};', + ), + 'global' => array( + 'default' => Global_Colors::COLOR_TEXT, + ), + ) + ); + + $this->add_control( + 'field_focus_background_color', + array( + 'label' => __( 'Background Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => array( + '{{WRAPPER}} fieldset > input:focus' => 'background-color: {{VALUE}};', + '{{WRAPPER}} fieldset select:focus' => 'background-color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea:focus' => 'background-color: {{VALUE}};', + ), + 'separator' => 'before', + ) + ); + + $this->add_control( + 'field_focus_border_color', + array( + 'label' => __( 'Border Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > input:focus' => 'border-color: {{VALUE}};', + '{{WRAPPER}} fieldset select:focus' => 'border-color: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea:focus' => 'border-color: {{VALUE}};', + ), + 'separator' => 'before', + ) + ); + + $this->add_control( + 'field_focus_border_style', + array( + 'label' => _x( 'Border Type', 'Border Control', 'textdomain' ), + 'type' => Controls_Manager::SELECT, + 'options' => array( + '' => __( 'None', 'textdomain' ), + 'solid' => _x( 'Solid', 'Border Control', 'textdomain' ), + 'double' => _x( 'Double', 'Border Control', 'textdomain' ), + 'dotted' => _x( 'Dotted', 'Border Control', 'textdomain' ), + 'dashed' => _x( 'Dashed', 'Border Control', 'textdomain' ), + 'groove' => _x( 'Groove', 'Border Control', 'textdomain' ), + ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input:focus' => 'border-style: {{VALUE}};', + '{{WRAPPER}} fieldset select:focus' => 'border-style: {{VALUE}};', + '{{WRAPPER}} fieldset > textarea:focus' => 'border-style: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'field_focus_border_width', + array( + 'label' => __( 'Border Width', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'placeholder' => '', + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input:focus' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset select:focus' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset > textarea:focus' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'field_focus_border_radius', + array( + 'label' => __( 'Border Radius', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > input:focus' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset select:focus' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} fieldset > textarea:focus' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_button_style', + array( + 'label' => __( 'Button', 'textdomain' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + array( + 'label' => __( 'Normal', 'textdomain' ), + ) + ); + + $this->add_control( + 'button_background_color', + array( + 'label' => __( 'Background Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'global' => array( + 'default' => Global_Colors::COLOR_ACCENT, + ), + 'selectors' => array( + '{{WRAPPER}} fieldset > button' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'button_text_color', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => array( + '{{WRAPPER}} fieldset > button' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'button_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ), + 'selector' => '{{WRAPPER}} fieldset > button', + ) + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + array( + 'name' => 'button_border', + 'placeholder' => '1px', + 'default' => '1px', + 'selector' => '{{WRAPPER}} fieldset > button', + 'separator' => 'before', + ) + ); + + $this->add_control( + 'button_border_radius', + array( + 'label' => __( 'Border Radius', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'button_text_padding', + array( + 'label' => __( 'Text Padding', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} fieldset > button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + array( + 'label' => __( 'Hover', 'textdomain' ), + ) + ); + + $this->add_control( + 'button_background_hover_color', + array( + 'label' => __( 'Background Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > button:hover' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'button_hover_color', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > button:hover' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'button_hover_border_color', + array( + 'label' => __( 'Border Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > button:hover' => 'border-color: {{VALUE}};', + ), + 'condition' => array( + 'button_border_border!' => '', + ), + ) + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'notification_style', + array( + 'label' => __( 'Notification', 'textdomain' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_responsive_control( + 'notification_margin', + array( + 'label' => __( 'Margin', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} .content-form-notice' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_responsive_control( + 'notification_text_padding', + array( + 'label' => __( 'Padding', 'textdomain' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} .content-form-notice' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_responsive_control( + 'notification_width', + array( + 'label' => __( 'Width', 'textdomain' ), + 'type' => Controls_Manager::SLIDER, + 'unit' => '%', + 'range' => array( + '%' => array( + 'min' => 0, + 'max' => 100, + ), + ), + 'default' => array( + 'unit' => '%', + ), + 'selectors' => array( + '{{WRAPPER}} .content-form-notice' => 'width: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'notification_typography', + 'selector' => '{{WRAPPER}} .content-form-notice', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ), + ) + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'notification_box_shadow', + 'label' => __( 'Box Shadow', 'textdomain' ), + 'selector' => '{{WRAPPER}} .content-form-notice', + ) + ); + + $this->add_responsive_control( + 'notification_alignment', + array( + 'label' => __( 'Alignment', 'textdomain' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'textdomain' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'textdomain' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'textdomain' ), + 'icon' => 'fa fa-align-right', + ), + ), + ) + ); + + $this->start_controls_tabs( 'tabs_notification_style' ); + + $this->start_controls_tab( + 'tab_notification_success', + array( + 'label' => __( 'Success', 'textdomain' ), + ) + ); + + $this->add_control( + 'notification_background_color_success', + array( + 'label' => __( 'Background Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} .content-form-notice.content-form-success' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'notification_text_color_success', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} .content-form-notice.content-form-success' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + array( + 'name' => 'notification_border_success', + 'label' => __( 'Border', 'textdomain' ), + 'selector' => '{{WRAPPER}} .content-form-notice.content-form-success', + ) + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_notification_error', + array( + 'label' => __( 'Error', 'textdomain' ), + ) + ); + + $this->add_control( + 'notification_background_color_error', + array( + 'label' => __( 'Background Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} .content-form-notice.content-form-error' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'notification_text_color_error', + array( + 'label' => __( 'Text Color', 'textdomain' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} .content-form-notice.content-form-error' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + array( + 'name' => 'notification_border_error', + 'label' => __( 'Border', 'textdomain' ), + 'selector' => '{{WRAPPER}} .content-form-notice.content-form-error', + ) + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + /** + * Render the widget. + */ + protected function render() { + $form_id = $this->get_data( 'id' ); + $settings = $this->get_settings(); + $fields = $settings['form_fields']; + + $this->maybe_load_widget_style(); + + $this->render_form_header( $form_id ); + $has_errors = $this->maybe_render_form_errors(); + $disabled = $has_errors === true ? 'disabled="disabled"' : ''; + + foreach ( $fields as $index => $field ) { + $this->render_form_field( $field ); + } + + $btn_label = ! empty( $settings['submit_label'] ) ? $settings['submit_label'] : esc_html__( 'Submit', 'textdomain' ); + echo '
'; + echo ''; + echo '
'; + $this->render_form_footer(); + } + + /** + * Display form configuration errors. + * + * @return bool + */ + private function maybe_render_form_errors() { + $has_error = false; + if ( ! current_user_can( 'manage_options' ) ) { + return $has_error; + } + + if ( $this->get_widget_type() === 'newsletter' ) { + $settings = $this->get_settings(); + echo '
'; + + if ( array_key_exists( 'access_key', $settings ) && empty( $settings['access_key'] ) ) { + echo '

'; + printf( + esc_html__( 'The %s setting is required!', 'textdomain' ), + '' . esc_html__( 'Access Key', 'textdomain' ) . '' + ); + echo '

'; + $has_error = true; + } + + if ( array_key_exists( 'list_id', $settings ) && empty( $settings['list_id'] ) ) { + echo '

'; + printf( + esc_html__( 'The %s setting is required!', 'textdomain' ), + '' . esc_html__( 'List id', 'textdomain' ) . '' + ); + echo '

'; + $has_error = true; + } + + $form_fields = $settings['form_fields']; + $mapping = array(); + foreach ( $form_fields as $field ) { + $field_map = $field['field_map']; + if ( in_array( $field_map, $mapping, true ) ) { + echo '

'; + printf( + esc_html__( 'The %s field is mapped to multiple form fields. Please check your field settings.', 'textdomain' ), + '' . $field_map . '' + ); + echo '

'; + $has_error = true; + } + array_push( $mapping, $field_map ); + } + + echo '
'; + + return $has_error; + } + + if ( $this->get_widget_type() === 'contact' ) { + $settings = $this->get_settings(); + + if ( array_key_exists( 'to_send_email', $settings ) && empty( $settings['to_send_email'] ) ) { + echo '

'; + printf( + esc_html__( 'The %s setting is required!', 'textdomain' ), + '' . esc_html__( 'Send to Email Address', 'textdomain' ) . '' + ); + echo '

'; + $has_error = true; + } + } + + return $has_error; + } + + /** + * Either enqueue the widget style registered by the library + * or load an inline version for the preview only + * + * @return void + * @since 1.0.0 + * @access protected + */ + protected function maybe_load_widget_style() { + if ( Plugin::$instance->editor->is_edit_mode() === true && apply_filters( 'themeisle_content_forms_register_default_style', true ) ) { + echo ''; + } else { + // if `themeisle_content_forms_register_default_style` is false, the style won't be registered anyway + $style = $this->get_notice_style(); + wp_localize_script( 'content-forms', 'formStyle', array( 'formStyle' => $style ) ); + wp_enqueue_script( 'content-forms' ); + } + } + + /** + * Sanitize alignment values before rendering. + * + * @param mixed $value The value to sanitize. + * + * @return string + */ + private function sanitize_alignment( $value ) { + return in_array( $value, array( 'left', 'center', 'right' ), true ) ? $value : 'left'; + } + + /** + * Get style for form notification. + * + * @return string + */ + public function get_notice_style() { + $settings = $this->get_settings_for_display(); + $notification_alignment = esc_attr( $this->sanitize_alignment( $settings['notification_alignment'] ) ); + + $style = 'style="margin-left:0; text-align:' . $notification_alignment . '"'; + if ( $settings['notification_alignment'] === 'right' ) { + $style = 'style="margin-right:0; margin-left:auto; text-align:' . $notification_alignment . '"'; + } + if ( $settings['notification_alignment'] === 'center' ) { + $style = 'style="margin-left: auto; margin-right: auto; text-align:' . $notification_alignment . '"'; + } + + return $style; + } + + /** + * Render the preview of form notifications. + * + * @return bool + */ + private function maybe_render_form_notification() { + if ( Plugin::$instance->editor->is_edit_mode() !== true ) { + return false; + } + + $style = $this->get_notice_style(); + + echo '
'; + echo '

' . __( 'This is a preview of how the success notification will look', 'textdomain' ) . '

'; + echo '
'; + + echo '
'; + echo '

' . __( 'This is a preview of how the error notification will look', 'textdomain' ) . '

'; + echo '
'; + + return true; + } + + /** + * Display method for the form's header + * It is also takes care about the form attributes and the regular hidden fields + * + * @param string $id Form id. + */ + private function render_form_header( $id ) { + // create an url for the form's action + $url = admin_url( 'admin-post.php' ); + echo '
'; + $this->maybe_render_form_notification(); + wp_nonce_field( 'content-form-' . esc_attr( $id ), '_wpnonce_' . esc_attr( $this->get_widget_type() ) ); + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + /** + * Print the output of an individual field + * + * @param array $field Field settings. + * @param bool $is_preview Is preview flag. + */ + private function render_form_field( $field, $is_preview = false ) { + + $field_id = $field['_id']; + $key = Form_Manager::get_field_key_name( $field ); + $key = $key === 'ADDRESS' ? $key = 'ADDRESS[addr1]' : $key; + $form_id = $this->get_data( 'id' ); + $field_name = 'data[' . $form_id . '][' . $key . ']'; + $disabled = $is_preview ? 'disabled="disabled"' : ''; + $required = $field['requirement'] === 'required' ? 'required="required"' : ''; + $placeholder = ! empty( $field['placeholder'] ) ? $field['placeholder'] : ''; + + $this->add_render_attribute( 'fieldset' . $field['_id'], 'class', 'content-form-field-' . $field['type'] ); + $this->add_render_attribute( 'fieldset' . $field['_id'], 'class', 'elementor-column elementor-col-' . $field['field_width'] ); + $this->add_render_attribute( + array( + 'icon-align' => array( + 'class' => array( + empty( $instance['button_icon_align'] ) ? '' : + 'elementor-align-icon-' . $instance['button_icon_align'], + 'elementor-button-icon', + ), + ), + ) + ); + + echo '
get_render_attribute_string( 'fieldset' . $field_id ) . '>'; + $this->render_field_label( $field ); + + switch ( $field['type'] ) { + case 'textarea': + echo ''; + break; + case 'password': + echo ''; + break; + case 'hidden': + $hidden_field_value = $field['hidden_value']; + echo ''; + break; + case 'checkbox': + echo ''; + break; + default: + echo ''; + break; + } + echo '
'; + + $this->maybe_render_newsletter_address( $field, $is_preview ); + } + + /** + * When using MailChimp, additional fields are required for the address field/ + * + * @param array $field Field data. + * @return bool + */ + private function maybe_render_newsletter_address( $field, $is_preview ) { + $settings = $this->get_settings_for_display(); + if ( ! array_key_exists( 'provider', $settings ) || $settings['provider'] !== 'mailchimp' ) { + return false; + } + + if ( ! array_key_exists( 'field_map', $field ) || $field['field_map'] !== 'address' ) { + return false; + } + + $form_id = $this->get_data( 'id' ); + $display_label = $settings['hide_label']; + $disabled = $is_preview ? 'disabled="disabled"' : ''; + $required = $field['requirement'] === 'required' ? 'required="required"' : ''; + + $address_fields = array( 'addr2', 'city', 'state', 'zip', 'country' ); + foreach ( $address_fields as $address_item ) { + if ( ! isset( $field[ $address_item . '_width' ] ) ) { + continue; + } + $field_name = 'data[' . $form_id . '][ADDRESS[' . $address_item . ']]'; + $this->add_render_attribute( 'fieldset' . $field['_id'] . $address_item, 'class', 'elementor-column elementor-col-' . $field[ $address_item . '_width' ] ); + + echo '
'; + + if ( $display_label !== 'hide' && isset( $field[ $address_item . '_label' ] ) ) { + echo ''; + } + + if ( $address_item === 'country' ) { + echo ''; + } else { + $placeholder = isset( $field[ $address_item . '_placeholder' ] ) ? $field[ $address_item . '_placeholder' ] : ''; + echo ''; + } + + echo '
'; + } + return true; + } + + /** + * Maybe render field label + * + * @var array $field Field data. + * + * @return true + */ + private function render_field_label( $field ) { + + if ( $field['type'] === 'hidden' || $field['type'] === 'checkbox' ) { + return false; + } + $settings = $this->get_settings(); + $display_label = $settings['hide_label']; + $field_id = $field['_id']; + $key = Form_Manager::get_field_key_name( $field ); + $form_id = $this->get_data( 'id' ); + $field_name = 'data[' . $form_id . '][' . $key . ']'; + + echo ''; + + return true; + } + + + /** + * Display method for the form's footer + */ + private function render_form_footer() { + echo '
'; + } + + /** + * Get widget type. + * @return string + */ + abstract function get_widget_type(); + + /** + * Add specific fields for repeater form fields. + * + * @param Object $repeater Repeater object + */ + abstract function add_repeater_specific_fields( $repeater ); + + /** + * Add widget specific settings. + * + * @return mixed + */ + abstract function add_widget_specific_settings(); + + /** + * Get form fields default values. + * + * @return array + */ + abstract function get_default_config(); + + /** + * Add Widget specific form fields. + */ + abstract function add_specific_form_fields(); + + /** + * Add widget specific settings controls. + */ + abstract function add_specific_settings_controls(); + + /** + * Get allowed field types. + * + * @return array + */ + abstract function get_specific_field_types(); +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_manager.php b/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_manager.php new file mode 100644 index 00000000..38e0aadf --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_manager.php @@ -0,0 +1,143 @@ +sanitize_alignment( $settings['notification_alignment'] ); + } + if ( isset( $settings['form_fields'] ) ) { + $form_fields = $settings['form_fields']; + foreach ( $form_fields as &$field ) { + $field = $this->sanitize_field_attributes( $field ); + } + $settings['form_fields'] = $form_fields; + } + //$settings[$control_name] = $desired_value; + $element['settings'] = $settings; + } + } + + if ( isset( $element['elements'] ) && is_array( $element['elements'] ) ) { + // If the element has nested elements (e.g., section or column), recursively call the function + $this->search_and_modify_widget_settings( $element['elements'] ); + } + } + } + + /** + * Filter the document data and sanitize the form parameters. + * + * @param array $data The document data. + * @param @param \Elementor\Core\Base\Document $document The document instance. + * + * @return mixed + */ + public function before_settings_save( $data, $document ) { + if ( ! isset( $data['elements'] ) ) { + return; + } + $this->search_and_modify_widget_settings( $data['elements'] ); + return $data; + } + + /** + * Register the category for widgets. + * + * @param \Elementor\Elements_Manager $elements_manager Elements manager. + */ + public function add_elementor_widget_categories( $elements_manager ) { + $elements_manager->add_category( + 'obfx-elementor-widgets', + array( + 'title' => __( 'Orbit Fox Addons', 'textdomain' ), + 'icon' => 'fa fa-plug', + ) + ); + } + + /** + * Register Elementor Widgets that are added in Orbit Fox. + */ + public function register_elementor_widget() { + foreach ( self::$forms as $form ) { + require_once $form . '_admin.php'; + $widget = '\ThemeIsle\ContentForms\Includes\Widgets_Admin\Elementor\\' . ucwords( $form ) . '_Admin'; + Plugin::instance()->widgets_manager->register_widget_type( new $widget() ); + } + } +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/elementor/newsletter_admin.php b/obfx_modules/content-forms/includes/widgets-admin/elementor/newsletter_admin.php new file mode 100644 index 00000000..abc58fb9 --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/elementor/newsletter_admin.php @@ -0,0 +1,373 @@ + 'email', + 'type' => 'email', + 'label' => esc_html__( 'Email', 'textdomain' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Email', 'textdomain' ), + 'field_width' => '100', + 'field_map' => 'email', + ), + ); + } + + /** + * Get Widget Title. + * + * @return string + */ + public function get_title() { + return esc_html__( 'Newsletter Form', 'textdomain' ); + } + + /** + * Add specific form fields for Newsletter widget. + */ + function add_specific_form_fields() { + return false; + } + + /** + * Add specific settings for Newsletter widget. + */ + function add_specific_settings_controls() { + $providers = array( + 'mailchimp' => esc_html__( 'MailChimp', 'textdomain' ), + 'sendinblue' => esc_html__( 'Sendinblue ', 'textdomain' ), + ); + if ( version_compare( '7.1', phpversion() ) !== 1 ) { + $providers['mailerlite'] = esc_html__( 'MailerLite', 'textdomain' ); + } + $this->add_control( + 'provider', + array( + 'type' => 'select', + 'label' => esc_html__( 'Subscribe to', 'textdomain' ), + 'options' => $providers, + 'default' => 'mailchimp', + 'separator' => 'after', + ) + ); + + $this->add_control( + 'success_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Success message', 'textdomain' ), + 'default' => esc_html__( 'Welcome to our newsletter!', 'textdomain' ), + ) + ); + + $this->add_control( + 'error_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'textdomain' ), + 'default' => esc_html__( 'Action failed!', 'textdomain' ), + 'separator' => 'after', + ) + ); + + $this->add_control( + 'submit_label', + array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'textdomain' ), + 'default' => esc_html__( 'Join Newsletter', 'textdomain' ), + ) + ); + + $this->add_control( + 'button_icon_new', + array( + 'label' => __( 'Icon', 'textdomain' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'button_icon', + ) + ); + + $this->add_control( + 'button_icon_size', + array( + 'label' => __( 'Icon Size', 'textdomain' ), + 'type' => Controls_Manager::SLIDER, + 'range' => array( + 'px' => array( + 'max' => 100, + ), + ), + 'condition' => array( + 'button_icon!' => '', + ), + 'selectors' => array( + '{{WRAPPER}} .elementor-button-icon svg' => 'width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-button-icon i' => 'font-size: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'button_icon_indent', + array( + 'label' => __( 'Icon Spacing', 'textdomain' ), + 'type' => Controls_Manager::SLIDER, + 'range' => array( + 'px' => array( + 'max' => 100, + ), + ), + 'condition' => array( + 'button_icon!' => '', + ), + 'selectors' => array( + '{{WRAPPER}} .elementor-button-icon' => 'margin-left: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->add_responsive_control( + 'align_submit', + array( + 'label' => __( 'Alignment', 'textdomain' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'textdomain' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'textdomain' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'textdomain' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'selectors' => array( + '{{WRAPPER}} .content-form .submit-form' => 'text-align: {{VALUE}};', + ), + ) + ); + } + + /** + * Add widget specific settings. + * + * @return mixed|void + */ + function add_widget_specific_settings() { + + $this->start_controls_section( + 'provider_settings', + array( + 'label' => __( 'Provider Settings', 'textdomain' ), + ) + ); + + $this->add_control( + 'access_key', + array( + 'type' => 'text', + 'label' => esc_html__( 'Access Key', 'textdomain' ), + ) + ); + + $this->add_control( + 'list_id', + array( + 'type' => 'text', + 'label' => esc_html__( 'List ID', 'textdomain' ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Add repeater specific fields for newsletter widget. + * @param Object $repeater + */ + function add_repeater_specific_fields( $repeater ) { + $repeater->add_control( + 'field_map', + array( + 'label' => __( 'Map field to', 'textdomain' ), + 'type' => Controls_Manager::TEXT, + 'separator' => 'after', + 'description' => esc_html__( 'If you\'re using SendInBlue or MailerLite and you map the field to address, please ignore the additional settings.', 'textdomain' ), + ) + ); + + $config = array( + 'addr2' => array( + 'label' => array( + 'label' => __( 'Line 2 Label', 'textdomain' ), + 'default' => __( 'Address Line 2', 'textdomain' ), + ), + 'placeholder' => array( + 'label' => __( 'Line 2 Placeholder', 'textdomain' ), + 'default' => __( 'Address Line 2', 'textdomain' ), + ), + 'width' => array( + 'label' => __( 'Line 2 Width', 'textdomain' ), + 'default' => '100', + ), + ), + 'city' => array( + 'label' => array( + 'label' => __( 'City Label', 'textdomain' ), + 'default' => __( 'City', 'textdomain' ), + ), + 'placeholder' => array( + 'label' => __( 'City Placeholder', 'textdomain' ), + 'default' => __( 'City', 'textdomain' ), + ), + 'width' => array( + 'label' => __( 'City Width', 'textdomain' ), + 'default' => '100', + ), + ), + 'state' => array( + 'label' => array( + 'label' => __( 'State Label', 'textdomain' ), + 'default' => __( 'State/Province/Region', 'textdomain' ), + ), + 'placeholder' => array( + 'label' => __( 'State Placeholder', 'textdomain' ), + 'default' => __( 'State/Province/Region', 'textdomain' ), + ), + 'width' => array( + 'label' => __( 'State Width', 'textdomain' ), + 'default' => '100', + ), + ), + 'zip' => array( + 'label' => array( + 'label' => __( 'Zip Code Label', 'textdomain' ), + 'default' => __( 'Postal / Zip Code', 'textdomain' ), + ), + 'placeholder' => array( + 'label' => __( 'Zip Code Placeholder', 'textdomain' ), + 'default' => __( 'Postal / Zip Code', 'textdomain' ), + ), + 'width' => array( + 'label' => __( 'Zip Code Width', 'textdomain' ), + 'default' => '100', + ), + ), + 'country' => array( + 'label' => array( + 'label' => __( 'Country Label', 'textdomain' ), + 'default' => __( 'Country', 'textdomain' ), + ), + 'placeholder' => array( + 'label' => __( ' Country Placeholder', 'textdomain' ), + 'default' => __( 'Country', 'textdomain' ), + ), + 'width' => array( + 'label' => __( 'Country Width', 'textdomain' ), + 'default' => '100', + ), + ), + ); + foreach ( $config as $main_field => $field_value ) { + foreach ( $field_value as $specific_field => $field_data ) { + $key = $main_field . '_' . $specific_field; + if ( $specific_field !== 'width' ) { + $repeater->add_control( + $key, + array( + 'label' => $field_data['label'], + 'type' => Controls_Manager::TEXT, + 'default' => $field_data['default'], + 'condition' => array( + 'field_map' => 'address', + ), + ) + ); + } else { + $repeater->add_responsive_control( + $key, + array( + 'label' => $field_data['label'], + 'type' => Controls_Manager::SELECT, + 'options' => array( + '100' => '100%', + '75' => '75%', + '66' => '66%', + '50' => '50%', + '33' => '33%', + '25' => '25%', + ), + 'default' => $field_data['default'], + 'condition' => array( + 'field_map' => 'address', + ), + ) + ); + } + } + } + } + + /** + * Specific field types for Newsletter form. + * + * @return array + */ + function get_specific_field_types() { + return $this->field_types; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-admin/elementor/registration_admin.php b/obfx_modules/content-forms/includes/widgets-admin/elementor/registration_admin.php new file mode 100644 index 00000000..687c94fd --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/elementor/registration_admin.php @@ -0,0 +1,180 @@ + 'username', + 'type' => 'text', + 'label' => esc_html__( 'User Name', 'textdomain' ), + 'require' => 'required', + 'placeholder' => esc_html__( 'User Name', 'textdomain' ), + 'field_width' => '100', + 'field_map' => 'user_login', + ), + array( + 'key' => 'email', + 'type' => 'email', + 'label' => esc_html__( 'Email', 'textdomain' ), + 'require' => 'required', + 'placeholder' => esc_html__( 'Email', 'textdomain' ), + 'field_width' => '100', + 'field_map' => 'user_email', + ), + array( + 'key' => 'password', + 'type' => 'password', + 'label' => esc_html__( 'Password', 'textdomain' ), + 'require' => 'required', + 'placeholder' => esc_html__( 'Password', 'textdomain' ), + 'field_width' => '100', + 'field_map' => 'user_pass', + ), + ); + } + + /** + * Add specific form fields for Registration Widget. + */ + function add_specific_form_fields() { + return false; + } + + /** + * Add specific settings for Newsletter widget. + */ + function add_specific_settings_controls() { + $this->add_control( + 'submit_label', + array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'textdomain' ), + 'default' => esc_html__( 'Register', 'textdomain' ), + ) + ); + + $this->add_responsive_control( + 'align_submit', + array( + 'label' => __( 'Alignment', 'textdomain' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'textdomain' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'textdomain' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'textdomain' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'selectors' => array( + '{{WRAPPER}} .content-form .submit-form' => 'text-align: {{VALUE}};', + ), + ) + ); + } + + /** + * Add specific widget settings. + */ + function add_widget_specific_settings() { + return false; + } + + /** + * Add repeater registration specific field. + * + * @param Object $repeater Repeater instance. + */ + function add_repeater_specific_fields( $repeater ) { + $field_types = array( + 'first_name' => __( 'First Name', 'textdomain' ), + 'last_name' => __( 'Last Name', 'textdomain' ), + 'user_pass' => __( 'Password', 'textdomain' ), + 'user_login' => __( 'Username', 'textdomain' ), + 'user_email' => __( 'Email', 'textdomain' ), + 'display_name' => __( 'Display Name', 'textdomain' ), + ); + $repeater->add_control( + 'field_map', + array( + 'label' => __( 'Map field to', 'textdomain' ), + 'type' => Controls_Manager::SELECT, + 'options' => $field_types, + 'default' => 'text', + ) + ); + } + + /** + * Specific field types for Registration form. + * + * @return array + */ + function get_specific_field_types() { + return $this->field_types; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-public/contact_public.php b/obfx_modules/content-forms/includes/widgets-public/contact_public.php new file mode 100644 index 00000000..0a277341 --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-public/contact_public.php @@ -0,0 +1,195 @@ +get_widget_settings( $widget_id, $post_id, $builder ); + $success_message = array_key_exists( 'success_message', $settings ) && ! empty( $settings['success_message'] ) ? $settings['success_message'] : esc_html__( 'Your message has been sent!', 'textdomain' ); + $error_message = array_key_exists( 'error_message', $settings ) && ! empty( $settings['error_message'] ) ? $settings['error_message'] : esc_html__( 'We failed to send your message!', 'textdomain' ); + if ( empty( $settings ) ) { + return $return; + } + + /** + * Bail if there is nowhere to send the email. + */ + if ( ! isset( $settings['to_send_email'] ) || ! is_email( $settings['to_send_email'] ) ) { + $return['message'] = esc_html__( 'Wrong email configuration! Please contact administration!', 'textdomain' ); + return $return; + } + + $fields = array_key_exists( 'form_fields', $settings ) ? $settings['form_fields'] : ( array_key_exists( 'fields', $settings ) ? $settings['fields'] : array() ); + if ( empty( $fields ) ) { + return $return; + } + + foreach ( $fields as $field ) { + $field = (array) $field; + $key = Form_Manager::get_field_key_name( $field ); + $required_field = array_key_exists( 'requirement', $field ) ? $field['requirement'] : ( array_key_exists( 'required', $field ) ? $field['required'] : '' ); + + if ( 'required' === $required_field && empty( $data[ $key ] ) && 'hidden' !== $field['type'] ) { + $return['message'] = sprintf( esc_html__( 'Missing %s', 'textdomain' ), $key ); + return $return; + } + + if ( 'email' === $field['type'] && ! is_email( $data[ $key ] ) ) { + $return['message'] = esc_html__( 'Invalid email.', 'textdomain' ); + return $return; + } + + if ( 'hidden' === $field['type'] ) { + $data[ $key ] = $this->parse_hidden_text( $data[ $key ], $post_id ); + } + } + + $from = isset( $data['email'] ) ? $data['email'] : null; + $name = isset( $data['name'] ) ? $data['name'] : null; + + // prepare settings for submit + $result = $this->_send_mail( $settings['to_send_email'], $from, $name, $data ); + + $return['message'] = $error_message; + if ( $result ) { + $return['success'] = true; + $return['message'] = $success_message; + } + + return $return; + } + + /** + * Mail sender method + * + * @param string $mailto Recipient email. + * @param string $mailfrom Sender email. + * @param string $name Name field. + * @param array $extra_data Form data. + * + * @return bool + */ + private function _send_mail( $mailto, $mailfrom, $name, $extra_data = array() ) { + + $name = sanitize_text_field( $name ); + $subject = 'Website inquiry from ' . ( ! empty( $name ) ? $name : 'N/A' ); + $mailto = sanitize_email( $mailto ); + $mailfrom = sanitize_email( $mailfrom ); + $headers = array(); + + $headers[] = 'From: Admin <' . $mailto . '>'; + if ( ! empty( $mailfrom ) ) { + $headers[] = 'Reply-To: ' . $name . ' <' . $mailfrom . '>'; + } + $headers[] = 'Content-Type: text/html; charset=UTF-8'; + + $body = $this->prepare_body( $extra_data ); + + ob_start(); + + $success = wp_mail( $mailto, $subject, $body, $headers ); + + if ( ! $success ) { + return ob_get_clean(); + } + + return $success; + } + + /** + * Body template preparation + * + * @param array $data + * + * @return string + */ + private function prepare_body( $data ) { + ob_start(); ?> + + + + + + + + <?php echo esc_html__( 'Mail From: ', 'textdomain' ) . isset( $data['name'] ) ? esc_html( $data['name'] ) : 'N/A'; ?> + + + + + + + + + + $value ) { + ?> + + + + + + + + + + +
+

+ + +

+
+
+ : +

+
+
+ + +
+ + + get_widget_settings( $widget_id, $post_id, $builder ); + if ( empty( $settings['access_key'] ) || empty( $settings['list_id'] ) ) { + $return['message'] = esc_html__( 'Wrong email configuration! Please contact administration!', 'textdomain' ); + + return $return; + } + + $form_fields = array(); + foreach ( $data as $field_name => $field_value ) { + $form_fields[ $field_name ] = $field_value; + } + + $form_settings = array( + 'provider_settings' => array( + 'provider' => ! empty( $settings['provider'] ) ? $settings['provider'] : 'mailchimp', + 'access_key' => $settings['access_key'], + 'list_id' => $settings['list_id'], + ), + 'data' => $form_fields, + 'strings' => array( + 'error_message' => array_key_exists( 'error_message', $settings ) && ! empty( $settings['error_message'] ) ? $settings['error_message'] : esc_html__( 'Action failed!', 'textdomain' ), + 'success_message' => array_key_exists( 'success_message', $settings ) && ! empty( $settings['success_message'] ) ? $settings['success_message'] : esc_html__( 'Welcome to our newsletter!', 'textdomain' ), + ), + ); + + $return = $this->subscribe_mail( $form_settings, $return ); + + return $return; + } + + /** + * Subscribe the given email to the given provider, either mailchimp or sendinblue. + * + * @param array $form_settings Form Settings. + * @param array $result Return result + * + * @return array + */ + private function subscribe_mail( $form_settings, $result ) { + + $provider_name = $form_settings['provider_settings']['provider']; + $result['success'] = false; + $result['message'] = $form_settings['strings']['error_message']; + + if ( $provider_name === 'mailchimp' ) { + $result = $this->mailchimp_subscribe( $form_settings, $result ); + } + + if ( $provider_name === 'sendinblue' ) { + $result = $this->sib_subscribe( $form_settings, $result ); + } + + if ( $provider_name === 'mailerlite' ) { + $result = $this->mailerlite_subscribe( $form_settings, $result ); + } + + return $result; + } + + /** + * Handle the request for mailchimp. + * https://mailchimp.com/developer/reference/lists/list-members/ + * + * @param array $form_settings Form settings. + * + * @return bool + */ + private function mailchimp_subscribe( $form_settings, $result ) { + + $api_key = $form_settings['provider_settings']['access_key']; + $list_id = $form_settings['provider_settings']['list_id']; + $data = $form_settings['data']; + $user_status = $this->get_new_user_status( $api_key, $list_id ); + $email = $data['EMAIL']; + unset( $data['EMAIL'] ); + + $form_data = array( + 'email_address' => $email, + 'status' => $user_status, + ); + + if ( ! empty( $data ) ) { + $form_data['merge_fields'] = $data; + } + + $url = 'https://' . substr( $api_key, strpos( $api_key, '-' ) + 1 ) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/' . md5( strtolower( $email ) ); + + $args = array( + 'method' => 'PUT', + 'headers' => array( + 'Authorization' => 'Basic ' . base64_encode( 'user:' . $api_key ), + ), + 'body' => json_encode( $form_data ), + ); + + $response = wp_remote_post( $url, $args ); + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + $message = ! empty( $body['detail'] ) && $body['detail'] !== 'null' ? $body['detail'] : $form_settings['strings']['error_message']; + $result['success'] = false; + $result['message'] = $message; + return $result; + } + + if ( $body['status'] === 'pending' || $body['status'] === 'subscribed' ) { + $result['message'] = $form_settings['strings']['success_message']; + $result['success'] = true; + return $result; + } + + return $result; + } + + /** + * Check if the subscribing list has double opt-in. + * If the option is activated, return pending status for new users, else return subscribed. + * + * @param string $api_key Api key. + * @param string $list_id List id. + * + * @return string + */ + private function get_new_user_status( $api_key, $list_id ) { + $url = 'https://' . substr( $api_key, strpos( $api_key, '-' ) + 1 ) . '.api.mailchimp.com/3.0/lists/' . $list_id; + $args = array( + 'method' => 'GET', + 'headers' => array( + 'Authorization' => 'Basic ' . base64_encode( 'user:' . $api_key ), + ), + ); + + $response = wp_remote_post( $url, $args ); + + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + return 'pending'; + } + + return array_key_exists( 'double_optin', $body ) && $body['double_optin'] === true ? 'pending' : 'subscribed'; + } + + /** + * Handle the request for sendinblue. + * https://developers.sendinblue.com/reference#createcontact + * + * @param array $form_settings Form settings. + * + * @return bool + */ + private function sib_subscribe( $form_settings, $result ) { + + $api_key = $form_settings['provider_settings']['access_key']; + $list_id = $form_settings['provider_settings']['list_id']; + $data = $form_settings['data']; + $email = $data['EMAIL']; + unset( $data['EMAIL'] ); + + $url = 'https://api.sendinblue.com/v3/contacts'; + + $form_data = array( + 'email' => $email, + 'listIds' => array( (int) $list_id ), + 'emailBlacklisted' => false, + 'smsBlacklisted' => false, + ); + + if ( ! empty( $data ) ) { + $form_data['attributes'] = $data; + } + $args = array( + 'method' => 'POST', + 'headers' => array( + 'content-type' => 'application/json', + 'api-key' => $api_key, + ), + 'body' => json_encode( $form_data ), + ); + + $response = wp_remote_post( $url, $args ); + if ( is_wp_error( $response ) ) { + return $result; + } + + if ( 400 !== wp_remote_retrieve_response_code( $response ) ) { + $result['message'] = $form_settings['strings']['success_message']; + $result['success'] = true; + return $result; + } + + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + $result['message'] = $body['message']; + return $result; + } + + /** + * Handle the request for MailerLite. + * + * @param array $form_settings Form data. + * @param array $result Server response array. + * + * @return array + */ + private function mailerlite_subscribe( $form_settings, $result ) { + if ( version_compare( '7.1', phpversion() ) === 1 ) { + return false; + } + + $api_key = $form_settings['provider_settings']['access_key']; + $list_id = $form_settings['provider_settings']['list_id']; + $data = $form_settings['data']; + if ( ! is_array( $data ) ) { + return $result; + } + $form_data = array( + 'email' => $data['EMAIL'], + ); + unset( $data['EMAIL'] ); + + if ( ! empty( $data ) ) { + foreach ( $data as $key => $value ) { + $form_data['fields'][ strtolower( $key ) ] = $value; + } + } + + try { + $ml_subscribers = new \MailerLiteApi\MailerLite( $api_key ); + $groups_api = $ml_subscribers->groups(); + $ml_response = $groups_api->addSubscriber( $list_id, $form_data ); + if ( ! property_exists( $ml_response, 'error' ) ) { + $result['message'] = $form_settings['strings']['success_message']; + $result['success'] = true; + return $result; + } + return $result; + } catch ( \MailerLiteApi\Exceptions\MailerLiteSdkException $e ) { + return $result; + } + } +} diff --git a/obfx_modules/content-forms/includes/widgets-public/registration_public.php b/obfx_modules/content-forms/includes/widgets-public/registration_public.php new file mode 100644 index 00000000..54d341fe --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-public/registration_public.php @@ -0,0 +1,106 @@ +_register_user( $return, $settings ); + + return $return; + } + + /** + * Add a new user for the given details + * + * @param array $return Return array. + * @param array $settings Settings array. + * + * @return array mixed + */ + private function _register_user( $return, $settings ) { + + if ( ! get_option( 'users_can_register' ) ) { + $return['message'] = esc_html__( 'This website does not allow registrations at this moment!' ); + + return $return; + } + + if ( ! validate_username( $settings['user_login'] ) ) { + $return['message'] = esc_html__( 'Invalid user name' ); + + return $return; + } + + if ( username_exists( $settings['user_login'] ) ) { + $return['message'] = esc_html__( 'Username already exists' ); + + return $return; + } + + if ( email_exists( $settings['user_email'] ) ) { + $return['message'] = esc_html__( 'This email is already registered' ); + return $return; + } + + $user_id = wp_insert_user( $settings ); + + if ( ! is_wp_error( $user_id ) ) { + + if ( ! empty( $extra_data ) ) { + foreach ( $extra_data as $key => $value ) { + update_user_meta( $user_id, sanitize_title( $key ), sanitize_text_field( $value ) ); + } + } + + $return['success'] = true; + $return['message'] = esc_html__( 'Welcome, ', 'textdomain' ) . $settings['user_login'] . '!'; + } + + return $return; + } +} diff --git a/obfx_modules/content-forms/includes/widgets-public/widget_actions_base.php b/obfx_modules/content-forms/includes/widgets-public/widget_actions_base.php new file mode 100644 index 00000000..037ceedd --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-public/widget_actions_base.php @@ -0,0 +1,176 @@ +form_type = $this->get_form_type(); + add_filter( 'content_forms_submit_' . $this->form_type, array( $this, 'rest_submit_form' ), 10, 5 ); + } + + /** + * This method is passed to the rest controller and it is responsible for submitting the data. + * + * @param array $return Return format. + * @param array $data Form data. + * @param string $widget_id Widget id. + * @param int $post_id Post id. + * @param string $builder Page builder. + * + * @return array + */ + abstract function rest_submit_form( $return, $data, $widget_id, $post_id, $builder ); + + /** + * Get form type. + * @return string + */ + abstract function get_form_type(); + + /** + * Extract widget settings based on a widget id and a page id + * + * @param int $post_id The id of the post. + * @param string $widget_id The widget id. + * @param string $builder Page builder. + * + * @return array|bool + */ + static function get_widget_settings( $widget_id, $post_id, $builder ) { + + if ( $builder === 'elementor' ) { + return self::get_elementor_module_settings_by_id( $widget_id, $post_id ); + } + + if ( $builder === 'beaver' ) { + return self::get_beaver_module_settings_by_id( $widget_id, $post_id ); + } + + return false; + } + + /** + * Extract Elementpr widget settings based on a widget id and a page id + * + * @param int $post_id The id of the post. + * @param string $widget_id The widget id. + * + * @return array|bool + */ + private static function get_elementor_module_settings_by_id( $widget_id, $post_id ) { + $document = Plugin::$instance->documents->get( $post_id ); + $elements_data = $document->get_elements_data(); + + //Filters the builder content in the frontend. + $elements_data = apply_filters( 'elementor/frontend/builder_content_data', $elements_data, $post_id ); + if ( ! empty( $elements_data ) ) { + $data = self::get_widget_data_by_id( $widget_id, $elements_data ); + if ( array_key_exists( 'settings', $data ) ) { + return $data['settings']; + } + } + + return $elements_data; + } + + /** + * Recursively look through Elementor data and extract the settings for a specific widget. + * + * @param string $widget_id Widget id. + * @param array $elements_data Elements data. + * + * @return array|bool + */ + private static function get_widget_data_by_id( $widget_id, $elements_data ) { + if ( empty( $elements_data ) ) { + return false; + } + + foreach ( $elements_data as $el ) { + + if ( $el['elType'] === 'widget' && $el['id'] === $widget_id ) { + return $el; + } + + if ( ! empty( $el['elements'] ) ) { + $el = self::get_widget_data_by_id( $widget_id, $el['elements'] ); + + if ( $el ) { + return $el; + } + } + } + + return false; + } + + /** + * Each beaver module has data saved in the post metadata, and we need to extract it by its id. + * + * @param $node_id + * @param $post_id + * + * @return array|bool + */ + public static function get_beaver_module_settings_by_id( $node_id, $post_id ) { + $post_data = \FLBuilderModel::get_layout_data( null, $post_id ); + if ( isset( $post_data[ $node_id ] ) ) { + $module = $post_data[ $node_id ]; + return (array) $module->settings; + } + return false; + } + + /** + * Replace magic tags in hidden field. + * + * @param string $hidden_value Field hidden value. + * @param int $post_id Post id. + * + * @return string + */ + protected function parse_hidden_text( $hidden_value, $post_id ) { + + $current_url = get_the_permalink( $post_id ); + + $hidden_value = str_replace( '{current_url}', $current_url, $hidden_value ); + + $user_id = get_current_user_id(); + if ( $user_id !== 0 ) { + $user_info = get_userdata( $user_id ); + $hidden_value = str_replace( '{username}', $user_info->user_login, $hidden_value ); + $hidden_value = str_replace( '{user_nice_name}', $user_info->first_name . ' ' . $user_info->last_name, $hidden_value ); + $hidden_value = str_replace( '{user_type}', implode( ', ', $user_info->roles ), $hidden_value ); + $hidden_value = str_replace( '{user_email}', $user_info->user_email, $hidden_value ); + } else { + $replacement = __( 'Could not retrieve the info because the user is not logged in.', 'textdomain' ); + $hidden_value = str_replace( '{username}', $replacement, $hidden_value ); + $hidden_value = str_replace( '{user_nice_name}', $replacement, $hidden_value ); + $hidden_value = str_replace( '{user_type}', $replacement, $hidden_value ); + $hidden_value = str_replace( '{user_email}', $replacement, $hidden_value ); + } + + return $hidden_value; + } + +} diff --git a/obfx_modules/content-forms/load.php b/obfx_modules/content-forms/load.php new file mode 100644 index 00000000..276abd69 --- /dev/null +++ b/obfx_modules/content-forms/load.php @@ -0,0 +1,8 @@ +artifact/* assets/* obfx_modules/elementor-extra-widgets/ + obfx_modules/content-forms/ \ No newline at end of file