diff --git a/composer.json b/composer.json index aacd358a..92c1d5c7 100644 --- a/composer.json +++ b/composer.json @@ -32,14 +32,14 @@ "require": { "codeinwp/full-width-page-templates": "master", "codeinwp/themeisle-sdk": "^3.3", - "codeinwp/elementor-extra-widgets": "dev-master", - "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" ] }, "prefer-stable": true, diff --git a/composer.lock b/composer.lock index 64c27eac..396c7e55 100644 --- a/composer.lock +++ b/composer.lock @@ -4,46 +4,73 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "98526a13b8c1cb51fd026cef17ddbaae", + "content-hash": "a5901a219e53451f0aa0c4ae62edd951", "packages": [ { - "name": "codeinwp/elementor-extra-widgets", - "version": "dev-master", + "name": "clue/stream-filter", + "version": "v1.7.0", "source": { "type": "git", - "url": "https://github.com/Codeinwp/elementor-extra-widgets.git", - "reference": "3dbe12d2ba79edda78402b8f27c4b7b60e87b70e" + "url": "https://github.com/clue/stream-filter.git", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/elementor-extra-widgets/zipball/3dbe12d2ba79edda78402b8f27c4b7b60e87b70e", - "reference": "3dbe12d2ba79edda78402b8f27c4b7b60e87b70e", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7", "shasum": "" }, - "default-branch": true, + "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-3.0-or-later" + "MIT" ], "authors": [ { - "name": "ThemeIsle team", - "email": "friends@themeisle.com", - "homepage": "https://themeisle.com" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "homepage": "https://github.com/Codeinwp/elementor-extra-widgets", + "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/Codeinwp/elementor-extra-widgets/issues", - "source": "https://github.com/Codeinwp/elementor-extra-widgets/tree/master" + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.7.0" }, - "time": "2024-04-16T14:25:20+00:00" + "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/full-width-page-templates", @@ -80,50 +107,6 @@ "homepage": "https://github.com/Codeinwp/full-width-page-templates", "time": "2019-04-02T11:34:00+00:00" }, - { - "name": "codeinwp/themeisle-content-forms", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/Codeinwp/themeisle-content-forms.git", - "reference": "5489008fb3354940e878cc4db5f0300a4853fa39" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/themeisle-content-forms/zipball/5489008fb3354940e878cc4db5f0300a4853fa39", - "reference": "5489008fb3354940e878cc4db5f0300a4853fa39", - "shasum": "" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", - "wptrt/wpthemereview": "*" - }, - "default-branch": true, - "type": "library", - "autoload": { - "files": [ - "load.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-3.0-or-later" - ], - "authors": [ - { - "name": "ThemeIsle", - "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" - }, { "name": "codeinwp/themeisle-sdk", "version": "3.3.39", @@ -209,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": [ @@ -593,10 +1201,7 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "codeinwp/elementor-extra-widgets": 20, - "codeinwp/themeisle-content-forms": 20 - }, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": [], @@ -604,5 +1209,5 @@ "platform-overrides": { "php": "5.6" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/obfx_modules/beaver-widgets/init.php b/obfx_modules/beaver-widgets/init.php index bbdfcb87..b53338e7 100644 --- a/obfx_modules/beaver-widgets/init.php +++ b/obfx_modules/beaver-widgets/init.php @@ -34,8 +34,8 @@ public function __construct() { * @access public */ public function set_module_strings() { - $this->name = __( 'Page builder widgets', 'themeisle-companion' ); - $this->description = __( 'Adds widgets to the most popular builders: Elementor or Beaver. More to come!', 'themeisle-companion' ); + $this->name = __( 'Page builder widgets', 'themeisle-companion' ); + $this->description = __( 'Adds widgets to the most popular builders: Elementor or Beaver. More to come!', 'themeisle-companion' ); } /** 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..67b8f61a --- /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?', 'themeisle-companion' ), '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?', 'themeisle-companion' ), '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..2bf28546 --- /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.', 'themeisle-companion' ), + ), + 'nonce' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'The security key', 'themeisle-companion' ), + ), + 'data' => array( + 'type' => 'json', + 'required' => true, + 'description' => __( 'The form must have data', 'themeisle-companion' ), + ), + 'form_id' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'The form identifier.', 'themeisle-companion' ), + ), + 'post_id' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'The form identifier.', 'themeisle-companion' ), + ), + 'form_builder' => array( + 'type' => 'string', + 'required' => true, + 'description' => __( 'Form builder.', 'themeisle-companion' ), + ), + ), + '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', 'themeisle-companion' ), + ), + 400 + ); + + } + + $data = $request->get_param( 'data' ); + if ( empty( $data[ $form_id ] ) ) { + return new \WP_REST_Response( + array( + 'success' => false, + 'message' => esc_html__( 'Invalid Data ', 'themeisle-companion' ) . $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', 'themeisle-companion' ), + ); + + /** + * 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..9793ed41 --- /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', 'themeisle-companion' ), + 'email' => esc_html__( 'Email', 'themeisle-companion' ), + 'textarea' => esc_html__( 'Textarea', 'themeisle-companion' ), + 'password' => esc_html__( 'Password', 'themeisle-companion' ), + ); + + $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', 'themeisle-companion' ), + 'fields' => array( + 'column_gap' => array( + 'responsive' => true, + 'type' => 'unit', + 'units' => array( 'px' ), + 'label' => __( 'Columns Gap', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'fields' => array( + 'label_color' => array( + 'type' => 'color', + 'label' => __( 'Text Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset label', + ), + ), + ), + ), + 'field' => array( + 'title' => esc_html__( 'Field', 'themeisle-companion' ), + 'fields' => array( + 'field_text_color' => array( + 'type' => 'color', + 'label' => __( 'Text Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'fields' => array( + 'button_width' => array( + 'responsive' => 'true', + 'type' => 'unit', + 'label' => __( 'Width', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]', + ), + ), + 'button_border' => array( + 'type' => 'border', + 'label' => __( 'Border', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'fields' => array( + 'button_background_color_hover' => array( + 'type' => 'color', + 'label' => __( 'Button Background Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' fieldset button[name="submit"]:hover', + ), + ), + ), + ), + 'notification' => array( + 'title' => esc_html__( 'Notification', 'themeisle-companion' ), + 'fields' => array( + 'notification_margin' => array( + 'type' => 'dimension', + 'label' => __( 'Margin', 'themeisle-companion' ), + 'description' => 'px', + ), + 'notification_text_padding' => array( + 'type' => 'dimension', + 'label' => __( 'Padding', 'themeisle-companion' ), + 'description' => 'px', + ), + 'notification_width' => array( + 'type' => 'unit', + 'label' => __( 'Width', 'themeisle-companion' ), + 'slider' => array( + 'min' => 0, + 'max' => 100, + 'step' => 1, + ), + ), + 'notification_typography' => array( + 'type' => 'typography', + 'label' => __( 'Typography', 'themeisle-companion' ), + 'responsive' => true, + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-notice', + ), + ), + 'notification_box_shadow' => array( + 'type' => 'shadow', + 'label' => __( 'Box Shadow', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'default' => 'left', + ), + ), + ), + 'notification_success' => array( + 'title' => esc_html__( 'Notification Success', 'themeisle-companion' ), + 'fields' => array( + 'notification_success_background_color' => array( + 'type' => 'color', + 'label' => __( 'Background', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'preview' => array( + 'type' => 'css', + 'selector' => '.content-form-' . $this->get_type() . ' .content-form-success', + ), + ), + ), + ), + 'notification_error' => array( + 'title' => esc_html__( 'Notification Error', 'themeisle-companion' ), + 'fields' => array( + 'notification_error_background_color' => array( + 'type' => 'color', + 'label' => __( 'Background', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'fields' => array( + 'fields' => array( + 'multiple' => true, + 'type' => 'form', + 'label' => esc_html__( 'Field', 'themeisle-companion' ), + 'form' => $this->get_type() . '_field', + 'preview_text' => 'label', + 'default' => $this->get_default( 'fields' ), + ), + 'hide_label' => array( + 'type' => 'select', + 'label' => __( 'Hide Label', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + ), + 'placeholder' => array( + 'type' => 'text', + 'label' => esc_html__( 'Placeholder', 'themeisle-companion' ), + ), + 'type' => array( + 'type' => 'select', + 'label' => esc_html__( 'Type', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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?', 'themeisle-companion' ), + 'options' => array( + 'required' => esc_html__( 'Required', 'themeisle-companion' ), + 'optional' => esc_html__( 'Optional', 'themeisle-companion' ), + ), + ), + ); + + \FLBuilder::register_settings_form( + $this->get_type() . '_field', + array( + 'title' => esc_html__( 'Field', 'themeisle-companion' ), + 'tabs' => array( + 'general' => array( + 'title' => esc_html__( 'Field', 'themeisle-companion' ), + 'sections' => array( + 'fields' => array( + 'title' => esc_html__( 'Field', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'fields' => array( + 'submit_label' => array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'themeisle-companion' ), + 'default' => $this->get_default( 'submit_label' ), + 'description' => esc_html__( 'The Call To Action label', 'themeisle-companion' ), + ), + 'submit_display' => array( + 'type' => 'select', + 'label' => __( 'Submit Display', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ) . '

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

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

'; + 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!', 'themeisle-companion' ), + '' . esc_html__( 'Access Key', 'themeisle-companion' ) . '' + ); + 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!', 'themeisle-companion' ), + '' . esc_html__( 'List id', 'themeisle-companion' ) . '' + ); + 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.', 'themeisle-companion' ), + '' . $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!', 'themeisle-companion' ), + '' . esc_html__( 'Send to Email Address', 'themeisle-companion' ) . '' + ); + 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', 'themeisle-companion' ), + 'city' => __( 'City', 'themeisle-companion' ), + 'state' => __( 'State/Province/Region', 'themeisle-companion' ), + 'zip' => __( 'Postal / Zip Code', 'themeisle-companion' ), + 'country' => __( 'Country', 'themeisle-companion' ), + ); + 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', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Name', 'themeisle-companion' ), + 'type' => 'text', + 'field_width' => '100', + 'required' => 'required', + ), + array( + 'key' => 'email', + 'label' => esc_html__( 'Email', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Email', 'themeisle-companion' ), + 'type' => 'email', + 'field_width' => '100', + 'required' => 'required', + ), + array( + 'key' => 'phone', + 'label' => esc_html__( 'Phone', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Phone', 'themeisle-companion' ), + 'type' => 'number', + 'field_width' => '100', + 'required' => 'optional', + ), + array( + 'key' => 'message', + 'label' => esc_html__( 'Message', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Message', 'themeisle-companion' ), + 'type' => 'textarea', + 'field_width' => '100', + 'required' => 'required', + ), + ), + 'submit_label' => esc_html__( 'Submit', 'themeisle-companion' ), + 'success_message' => esc_html__( 'Your message has been sent!', 'themeisle-companion' ), + 'error_message' => esc_html__( 'Oops! I cannot send this email!', 'themeisle-companion' ), + ); + } + + /** + * Contact_Admin constructor. + */ + public function __construct() { + parent::__construct( + array( + 'name' => esc_html__( 'Contact', 'themeisle-companion' ), + 'description' => esc_html__( 'A contact form.', 'themeisle-companion' ), + 'category' => esc_html__( 'Orbit Fox Modules', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'description' => __( 'You can use the following magic tags to get additional information: {current_url}, {username}, {user_nice_name}, {user_type}, {user_email}', 'themeisle-companion' ), + ); + 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', 'themeisle-companion' ), + 'default' => $this->get_default( 'success_message' ), + ), + 'error_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'themeisle-companion' ), + 'default' => $this->get_default( 'error_message' ), + ), + 'to_send_email' => array( + 'type' => 'text', + 'label' => esc_html__( 'Send to', 'themeisle-companion' ), + 'description' => esc_html__( 'Where should we send the email?', 'themeisle-companion' ), + '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', 'themeisle-companion' ); + $field_types['hidden'] = esc_html__( 'Hidden', 'themeisle-companion' ); + 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..7240e425 --- /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', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Email', 'themeisle-companion' ), + 'type' => 'email', + 'required' => 'required', + 'field_map' => 'email', + 'field_width' => '75', + ), + ), + 'submit_label' => esc_html__( 'Join Newsletter', 'themeisle-companion' ), + 'success_message' => esc_html__( 'Welcome to our newsletter!', 'themeisle-companion' ), + 'error_message' => esc_html__( 'Action failed!', 'themeisle-companion' ), + ); + } + + /** + * Newsletter_Admin constructor. + */ + public function __construct() { + parent::__construct( + array( + 'name' => esc_html__( 'Newsletter', 'themeisle-companion' ), + 'description' => esc_html__( 'A simple newsletter form.', 'themeisle-companion' ), + 'category' => esc_html__( 'Orbit Fox Modules', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'sendinblue' => esc_html__( 'Sendinblue ', 'themeisle-companion' ), + ); + if ( version_compare( '7.1', phpversion() ) !== 1 ) { + $providers['mailerlite'] = esc_html__( 'MailerLite', 'themeisle-companion' ); + } + $fields['fields'] = array( + 'provider' => array( + 'type' => 'select', + 'label' => esc_html__( 'Subscribe to', 'themeisle-companion' ), + 'options' => $providers, + ), + 'access_key' => array( + 'type' => 'text', + 'label' => esc_html__( 'Access Key', 'themeisle-companion' ), + ), + 'list_id' => array( + 'type' => 'text', + 'label' => esc_html__( 'List ID', 'themeisle-companion' ), + ), + 'success_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Success message', 'themeisle-companion' ), + 'default' => $this->get_default( 'success_message' ), + ), + 'error_message' => array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'themeisle-companion' ), + '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..bb2679fb --- /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', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'User Name', 'themeisle-companion' ), + 'type' => 'text', + 'required' => 'required', + 'field_map' => 'user_login', + 'field_width' => '100', + ), + array( + 'key' => 'email', + 'label' => esc_html__( 'Email', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Email', 'themeisle-companion' ), + 'type' => 'email', + 'required' => 'required', + 'field_map' => 'user_email', + 'field_width' => '100', + ), + array( + 'key' => 'password', + 'label' => esc_html__( 'Password', 'themeisle-companion' ), + 'placeholder' => esc_html__( 'Password', 'themeisle-companion' ), + 'type' => 'password', + 'required' => 'required', + 'field_map' => 'user_pass', + 'field_width' => '100', + ), + ), + 'submit_label' => esc_html__( 'Register', 'themeisle-companion' ), + ); + } + + /** + * Registration_Admin constructor. + */ + public function __construct() { + parent::__construct( + array( + 'name' => esc_html__( 'Registration', 'themeisle-companion' ), + 'description' => esc_html__( 'A sign up form.', 'themeisle-companion' ), + 'category' => esc_html__( 'Orbit Fox Modules', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'last_name' => __( 'Last Name', 'themeisle-companion' ), + 'user_pass' => __( 'Password', 'themeisle-companion' ), + 'user_login' => __( 'Username', 'themeisle-companion' ), + 'user_email' => __( 'Email', 'themeisle-companion' ), + 'display_name' => __( 'Display Name', 'themeisle-companion' ), + ); + + $fields['field_map'] = array( + 'label' => __( 'Map field to', 'themeisle-companion' ), + '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..d3b74c20 --- /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', 'themeisle-companion' ); +$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..5f9d5912 --- /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', 'themeisle-companion' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Name', 'themeisle-companion' ), + 'field_width' => '100', + ), + array( + 'key' => 'email', + 'type' => 'email', + 'label' => esc_html__( 'Email', 'themeisle-companion' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Email', 'themeisle-companion' ), + 'field_width' => '100', + ), + array( + 'key' => 'phone', + 'type' => 'number', + 'label' => esc_html__( 'Phone', 'themeisle-companion' ), + 'requirement' => 'optional', + 'placeholder' => esc_html__( 'Phone', 'themeisle-companion' ), + 'field_width' => '100', + ), + array( + 'key' => 'message', + 'type' => 'textarea', + 'label' => esc_html__( 'Message', 'themeisle-companion' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Message', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'default' => esc_html__( 'Your message has been sent!', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'error_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'themeisle-companion' ), + 'default' => esc_html__( 'Oops! I cannot send this email!', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'to_send_email', + array( + 'type' => 'text', + 'label' => esc_html__( 'Send to', 'themeisle-companion' ), + 'default' => get_bloginfo( 'admin_email' ), + 'description' => esc_html__( 'Where should we send the email?', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'submit_label', + array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'themeisle-companion' ), + 'default' => esc_html__( 'Submit', 'themeisle-companion' ), + ) + ); + + $this->add_responsive_control( + 'align_submit', + array( + 'label' => __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'description' => __( 'You can use the following magic tags to get additional information: {current_url}, {username}, {user_nice_name}, {user_type}, {user_email}', 'themeisle-companion' ), + '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', 'themeisle-companion' ); + $field_types['hidden'] = esc_html__( 'Hidden', 'themeisle-companion' ); + 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..c325415c --- /dev/null +++ b/obfx_modules/content-forms/includes/widgets-admin/elementor/elementor_widget_base.php @@ -0,0 +1,1343 @@ +field_types = array( + 'text' => __( 'Text', 'themeisle-companion' ), + 'password' => __( 'Password', 'themeisle-companion' ), + 'email' => __( 'Email', 'themeisle-companion' ), + 'textarea' => __( 'Textarea', 'themeisle-companion' ), + ); + + $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', 'themeisle-companion' ), + ) + ); + $repeater = new Repeater(); + + $repeater->add_control( + 'requirement', + array( + 'label' => __( 'Required', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::SELECT, + 'options' => $field_types, + 'default' => 'text', + ) + ); + + $repeater->add_control( + 'key', + array( + 'label' => __( 'Key', 'themeisle-companion' ), + 'type' => Controls_Manager::HIDDEN, + ) + ); + + $repeater->add_responsive_control( + 'field_width', + array( + 'label' => __( 'Field Width', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + ) + ); + + $repeater->add_control( + 'placeholder', + array( + 'label' => __( 'Placeholder', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + ) + ); + + $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', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_control( + 'column_gap', + array( + 'label' => __( 'Columns Gap', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'label_spacing', + array( + 'label' => __( 'Spacing', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'field_text_color', + array( + 'label' => __( 'Text Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::SELECT, + 'options' => array( + '' => __( 'None', 'themeisle-companion' ), + 'solid' => _x( 'Solid', 'Border Control', 'themeisle-companion' ), + 'double' => _x( 'Double', 'Border Control', 'themeisle-companion' ), + 'dotted' => _x( 'Dotted', 'Border Control', 'themeisle-companion' ), + 'dashed' => _x( 'Dashed', 'Border Control', 'themeisle-companion' ), + 'groove' => _x( 'Groove', 'Border Control', 'themeisle-companion' ), + ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'field_focus_text_color', + array( + 'label' => __( 'Text Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::SELECT, + 'options' => array( + '' => __( 'None', 'themeisle-companion' ), + 'solid' => _x( 'Solid', 'Border Control', 'themeisle-companion' ), + 'double' => _x( 'Double', 'Border Control', 'themeisle-companion' ), + 'dotted' => _x( 'Dotted', 'Border Control', 'themeisle-companion' ), + 'dashed' => _x( 'Dashed', 'Border Control', 'themeisle-companion' ), + 'groove' => _x( 'Groove', 'Border Control', 'themeisle-companion' ), + ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + array( + 'label' => __( 'Normal', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_background_color', + array( + 'label' => __( 'Background Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_background_hover_color', + array( + 'label' => __( 'Background Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > button:hover' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'button_hover_color', + array( + 'label' => __( 'Text Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => array( + '{{WRAPPER}} fieldset > button:hover' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'button_hover_border_color', + array( + 'label' => __( 'Border Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_responsive_control( + 'notification_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'selector' => '{{WRAPPER}} .content-form-notice', + ) + ); + + $this->add_responsive_control( + 'notification_alignment', + array( + 'label' => __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-align-right', + ), + ), + ) + ); + + $this->start_controls_tabs( 'tabs_notification_style' ); + + $this->start_controls_tab( + 'tab_notification_success', + array( + 'label' => __( 'Success', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'notification_background_color_success', + array( + 'label' => __( 'Background Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'selector' => '{{WRAPPER}} .content-form-notice.content-form-success', + ) + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_notification_error', + array( + 'label' => __( 'Error', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'notification_background_color_error', + array( + 'label' => __( 'Background Color', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ); + 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!', 'themeisle-companion' ), + '' . esc_html__( 'Access Key', 'themeisle-companion' ) . '' + ); + echo '

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

'; + printf( + esc_html__( 'The %s setting is required!', 'themeisle-companion' ), + '' . esc_html__( 'List id', 'themeisle-companion' ) . '' + ); + 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.', 'themeisle-companion' ), + '' . $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!', 'themeisle-companion' ), + '' . esc_html__( 'Send to Email Address', 'themeisle-companion' ) . '' + ); + 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', 'themeisle-companion' ) . '

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

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

'; + 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..34ae14b2 --- /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', 'themeisle-companion' ), + '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..3faac4cc --- /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', 'themeisle-companion' ), + 'requirement' => 'required', + 'placeholder' => esc_html__( 'Email', 'themeisle-companion' ), + 'field_width' => '100', + 'field_map' => 'email', + ), + ); + } + + /** + * Get Widget Title. + * + * @return string + */ + public function get_title() { + return esc_html__( 'Newsletter Form', 'themeisle-companion' ); + } + + /** + * 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', 'themeisle-companion' ), + 'sendinblue' => esc_html__( 'Sendinblue ', 'themeisle-companion' ), + ); + if ( version_compare( '7.1', phpversion() ) !== 1 ) { + $providers['mailerlite'] = esc_html__( 'MailerLite', 'themeisle-companion' ); + } + $this->add_control( + 'provider', + array( + 'type' => 'select', + 'label' => esc_html__( 'Subscribe to', 'themeisle-companion' ), + 'options' => $providers, + 'default' => 'mailchimp', + 'separator' => 'after', + ) + ); + + $this->add_control( + 'success_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Success message', 'themeisle-companion' ), + 'default' => esc_html__( 'Welcome to our newsletter!', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'error_message', + array( + 'type' => 'text', + 'label' => esc_html__( 'Error message', 'themeisle-companion' ), + 'default' => esc_html__( 'Action failed!', 'themeisle-companion' ), + 'separator' => 'after', + ) + ); + + $this->add_control( + 'submit_label', + array( + 'type' => 'text', + 'label' => esc_html__( 'Submit', 'themeisle-companion' ), + 'default' => esc_html__( 'Join Newsletter', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_icon_new', + array( + 'label' => __( 'Icon', 'themeisle-companion' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'button_icon', + ) + ); + + $this->add_control( + 'button_icon_size', + array( + 'label' => __( 'Icon Size', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'access_key', + array( + 'type' => 'text', + 'label' => esc_html__( 'Access Key', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'list_id', + array( + 'type' => 'text', + 'label' => esc_html__( 'List ID', 'themeisle-companion' ), + ) + ); + + $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', 'themeisle-companion' ), + '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.', 'themeisle-companion' ), + ) + ); + + $config = array( + 'addr2' => array( + 'label' => array( + 'label' => __( 'Line 2 Label', 'themeisle-companion' ), + 'default' => __( 'Address Line 2', 'themeisle-companion' ), + ), + 'placeholder' => array( + 'label' => __( 'Line 2 Placeholder', 'themeisle-companion' ), + 'default' => __( 'Address Line 2', 'themeisle-companion' ), + ), + 'width' => array( + 'label' => __( 'Line 2 Width', 'themeisle-companion' ), + 'default' => '100', + ), + ), + 'city' => array( + 'label' => array( + 'label' => __( 'City Label', 'themeisle-companion' ), + 'default' => __( 'City', 'themeisle-companion' ), + ), + 'placeholder' => array( + 'label' => __( 'City Placeholder', 'themeisle-companion' ), + 'default' => __( 'City', 'themeisle-companion' ), + ), + 'width' => array( + 'label' => __( 'City Width', 'themeisle-companion' ), + 'default' => '100', + ), + ), + 'state' => array( + 'label' => array( + 'label' => __( 'State Label', 'themeisle-companion' ), + 'default' => __( 'State/Province/Region', 'themeisle-companion' ), + ), + 'placeholder' => array( + 'label' => __( 'State Placeholder', 'themeisle-companion' ), + 'default' => __( 'State/Province/Region', 'themeisle-companion' ), + ), + 'width' => array( + 'label' => __( 'State Width', 'themeisle-companion' ), + 'default' => '100', + ), + ), + 'zip' => array( + 'label' => array( + 'label' => __( 'Zip Code Label', 'themeisle-companion' ), + 'default' => __( 'Postal / Zip Code', 'themeisle-companion' ), + ), + 'placeholder' => array( + 'label' => __( 'Zip Code Placeholder', 'themeisle-companion' ), + 'default' => __( 'Postal / Zip Code', 'themeisle-companion' ), + ), + 'width' => array( + 'label' => __( 'Zip Code Width', 'themeisle-companion' ), + 'default' => '100', + ), + ), + 'country' => array( + 'label' => array( + 'label' => __( 'Country Label', 'themeisle-companion' ), + 'default' => __( 'Country', 'themeisle-companion' ), + ), + 'placeholder' => array( + 'label' => __( ' Country Placeholder', 'themeisle-companion' ), + 'default' => __( 'Country', 'themeisle-companion' ), + ), + 'width' => array( + 'label' => __( 'Country Width', 'themeisle-companion' ), + '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..0aeafe2a --- /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', 'themeisle-companion' ), + 'require' => 'required', + 'placeholder' => esc_html__( 'User Name', 'themeisle-companion' ), + 'field_width' => '100', + 'field_map' => 'user_login', + ), + array( + 'key' => 'email', + 'type' => 'email', + 'label' => esc_html__( 'Email', 'themeisle-companion' ), + 'require' => 'required', + 'placeholder' => esc_html__( 'Email', 'themeisle-companion' ), + 'field_width' => '100', + 'field_map' => 'user_email', + ), + array( + 'key' => 'password', + 'type' => 'password', + 'label' => esc_html__( 'Password', 'themeisle-companion' ), + 'require' => 'required', + 'placeholder' => esc_html__( 'Password', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'default' => esc_html__( 'Register', 'themeisle-companion' ), + ) + ); + + $this->add_responsive_control( + 'align_submit', + array( + 'label' => __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'left', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + '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', 'themeisle-companion' ), + 'last_name' => __( 'Last Name', 'themeisle-companion' ), + 'user_pass' => __( 'Password', 'themeisle-companion' ), + 'user_login' => __( 'Username', 'themeisle-companion' ), + 'user_email' => __( 'Email', 'themeisle-companion' ), + 'display_name' => __( 'Display Name', 'themeisle-companion' ), + ); + $repeater->add_control( + 'field_map', + array( + 'label' => __( 'Map field to', 'themeisle-companion' ), + '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..6df0fe1e --- /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!', 'themeisle-companion' ); + $error_message = array_key_exists( 'error_message', $settings ) && ! empty( $settings['error_message'] ) ? $settings['error_message'] : esc_html__( 'We failed to send your message!', 'themeisle-companion' ); + 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!', 'themeisle-companion' ); + 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', 'themeisle-companion' ), $key ); + return $return; + } + + if ( 'email' === $field['type'] && ! is_email( $data[ $key ] ) ) { + $return['message'] = esc_html__( 'Invalid email.', 'themeisle-companion' ); + 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: ', 'themeisle-companion' ) . 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!', 'themeisle-companion' ); + + 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!', 'themeisle-companion' ), + 'success_message' => array_key_exists( 'success_message', $settings ) && ! empty( $settings['success_message'] ) ? $settings['success_message'] : esc_html__( 'Welcome to our newsletter!', 'themeisle-companion' ), + ), + ); + + $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..d3fca76b --- /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, ', 'themeisle-companion' ) . $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..8a3c1d4f --- /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.', 'themeisle-companion' ); + $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 @@ +name = __( 'Custom fonts', 'themeisle-companion' ); - $this->description = __( 'Upload custom fonts and use them anywhere on your site.', 'themeisle-companion' ); + $this->name = __( 'Custom fonts', 'themeisle-companion' ); + $this->description = __( 'Upload custom fonts and use them anywhere on your site.', 'themeisle-companion' ); } /** diff --git a/obfx_modules/elementor-extra-widgets/class-elementor-extra-widgets.php b/obfx_modules/elementor-extra-widgets/class-elementor-extra-widgets.php new file mode 100644 index 00000000..f3eb6073 --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/class-elementor-extra-widgets.php @@ -0,0 +1,290 @@ + 'obfx-elementor-widgets', + 'title' => __( 'Orbit Fox Addons', 'themeisle-companion' ), + 'icon' => 'fa fa-plug', + ) + ); + + // add a separate category for the premium widgets + $elements_manager->add_category( + $category_args['slug'] . '-pro', + array( + 'title' => 'Neve PRO Addon Widgets', + 'icon' => $category_args['slug'], + ) + ); + + $elements_manager->add_category( + $category_args['slug'], + array( + 'title' => $category_args['title'], + 'icon' => $category_args['slug'], + ) + ); + } + + /** + * Register style. + */ + public function register_styles() { + wp_register_style( 'eaw-elementor', plugins_url( '/css/public.css', __FILE__ ), array(), $this::$version ); + wp_register_style( 'font-awesome-5', ELEMENTOR_ASSETS_URL . 'lib/font-awesome/css/all.min.css', false, $this::$version ); + } + + /** + * Register js scripts. + */ + public function register_scripts() { + wp_register_script( 'obfx-grid-js', plugins_url( '/js/obfx-grid.js', __FILE__ ), array( 'jquery' ), $this::$version, true ); + } + + public function enqueue_sidebar_css() { + wp_enqueue_style( 'eaw-elementor-admin', plugins_url( '/css/admin.css', __FILE__ ), array(), $this::$version ); + } + + /** + * Require and instantiate Elementor Widgets and Premium Placeholders. + * + * @param $widgets_manager + */ + public function add_elementor_widgets( $widgets_manager ) { + $elementor_widgets = $this->get_dir_files( __DIR__ . '/widgets/elementor' ); + + foreach ( $elementor_widgets as $widget ) { + require_once $widget; + + $widget = basename( $widget, '.php' ); + + if ( $widget === 'premium-placeholder' ) {// avoid instantiate an abstract class + continue; + } + + $classname = $this->convert_filename_to_classname( $widget ); + + if ( class_exists( $classname ) ) { + $widget_object = new $classname(); + $widgets_manager->register_widget_type( $widget_object ); + } + } + + if ( wp_get_theme()->get( 'Name' ) === 'Neve' && class_exists( 'Elementor_Widgets_OBFX_Module', false ) && ! \Elementor_Widgets_OBFX_Module::has_valid_addons() ) { + $placeholders = $this->get_dir_files( __DIR__ . '/widgets/elementor/placeholders' ); + foreach ( $placeholders as $widget ) { + require_once $widget; + } + + do_action( 'eaw_before_pro_widgets', $placeholders, $widgets_manager ); + + foreach ( $placeholders as $widget ) { + $widget = basename( $widget, '.php' ); + + $classname = $this->convert_filename_to_classname( $widget ); + + // Maybe Premium Elements + if ( ! class_exists( $classname ) ) { + $classname = $classname . '_Placeholder'; + } + + if ( class_exists( $classname ) ) { + $widget_object = new $classname(); + $widgets_manager->register_widget_type( $widget_object ); + } + } + } + } + + /** + * WooCommerce Widget section + * + * @since 1.0.0 + * @return void + */ + public function register_woo_widgets() { + if ( ! class_exists( 'woocommerce' ) ) { // Lets not do anything unless WooCommerce is active! + return null; + } + + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/class-eaw-wp-widget.php'; + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/products-categories.php'; + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/recent-products.php'; + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/featured-products.php'; + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/popular-products.php'; + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/sale-products.php'; + include_once plugin_dir_path( __FILE__ ) . 'widgets/woo/best-products.php'; + + register_widget( 'Woo_Product_Categories' ); + register_widget( 'Woo_Recent_Products' ); + register_widget( 'Woo_Featured_Products' ); + register_widget( 'Woo_Popular_Products' ); + register_widget( 'Woo_Sale_Products' ); + register_widget( 'Woo_Best_Products' ); + } + + /** + * Posts Widget section + * + * @since 1.0.0 + * @return void + */ + public function register_posts_widgets() { + include_once plugin_dir_path( __FILE__ ) . 'widgets/wp/eaw-posts-widget.php'; + register_widget( 'EAW_Recent_Posts' ); + + include_once plugin_dir_path( __FILE__ ) . 'widgets/wp/eaw-posts-widget-plus.php'; + register_widget( 'EAW_Recent_Posts_Plus' ); + } + + /** + * Returns an array of all PHP files in the specified absolute path. + * Inspired from jetpack's glob_php + * + * @param string $absolute_path The absolute path of the directory to search. + * + * @return array Array of absolute paths to the PHP files. + */ + protected function get_dir_files( $absolute_path ) { + if ( function_exists( 'glob' ) ) { + return glob( "$absolute_path/*.php" ); + } + + $absolute_path = untrailingslashit( $absolute_path ); + $files = array(); + if ( ! $dir = @opendir( $absolute_path ) ) { + return $files; + } + + while ( false !== $file = readdir( $dir ) ) { + if ( '.' == substr( $file, 0, 1 ) || '.php' != substr( $file, - 4 ) ) { + continue; + } + + $file = "$absolute_path/$file"; + + if ( ! is_file( $file ) ) { + continue; + } + + $files[] = $file; + } + + closedir( $dir ); + + return $files; + } + + protected function convert_filename_to_classname( $widget ) { + $classname = ucwords( $widget, '-' ); + $classname = str_replace( '-', '_', $classname ); + $classname = '\\ThemeIsle\\ElementorExtraWidgets\\' . $classname; + + return $classname; + } + + /** + * + * @static + * @since 1.0.0 + * @access public + * @return ElementorExtraWidgets + */ + public static function instance() { + if ( is_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?', 'themeisle-companion' ), '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?', 'themeisle-companion' ), '1.0.0' ); + } + } +} diff --git a/obfx_modules/elementor-extra-widgets/css/admin.css b/obfx_modules/elementor-extra-widgets/css/admin.css new file mode 100644 index 00000000..70840306 --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/css/admin.css @@ -0,0 +1,15 @@ +.panel-elements-category-title-eaw-elementor-widgets-pro + .panel-elements-category-items .elementor-element { + position: relative; +} +.panel-elements-category-title-eaw-elementor-widgets-pro + .panel-elements-category-items .elementor-element:before { + content:"PRO"; + position: absolute; + background: #b7084e; + color: #fff; + border-radius: 3px; + padding: 3px 5px; + top: 5px; + right: 5px; + font-size: 10px; + font-weight: 700; +} diff --git a/obfx_modules/elementor-extra-widgets/css/public.css b/obfx_modules/elementor-extra-widgets/css/public.css new file mode 100644 index 00000000..087e6c0d --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/css/public.css @@ -0,0 +1,405 @@ +/* Pricing Table Base CSS */ +.obfx-pricing-table-wrapper, +.obfx-pricing-table-wrapper p.obfx-pricing-table-subtitle { + text-align: center; +} + +.obfx-pricing-table-wrapper a { + cursor: pointer; +} + +.obfx-title-wrapper { + padding: 15px; +} + +.obfx-pricing-table-title { + font-weight: 600; +} + +.obfx-pricing-table-wrapper .obfx-feature-list { + margin: 0; + padding: 10px 50px; + list-style: none; +} + +.obfx-pricing-table-wrapper .obfx-feature-list li { + font-size: 16px; +} + +.obfx-price-wrapper { + padding: 20px 0; +} + +.obfx-price { + font-size: 80px; + font-weight: 600; + line-height: normal; +} + +.obfx-pricing-period, +.obfx-price-currency { + font-size: 21px; +} + +.obfx-button-icon-align-right i { + margin-left: 5px; +} + +.obfx-button-icon-align-left i { + margin-right: 5px; +} + +.obfx-pricing-table-accented { + font-weight: 600; +} + +.obfx-pricing-table-button-wrapper { + padding: 20px 0; +} + +.obfx-pricing-table-button { + padding: 10px 20px; + border-radius: 5px; +} + +/* End Of Pricing Table Base CSS */ + +/* Post Type Grid Base CSS */ + +.obfx-grid:after { + display: block; + visibility: hidden; + clear: both; + height: 0; + font-size: 0; + content: " "; +} + +.obfx-grid-container { + display: -webkit-flex; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + margin-right: -15px; + margin-left: -15px; + + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.obfx-grid-wrapper { + padding-right: 15px; + padding-left: 15px; +} + +.obfx-grid .obfx-grid-col-image { + display: block; + overflow: hidden; + position: relative; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: 0 0 10px 0; + box-shadow: 0 3px 10px 0 rgba(181,181,181,1); +} + +.obfx-grid .obfx-grid-col-image { + display: inline-block; + width: 100%; + height: 200px; +} + +.obfx-grid .obfx-grid-col-image.obfx-fit-height img { + width: auto; + height: 100%; +} + +.obfx-grid .obfx-grid-col-image img { + display: block; + position: absolute; + top: 50%; + left: 50%; + width: 100%; + max-width: none; + height: auto; + max-height: none; + -webkit-transform: translate(-50%,-50%); + -ms-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); +} + +.obfx-grid .obfx-grid-title, +.obfx-grid .obfx-grid-title a { + margin: 0; + color: #333; + font-size: 24px; + line-height: 1.5; +} + +.obfx-grid-meta { + margin: 0 0 10px 0; +} + +.obfx-grid-meta > span { + margin-right: 10px; + color: #999; + font-size: 14px; +} + +.obfx-grid-meta > span:last-of-type { + margin-right: 0; +} + +.obfx-grid-meta .fa { + margin-right: 7px; +} + +.obfx-grid-meta a { + color: #999; + text-decoration: none; +} + +.obfx-grid-meta a:hover, +.obfx-grid-meta a:focus { + color: inherit; + text-decoration: underline; +} + +.obfx-grid-categories-item:after, +.obfx-grid-tags-item:after { + content: ", "; +} + +.obfx-grid-categories-item:last-of-type:after, +.obfx-grid-tags-item:last-of-type:after { + display: none; + content: ""; +} + +.obfx-grid-content { + margin: 0 0 10px 0; + color: #555; + font-size: 16px; + line-height: 1.5; +} + +.obfx-grid-footer a { + display: inline-block; + color: #333; + font-size: 14px; + font-weight: 700; +} + +.obfx-grid-container.obfx-grid-style-list .obfx-grid-col { + display: -webkit-flex; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.obfx-grid-container.obfx-grid-style-list .obfx-grid-col-image { + width: 40%; + margin-bottom: 0; +} + +.obfx-grid-container.obfx-grid-style-list .obfx-grid-col-content { + width: 60%; + padding-left: 15px; +} + +.obfx-grid-container.obfx-grid-style-list .obfx-grid-col.obfx-no-image .obfx-grid-col-content { + width: 100%; + padding-left: 0; +} + +.obfx-grid-pagination { + width: 100%; +} + +.obfx-grid-pagination .page-numbers{ + display: inline-block; +} + +.obfx-grid-desktop-1 .obfx-grid-wrapper { + width: 100%; +} + +.obfx-grid-desktop-2 .obfx-grid-wrapper { + width: 50%; +} + +.obfx-grid-desktop-3 .obfx-grid-wrapper { + width: 33.333%; +} + +.obfx-grid-desktop-4 .obfx-grid-wrapper { + width: 25%; +} + +.obfx-grid-desktop-5 .obfx-grid-wrapper { + width: 20%; +} + +@media (max-width: 992px) { + .obfx-grid-tablet-1 .obfx-grid-wrapper { + width: 100%; + } + + .obfx-grid-tablet-2 .obfx-grid-wrapper { + width: 50%; + } + + .obfx-grid-tablet-3 .obfx-grid-wrapper { + width: 33.333%; + } + + .obfx-grid-tablet-4 .obfx-grid-wrapper { + width: 25%; + } + + .obfx-grid-tablet-5 .obfx-grid-wrapper { + width: 20%; + } +} + +@media (max-width: 767px) { + .obfx-grid-mobile-1 .obfx-grid-wrapper { + width: 100%; + } + + .obfx-grid-mobile-2 .obfx-grid-wrapper { + width: 50%; + } + + .obfx-grid-mobile-3 .obfx-grid-wrapper { + width: 33.333%; + } + + .obfx-grid-mobile-4 .obfx-grid-wrapper { + width: 25%; + } + + .obfx-grid-mobile-5 .obfx-grid-wrapper { + width: 20%; + } + + .obfx-grid-container.obfx-grid-style-list .obfx-grid-col-image, + .obfx-grid-container.obfx-grid-style-list .obfx-grid-col-content{ + width: 100%; + } +} + +/* End Of Post Type Grid Base CSS */ + +.obfx-service-box { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.obfx-position-left .obfx-service-box { + flex-direction: row; + + -webkit-box-direction: normal; + -webkit-box-orient: horizontal; + -webkit-flex-direction: row; + -ms-flex-direction: row; +} + +.obfx-position-right .obfx-service-box { + flex-direction: row-reverse; + + -webkit-box-direction: reverse; + -webkit-box-orient: horizontal; + -webkit-flex-direction: row-reverse; + -ms-flex-direction: row-reverse; +} + +.obfx-position-top .obfx-service-box { + flex-direction: column; + + -webkit-box-direction: normal; + -webkit-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; +} + +.obfx-service-box .obfx-service-box-content .obfx-service-title, +.obfx-service-box .obfx-service-box-content .obfx-service-text { + margin: 0; +} + + +/** passed from eaw.css **/ + +/* + * Elementor CSS support + */ + +.eaw-product-section .section-title { + margin-bottom: 20px; +} + +.elementor-widget-wp-widget-eaw-recent-posts h5, +.elementor-widget-wp-widget-eaw-recent-posts-plus h5 { + font-size: 1.75rem; + line-height: 1.75; + text-align: center; +} + +.eaw-recent-posts, +.eaw-recent-posts-plus { + width: 32.3333%; + padding: 0; + margin: 0; + margin-right: 1.3333%; + float: left; +} + +.eaw-recent-posts:last-child, +.eaw-recent-posts-plus:last-child { + margin-right: 0; +} + +.eaw-recent-posts img { + width: 100%; + height: 250px; + margin: 10px 0; + border-radius: 6px; +} + +.eaw-recent-posts .eaw-content { + padding: 1% 2%; +} + +@media screen and (max-width: 768px) { + .eaw-recent-posts { + width: 48%; + padding: 0; + margin: 0 1%; + } + + .eaw-recent-posts img { + height: 300px; + margin: 0 auto; + } +} + +@media screen and (max-width: 667px) { + .eaw-recent-posts { + width: 100%; + margin: 0; + } + + .eaw-recent-posts img { + height: 300px; + margin: 0 auto; + } +} diff --git a/obfx_modules/elementor-extra-widgets/js/obfx-grid.js b/obfx_modules/elementor-extra-widgets/js/obfx-grid.js new file mode 100644 index 00000000..23b75185 --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/js/obfx-grid.js @@ -0,0 +1,62 @@ +/* global elementor */ +(function ($) { + + $( document ).ready( + function () { + checkImageSize(); + } + ); + + $( window ).resize( + function () { + checkImageSize(); + } + ); + + if ( typeof elementor !== 'undefined' ) { + $( window ).on( + 'elementor/frontend/init', function () { + elementor.hooks.addAction( + 'panel/open_editor/widget/obfx-posts-grid', function ( panel ) { + var $element = panel.$el.find( '.elementor-control-section_grid_image' ); + $element.click( + function () { + panel.$el.find( '.elementor-control-grid_image_height .elementor-control-input-wrapper' ).mouseup( + function () { + checkImageSize(); + } + ); + } + ); + } + ); + } + ); + } + + /** + * Check the container and image size. + */ + function checkImageSize() { + $( '.obfx-grid .obfx-grid-col' ).each( + function () { + var container = $( this ).find( '.obfx-grid-col-image' ), + containerWidth = $( this ).find( '.obfx-grid-col-image' ).width(), + containerHeight = $( this ).find( '.obfx-grid-col-image' ).height(), + imageWidth = $( this ).find( '.obfx-grid-col-image img' ).width(), + imageHeight = $( this ).find( '.obfx-grid-col-image img' ).height(); + + if ( $( this ).find( '.obfx-grid-col-image' ).length > 0 ) { + if ( containerHeight > imageHeight ) { + container.addClass( 'obfx-fit-height' ); + } + + if ( (containerWidth - imageWidth > 2) && container.hasClass( 'obfx-fit-height' ) ) { + container.removeClass( 'obfx-fit-height' ); + } + } + } + ); + } + +})( jQuery ); diff --git a/obfx_modules/elementor-extra-widgets/load.php b/obfx_modules/elementor-extra-widgets/load.php new file mode 100644 index 00000000..f972186e --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/load.php @@ -0,0 +1,11 @@ + true, + ); + + foreach ( get_post_types( $args, 'objects' ) as $post_type ) { + // Check if post type name exists. + if ( ! isset( $post_type->name ) ) { + continue; + } + + // Check if post type label exists. + if ( ! isset( $post_type->label ) ) { + continue; + } + + // Check if post type is excluded. + if ( in_array( $post_type->name, $exclude ) === true ) { + continue; + } + + $options[ $post_type->name ] = $post_type->label; + } + + return $options; + } + + /** + * Get post type categories. + */ + private function grid_get_all_post_type_categories( $post_type ) { + $options = array( 'all' => __( 'All Categories', 'themeisle-companion' ) ); + + if ( $post_type == 'post' ) { + $taxonomy = 'category'; + } elseif ( $post_type == 'product' ) { + $taxonomy = 'product_cat'; + } + + if ( ! empty( $taxonomy ) ) { + // Get categories for post type. + $terms = get_terms( + array( + 'taxonomy' => $taxonomy, + 'hide_empty' => false, + ) + ); + if ( ! empty( $terms ) ) { + foreach ( $terms as $term ) { + if ( isset( $term ) ) { + if ( isset( $term->slug ) && isset( $term->name ) ) { + $options[ $term->slug ] = $term->name; + } + } + } + } + } + + return $options; + } + + /** + * Register Elementor Controls. + */ + protected function register_controls() { + // Content. + $this->grid_options_section(); + $this->grid_image_section(); + $this->grid_title_section(); + $this->grid_meta_section(); + $this->grid_content_section(); + $this->grid_pagination_section(); + // Style. + $this->grid_options_style_section(); + $this->grid_image_style_section(); + $this->grid_title_style_section(); + $this->grid_meta_style_section(); + $this->grid_content_style_section(); + $this->grid_pagination_style_section(); + } + + /** + * Content > Grid. + */ + private function grid_options_section() { + $this->start_controls_section( + 'section_grid', + array( + 'label' => __( 'Grid Options', 'themeisle-companion' ), + ) + ); + + // Post type. + $this->add_control( + 'grid_post_type', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Post Type', 'themeisle-companion' ), + 'default' => 'post', + 'options' => $this->grid_get_all_post_types(), + ) + ); + + // Post categories. + $this->add_control( + 'grid_post_categories', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Category', 'themeisle-companion' ), + 'options' => $this->grid_get_all_post_type_categories( 'post' ), + 'condition' => array( + 'grid_post_type' => 'post', + ), + 'default' => 'all', + ) + ); + + // Product categories. + $this->add_control( + 'grid_product_categories', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Category', 'themeisle-companion' ), + 'options' => $this->grid_get_all_post_type_categories( 'product' ), + 'condition' => array( + 'grid_post_type' => 'product', + ), + ) + ); + + // Style. + $this->add_control( + 'grid_style', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Style', 'themeisle-companion' ), + 'default' => 'grid', + 'options' => array( + 'grid' => __( 'Grid', 'themeisle-companion' ), + 'list' => __( 'List', 'themeisle-companion' ), + ), + ) + ); + + // Items. + $this->add_control( + 'grid_items', + array( + 'type' => Controls_Manager::NUMBER, + 'label' => ' ' . __( 'Items', 'themeisle-companion' ), + 'placeholder' => __( 'How many items?', 'themeisle-companion' ), + 'default' => 6, + ) + ); + + // Columns. + $this->add_responsive_control( + 'grid_columns', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Columns', 'themeisle-companion' ), + 'default' => 3, + 'tablet_default' => 2, + 'mobile_default' => 1, + 'options' => array( + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + ), + ) + ); + + // Order by. + $this->add_control( + 'grid_order_by', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Order by', 'themeisle-companion' ), + 'default' => 'date', + 'options' => array( + 'date' => __( 'Date', 'themeisle-companion' ), + 'title' => __( 'Title', 'themeisle-companion' ), + 'modified' => __( 'Modified date', 'themeisle-companion' ), + 'comment_count' => __( 'Comment count', 'themeisle-companion' ), + 'rand' => __( 'Random', 'themeisle-companion' ), + ), + ) + ); + + //Order type + $this->add_control( + 'grid_order_type', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Order', 'themeisle-companion' ), + 'default' => 'DESC', + 'options' => array( + 'ASC' => __( 'Ascending', 'themeisle-companion' ), + 'DESC' => __( 'Descending', 'themeisle-companion' ), + ), + ) + ); + + // Display pagination. + $this->add_control( + 'grid_pagination', + array( + 'label' => ' ' . __( 'Pagination', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + $this->end_controls_section(); + } + + /** + * Content > Image Options. + */ + private function grid_image_section() { + $this->start_controls_section( + 'section_grid_image', + array( + 'label' => __( 'Image', 'themeisle-companion' ), + ) + ); + + // Hide image. + $this->add_control( + 'grid_image_hide', + array( + 'label' => ' ' . __( 'Hide', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + $available_size = array( 'full' => __( 'Full size', 'themeisle-companion' ) ); + global $_wp_additional_image_sizes; + if ( ! empty( $_wp_additional_image_sizes ) ) { + foreach ( $_wp_additional_image_sizes as $label => $size_data ) { + if ( $size_data['height'] === 0 || $size_data['width'] === 0 ) { + continue; + } + $available_size[ $label ] = $size_data['width'] . ' x ' . $size_data['height']; + } + } + + $this->add_control( + 'grid_image_size', + array( + 'label' => __( 'Image size', 'plugin-domain' ), + 'type' => Controls_Manager::SELECT, + 'options' => array_unique( $available_size ), + ) + ); + + // Image height. + $this->add_responsive_control( + 'grid_image_height', + array( + 'label' => ' ' . __( 'Image height', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 220, + ), + 'range' => array( + 'px' => array( + 'min' => 1, + 'max' => 1000, + 'step' => 1, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col-image' => 'height: {{SIZE}}{{UNIT}};', + ), + ) + ); + + // Image alignment + $this->add_control( + 'grid_image_alignment', + array( + 'label' => __( 'Image alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'top', + 'options' => array( + 'top' => __( 'Top', 'themeisle-companion' ), + 'middle' => __( 'Middle', 'themeisle-companion' ), + 'bottom' => __( 'Bottom', 'themeisle-companion' ), + ), + 'condition' => array( + 'grid_style' => 'list', + ), + ) + ); + + + // Image link. + $this->add_control( + 'grid_image_link', + array( + 'label' => ' ' . __( 'Link', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ) + ); + + $this->end_controls_section(); + } + + /** + * Content > Title Options. + */ + private function grid_title_section() { + $this->start_controls_section( + 'section_grid_title', + array( + 'label' => __( 'Title', 'themeisle-companion' ), + ) + ); + + // Hide title. + $this->add_control( + 'grid_title_hide', + array( + 'label' => ' ' . __( 'Hide', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + // Title tag. + $this->add_control( + 'grid_title_tag', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Tag', 'themeisle-companion' ), + 'default' => 'h2', + 'options' => array( + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'span' => 'span', + 'p' => 'p', + 'div' => 'div', + ), + ) + ); + + // Title link. + $this->add_control( + 'grid_title_link', + array( + 'label' => ' ' . __( 'Link', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ) + ); + + $this->end_controls_section(); + } + + /** + * Content > Meta Options. + */ + private function grid_meta_section() { + $this->start_controls_section( + 'section_grid_meta', + array( + 'label' => __( 'Meta', 'themeisle-companion' ), + ) + ); + + // Hide content. + $this->add_control( + 'grid_meta_hide', + array( + 'label' => ' ' . __( 'Hide', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + // Meta. + $this->add_control( + 'grid_meta_display', + array( + 'label' => ' ' . __( 'Display', 'themeisle-companion' ), + 'label_block' => true, + 'type' => Controls_Manager::SELECT2, + 'default' => array( 'author', 'date' ), + 'multiple' => true, + 'options' => array( + 'author' => __( 'Author', 'themeisle-companion' ), + 'date' => __( 'Date', 'themeisle-companion' ), + 'category' => __( 'Category', 'themeisle-companion' ), + 'tags' => __( 'Tags', 'themeisle-companion' ), + 'comments' => __( 'Comments', 'themeisle-companion' ), + ), + ) + ); + + // No. of Categories. + $this->add_control( + 'grid_meta_categories_max', + array( + 'type' => Controls_Manager::NUMBER, + 'label' => __( 'No. of Categories', 'themeisle-companion' ), + 'placeholder' => __( 'How many categories to display?', 'themeisle-companion' ), + 'default' => __( '1', 'themeisle-companion' ), + 'condition' => array( + 'grid_meta_display' => 'category', + ), + ) + ); + + // No. of Tags. + $this->add_control( + 'grid_meta_tags_max', + array( + 'type' => Controls_Manager::NUMBER, + 'label' => __( 'No. of Tags', 'themeisle-companion' ), + 'placeholder' => __( 'How many tags to display?', 'themeisle-companion' ), + 'condition' => array( + 'grid_meta_display' => 'tags', + ), + ) + ); + + // Remove meta icons. + $this->add_control( + 'grid_meta_remove_icons', + array( + 'label' => ' ' . __( 'Remove icons', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + $this->end_controls_section(); + } + + /** + * Content > Content Options. + */ + private function grid_content_section() { + $this->start_controls_section( + 'section_grid_content', + array( + 'label' => __( 'Content', 'themeisle-companion' ), + ) + ); + + // Hide content. + $this->add_control( + 'grid_content_hide', + array( + 'label' => ' ' . __( 'Hide', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + // Show full content. + $this->add_control( + 'grid_content_full_post', + array( + 'label' => __( 'Show full content', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ) + ); + + // Length. + $this->add_control( + 'grid_content_length', + array( + 'type' => Controls_Manager::NUMBER, + 'label' => ' ' . __( 'Length (words)', 'themeisle-companion' ), + 'placeholder' => __( 'Length of content (words)', 'themeisle-companion' ), + 'default' => 30, + 'condition' => array( + 'grid_content_full_post!' => 'yes', + ), + ) + ); + + // Price. + $this->add_control( + 'grid_content_price', + array( + 'label' => ' ' . __( 'Price', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => array( + 'section_grid.grid_post_type' => 'product', + ), + ) + ); + + // Read more button hide. + $this->add_control( + 'grid_content_default_btn', + array( + 'label' => ' ' . __( 'Button', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'condition' => array( + 'section_grid.grid_post_type!' => 'product', + ), + ) + ); + + // Default button text. + $this->add_control( + 'grid_content_default_btn_text', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Button text', 'themeisle-companion' ), + 'placeholder' => __( 'Read more', 'themeisle-companion' ), + 'default' => __( 'Read more', 'themeisle-companion' ), + 'condition' => array( + 'grid_content_default_btn!' => array( '', 'no' ), + 'section_grid.grid_post_type!' => 'product', + ), + ) + ); + + // Add to cart button hide. + $this->add_control( + 'grid_content_product_btn', + array( + 'label' => ' ' . __( 'Button', 'themeisle-companion' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => array( + 'section_grid.grid_post_type' => 'product', + ), + ) + ); + + // Button alignment. + $this->add_responsive_control( + 'grid_content_btn_alignment', + array( + 'label' => __( 'Button alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-align-right', + ), + 'justify' => array( + 'title' => __( 'Justified', 'themeisle-companion' ), + 'icon' => 'fa fa-align-justify', + ), + ), + 'default' => 'left', + 'tablet_default' => 'left', + 'mobile_default' => 'center', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer' => 'text-align: {{VALUE}};', + ), + 'condition' => array( + 'grid_content_btn!' => '', + ), + ) + ); + + // Content alignment. + $this->add_responsive_control( + 'grid_content_alignment', + array( + 'label' => ' ' . __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'default' => 'left', + 'tablet_default' => 'left', + 'mobile_default' => 'center', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col-content' => 'text-align: {{VALUE}};', + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Content > Pagination Options. + */ + private function grid_pagination_section() { + $this->start_controls_section( + 'section_grid_pagination', + array( + 'label' => __( 'Pagination', 'themeisle-companion' ), + 'condition' => array( + 'section_grid.grid_pagination' => 'yes', + ), + ) + ); + + // Pagination alignment. + $this->add_responsive_control( + 'grid_pagination_alignment', + array( + 'label' => __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'default' => 'center', + 'tablet_default' => 'center', + 'mobile_default' => 'center', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-pagination .pagination' => 'text-align: {{VALUE}};', + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Style > Grid options. + */ + private function grid_options_style_section() { + // Tab. + $this->start_controls_section( + 'section_grid_style', + array( + 'label' => __( 'Grid Options', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + // Columns margin. + $this->add_responsive_control( + 'grid_style_columns_margin', + array( + 'label' => __( 'Columns margin', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 15, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 100, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-wrapper' => 'padding-right: calc( {{SIZE}}{{UNIT}} ); padding-left: calc( {{SIZE}}{{UNIT}} );', + '{{WRAPPER}} .obfx-grid-container' => 'margin-left: calc( -{{SIZE}}{{UNIT}} ); margin-right: calc( -{{SIZE}}{{UNIT}} );', + ), + ) + ); + + // Row margin. + $this->add_responsive_control( + 'grid_style_rows_margin', + array( + 'label' => __( 'Rows margin', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 30, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 100, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-wrapper' => 'padding-bottom: {{SIZE}}{{UNIT}};', + ), + ) + ); + + // Background. + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'grid_style_background', + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-grid', + ) + ); + + // Items options. + $this->add_control( + 'grid_items_style_heading', + array( + 'label' => __( 'Items', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + // Items internal padding. + $this->add_responsive_control( + 'grid_items_style_padding', + array( + 'label' => __( 'Padding', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + // Items border radius. + $this->add_control( + 'grid_items_style_border_radius', + array( + 'label' => __( 'Border Radius', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + // Items box shadow. + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'grid_items_style_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-grid-col', + 'separator' => '', + ) + ); + + // Background for items options. + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'grid_items_style_background', + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-grid-col', + ) + ); + + $this->end_controls_section(); + } + + /** + * Style > Image. + */ + private function grid_image_style_section() { + // Tab. + $this->start_controls_section( + 'section_grid_image_style', + array( + 'label' => __( 'Image', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => array( + 'section_grid_image.grid_image_hide' => '', + ), + ) + ); + + // Image border radius. + $this->add_control( + 'grid_image_style_border_radius', + array( + 'label' => __( 'Border Radius', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col-image' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + 'condition' => array( + 'section_grid_image.grid_image_hide' => '', + ), + ) + ); + + // Image box shadow. + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'grid_image_style_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-grid-col-image', + 'separator' => '', + 'condition' => array( + 'section_grid_image.grid_image_hide' => '', + ), + ) + ); + + // Image margin. + $this->add_responsive_control( + 'grid_image_style_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col-image' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + 'condition' => array( + 'section_grid_image.grid_image_hide' => '', + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Style > Title. + */ + private function grid_title_style_section() { + // Tab. + $this->start_controls_section( + 'section_grid_title_style', + array( + 'label' => __( 'Title', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => array( + 'section_grid_title.grid_title_hide' => '', + ), + ) + ); + + // Title typography. + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'grid_title_style_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-grid .entry-title.obfx-grid-title, {{WRAPPER}} .obfx-grid .entry-title.obfx-grid-title > a', + ) + ); + + // Title color. + $this->add_control( + 'grid_title_style_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid .entry-title.obfx-grid-title' => 'color: {{VALUE}};', + '{{WRAPPER}} .obfx-grid .entry-title.obfx-grid-title > a' => 'color: {{VALUE}};', + ), + ) + ); + + // Title margin. + $this->add_responsive_control( + 'grid_title_style_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-title' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Style > Meta. + */ + private function grid_meta_style_section() { + // Tab. + $this->start_controls_section( + 'section_grid_meta_style', + array( + 'label' => __( 'Meta', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => array( + 'section_grid_meta.grid_meta_hide' => '', + ), + ) + ); + + // Meta typography. + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'grid_meta_style_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-grid-meta > span', + ) + ); + + // Meta color. + $this->add_control( + 'grid_meta_style_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-meta' => 'color: {{VALUE}};', + '{{WRAPPER}} .obfx-grid-meta span' => 'color: {{VALUE}};', + '{{WRAPPER}} .obfx-grid-meta a' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_responsive_control( + 'grid_meta_icon_spacing', + array( + 'label' => __( 'Icons spacing', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 50, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-meta i' => 'margin-right: {{SIZE}}{{UNIT}};', + ), + ) + ); + + // Meta margin. + $this->add_responsive_control( + 'grid_meta_style_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-meta' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Style > Content. + */ + private function grid_content_style_section() { + // Tab. + $this->start_controls_section( + 'section_grid_content_style', + array( + 'label' => __( 'Content', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + // Content typography. + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'grid_content_style_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-grid-content', + 'condition' => array( + 'section_grid_content.grid_content_hide' => '', + ), + ) + ); + + // Content color. + $this->add_control( + 'grid_content_style_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-content' => 'color: {{VALUE}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_hide' => '', + ), + ) + ); + + // Content margin + $this->add_responsive_control( + 'grid_content_style_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-content' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_hide' => '', + ), + ) + ); + + // Heading for price options. + $this->add_control( + 'grid_content_price_style_heading', + array( + 'label' => __( 'Price', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => array( + 'section_grid_content.grid_content_price' => 'yes', + 'section_grid.grid_post_type' => 'product', + ), + ) + ); + + // Price typography. + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'grid_content_price_style_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-grid-price', + 'condition' => array( + 'section_grid_content.grid_content_price' => 'yes', + 'section_grid.grid_post_type' => 'product', + ), + ) + ); + + // Price color. + $this->add_control( + 'grid_content_price_style_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-price' => 'color: {{VALUE}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_price' => 'yes', + 'section_grid.grid_post_type' => 'product', + ), + ) + ); + + // Price bottom margin. + $this->add_responsive_control( + 'grid_content_price_style_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-price' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_price' => 'yes', + 'section_grid.grid_post_type' => 'product', + ), + ) + ); + + // Buttons options. + $this->grid_content_style_button(); + + $this->end_controls_section(); + } + + /** + * Tabs for the Style > Button section. + */ + private function grid_content_style_button() { + // Heading for button options. + $this->add_control( + 'grid_button_style_heading', + array( + 'label' => __( 'Button', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Content typography. + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'grid_button_style_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-grid-footer a', + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + $this->start_controls_tabs( 'grid_button_style' ); + + // Normal tab. + $this->start_controls_tab( + 'grid_button_style_normal', + array( + 'label' => __( 'Normal', 'themeisle-companion' ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Normal text color. + $this->add_control( + 'grid_button_style_normal_text_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Text Color', 'themeisle-companion' ), + 'default' => '#ffffff', + 'separator' => '', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer a' => 'color: {{VALUE}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Normal background color. + $this->add_control( + 'grid_button_style_normal_bg_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Background Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'separator' => '', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer a' => 'background-color: {{VALUE}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Normal box shadow. + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'grid_button_style_normal_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-grid-footer a', + 'separator' => '', + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + $this->end_controls_tab(); + + // Hover tab. + $this->start_controls_tab( + 'grid_button_style_hover', + array( + 'label' => __( 'Hover', 'themeisle-companion' ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Hover text color. + $this->add_control( + 'grid_button_style_hover_text_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Text Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'separator' => '', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer a:hover' => 'color: {{VALUE}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Hover background color. + $this->add_control( + 'grid_button_style_hover_bg_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Background Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'separator' => '', + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer a:hover' => 'background-color: {{VALUE}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Hover box shadow. + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'grid_button_style_hover_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-grid-footer a:hover', + 'separator' => '', + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + // Button padding. + $this->add_control( + 'grid_button_style_padding', + array( + 'label' => __( 'Button padding', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer a' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + + // Button border radius. + $this->add_control( + 'grid_button_style_border_radius', + array( + 'label' => __( 'Button border radius', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-footer a' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + 'condition' => array( + 'section_grid_content.grid_content_default_btn!' => '', + 'section_grid_content.grid_content_product_btn!' => '', + ), + ) + ); + } + + /** + * Style > Pagination. + */ + private function grid_pagination_style_section() { + // Tab. + $this->start_controls_section( + 'section_grid_pagination_style', + array( + 'label' => __( 'Pagination', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => array( + 'section_grid.grid_pagination' => 'yes', + ), + ) + ); + + // Image margin. + $this->add_responsive_control( + 'grid_pagination_style_margin', + array( + 'label' => __( 'Margin', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-pagination .pagination' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Render function to output the post type grid. + */ + protected function render() { + // Get settings. + $settings = $this->get_settings(); + + // Output. + echo '
'; + echo '
'; + + // Arguments for query. + $args = array(); + + // Display only published posts. + $args['post_status'] = 'publish'; + + // Ignore sticky posts. + $args['ignore_sticky_posts'] = 1; + + // Check if post type exists. + if ( ! empty( $settings['grid_post_type'] ) && post_type_exists( $settings['grid_post_type'] ) ) { + $args['post_type'] = $settings['grid_post_type']; + } + + // Display posts in category. + if ( ! empty( $settings['grid_post_categories'] ) && $settings['grid_post_categories'] !== 'all' && $settings['grid_post_type'] == 'post' ) { + $args['category_name'] = $settings['grid_post_categories']; + } + + // Display products in category. + if ( ! empty( $settings['grid_product_categories'] ) && $settings['grid_product_categories'] !== 'all' && $settings['grid_post_type'] === 'product' ) { + $args['tax_query'] = array( + 'relation' => 'AND', + array( + 'taxonomy' => 'product_cat', + 'field' => 'slug', + 'terms' => $settings['grid_product_categories'], + ), + ); + } + + // Items to display. + if ( ! empty( $settings['grid_items'] ) && intval( $settings['grid_items'] ) == $settings['grid_items'] ) { + $args['posts_per_page'] = $settings['grid_items']; + } + + // Order by. + if ( ! empty( $settings['grid_order_by'] ) ) { + $args['orderby'] = $settings['grid_order_by']; + } + + // Order type + if ( ! empty( $settings['grid_order_type'] ) ) { + $args['order'] = $settings['grid_order_type']; + } + + // Pagination. + if ( ! empty( $settings['grid_pagination'] ) ) { + $paged = get_query_var( 'paged' ); + if ( empty( $paged ) ) { + $paged = get_query_var( 'page' ); + } + $args['paged'] = $paged; + } + + // Query. + $query = new \WP_Query( $args ); + + // Query results. + if ( $query->have_posts() ) { + while ( $query->have_posts() ) { + $query->the_post(); + + echo '
'; + echo '
'; + + // Image. + $this->renderImage(); + + echo '
'; + // Title. + $this->renderTitle(); + + // Meta. + $this->renderMeta(); + + // Content. + $this->renderContent(); + + // Price. + if ( class_exists( 'WooCommerce' ) ) { + $this->renderPrice(); + } + + // Button. + $this->renderButton(); + + echo '
'; + echo '
'; + echo '
'; + } + + // Pagination. + if ( ! empty( $settings['grid_pagination'] ) ) { ?> +
+ max_num_pages; + $current = max( 1, $paged ); + $paginate_args = array( + 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), + 'format' => '?paged=%#%', + 'current' => $current, + 'total' => $totalpages, + 'show_all' => false, + 'end_size' => 1, + 'mid_size' => 3, + 'prev_next' => true, + 'prev_text' => esc_html__( 'Previous', 'themeisle-companion' ), + 'next_text' => esc_html__( 'Next', 'themeisle-companion' ), + 'type' => 'plain', + 'add_args' => false, + ); + + $pagination = paginate_links( $paginate_args ); + ?> + +
+ '; + + echo '
'; + } + + /** + * Render image of post type. + * + * @return bool + */ + protected function renderImage() { + $settings = $this->get_settings(); + if ( $settings['grid_image_hide'] === 'yes' ) { + return false; + } + + if ( ! has_post_thumbnail() ) { + return false; + } + $image_alignment = $settings['grid_image_alignment']; + $alignment = $image_alignment === 'middle' ? 'style="align-self:center"' : ( $image_alignment === 'bottom' ? 'style="align-self:flex-end"' : '' ); + $a_tag_open = $settings['grid_image_link'] == 'yes' ? '' : ''; + $a_tag_close = ''; + + $image_size = ! empty( $settings['grid_image_size'] ) ? $settings['grid_image_size'] : 'full'; + echo '
'; + echo $a_tag_open; + the_post_thumbnail( + $image_size, + array( + 'class' => 'img-responsive', + 'alt' => get_the_title( get_post_thumbnail_id() ), + ) + ); + echo $a_tag_close; + echo '
'; + + return true; + } + + /** + * Render title of post type. + */ + protected function renderTitle() { + $settings = $this->get_settings(); + + if ( $settings['grid_title_hide'] !== 'yes' ) { + ?> + < class="entry-title obfx-grid-title"> + + + + + + > + get_settings(); + + if ( $settings['grid_meta_hide'] !== 'yes' ) { + if ( ! empty( $settings['grid_meta_display'] ) ) { + ?> +
+ + + + ' : ''; + + echo get_the_author(); + ?> + + + + ' : ''; + echo get_the_date(); + ?> + + renderMetaGridCategories(); + + // Tags + break; + case 'tags': + $this->renderMetaGridTags(); + + // Comments/Reviews + break; + case 'comments': + ?> + + ' : ''; + + if ( $settings['grid_post_type'] == 'product' ) { + echo comments_number( __( 'No reviews', 'themeisle-companion' ), __( '1 review', 'themeisle-companion' ), __( '% reviews', 'themeisle-companion' ) ); + } else { + echo comments_number( __( 'No comments', 'themeisle-companion' ), __( '1 comment', 'themeisle-companion' ), __( '% comments', 'themeisle-companion' ) ); + } + ?> + + + +
+ get_settings(); + $product = wc_get_product( get_the_ID() ); + + if ( $settings['grid_post_type'] == 'product' && $settings['grid_content_price'] == 'yes' ) { + ?> +
+ get_price_html(); + if ( ! empty( $price ) ) { + echo wp_kses( + $price, + array( + 'span' => array( + 'class' => array(), + ), + 'del' => array(), + ) + ); + } + ?> +
+ %s', + esc_url( $product->add_to_cart_url() ), + esc_attr( $product->add_to_cart_text() ), + esc_html( $product->add_to_cart_text() ) + ), + $product + ); + } + + /** + * Render content of post type. + */ + protected function renderContent() { + $settings = $this->get_settings(); + if ( $settings['grid_content_hide'] !== 'yes' ) { + ?> +
+ +
+ get_settings(); + + if ( $settings['grid_post_type'] === 'product' ) { + if ( $settings['grid_content_product_btn'] !== 'yes' ) { + return false; + } + echo ''; + return true; + } else { + if ( $settings['grid_content_default_btn'] !== 'yes' ) { + return false; + } + echo ''; + return true; + } + + return false; + } + + /** + * Display categories in meta section. + */ + protected function renderMetaGridCategories() { + $settings = $this->get_settings(); + $post_type_category = get_the_category(); + $maxCategories = $settings['grid_meta_categories_max'] ? $settings['grid_meta_categories_max'] : '-1'; + $i = 0; // counter + + if ( $post_type_category ) { + ?> + + ' : ''; + + foreach ( $post_type_category as $category ) { + if ( $i == $maxCategories ) { + break; + } + ?> + + + name; ?> + + + + + get_settings(); + $post_type_tags = get_the_tags(); + $maxTags = $settings['grid_meta_tags_max'] ? $settings['grid_meta_tags_max'] : '-1'; + $i = 0; // counter + + if ( $post_type_tags ) { + ?> + + ' : ''; + + foreach ( $post_type_tags as $tag ) { + if ( $i == $maxTags ) { + break; + } + ?> + + + name; ?> + + + + + get_pro_element_name(); + } + + /** + * Get widget icon. + * + * @return string + */ + public function get_icon() { + return 'eicon-insert-image'; + } + + /** + * The Widget Category is filterable, so we need some extra logic to handle it better. + * Premium category is suffixed with `-pro` string. + * + * @return array + */ + public function get_categories() { + $category_args = apply_filters( 'elementor_extra_widgets_category_args', array() ); + $slug = isset( $category_args['slug'] ) ? $category_args['slug'] : 'obfx-elementor-widgets'; + + return array( $slug . '-pro' ); + } + + /** + * Register Elementor Controls. + * + * Because this is just a placeholder widget, we need to output this to the Lite users. + */ + protected function register_controls() { + // Empty controls section the because the widgets settings can't be open. + } + + /** + * A placeholder should not output anything in front-end. + * Only on the editor side will output a message about it's type. + */ + public function render() { + // Empty render function because the widgets can't be added. + } +} diff --git a/obfx_modules/elementor-extra-widgets/widgets/elementor/pricing-table.php b/obfx_modules/elementor-extra-widgets/widgets/elementor/pricing-table.php new file mode 100644 index 00000000..04ae9fa8 --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/widgets/elementor/pricing-table.php @@ -0,0 +1,1161 @@ +plan_title_section(); + + $this->plan_price_tag_section(); + + $this->features_section(); + + $this->button_section(); + + $this->header_style_section(); + + $this->price_tag_style_section(); + + $this->features_style_section(); + + $this->button_style_section(); + } + + /** + * Content > Title section. + */ + private function plan_title_section() { + $this->start_controls_section( + 'section_title', + array( + 'label' => __( 'Plan Title', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'title', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Title', 'themeisle-companion' ), + 'placeholder' => __( 'Title', 'themeisle-companion' ), + 'default' => __( 'Pricing Plan', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'title_tag', + array( + 'type' => Controls_Manager::SELECT, + 'label' => __( 'Title HTML tag', 'themeisle-companion' ), + 'default' => 'h3', + 'options' => array( + 'h1' => __( 'h1', 'themeisle-companion' ), + 'h2' => __( 'h2', 'themeisle-companion' ), + 'h3' => __( 'h3', 'themeisle-companion' ), + 'h4' => __( 'h4', 'themeisle-companion' ), + 'h5' => __( 'h5', 'themeisle-companion' ), + 'h6' => __( 'h6', 'themeisle-companion' ), + 'p' => __( 'p', 'themeisle-companion' ), + ), + ) + ); + + $this->add_control( + 'subtitle', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Subtitle', 'themeisle-companion' ), + 'placeholder' => __( 'Subtitle', 'themeisle-companion' ), + 'default' => __( 'Description', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'subtitle_tag', + array( + 'type' => Controls_Manager::SELECT, + 'label' => __( 'Subtitle HTML Tag', 'themeisle-companion' ), + 'default' => 'p', + 'options' => array( + 'h1' => __( 'h1', 'themeisle-companion' ), + 'h2' => __( 'h2', 'themeisle-companion' ), + 'h3' => __( 'h3', 'themeisle-companion' ), + 'h4' => __( 'h4', 'themeisle-companion' ), + 'h5' => __( 'h5', 'themeisle-companion' ), + 'h6' => __( 'h6', 'themeisle-companion' ), + 'p' => __( 'p', 'themeisle-companion' ), + ), + ) + ); + $this->end_controls_section(); // end section-title + } + + /** + * Content > Price Tag section. + */ + private function plan_price_tag_section() { + $this->start_controls_section( + 'section_price_tag', + array( + 'label' => __( 'Price Tag', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'price_tag_text', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Price', 'themeisle-companion' ), + 'placeholder' => __( 'Price', 'themeisle-companion' ), + 'default' => __( '50', 'themeisle-companion' ), + 'separator' => 'after', + ) + ); + + $this->add_control( + 'price_tag_currency', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Currency', 'themeisle-companion' ), + 'placeholder' => __( 'Currency', 'themeisle-companion' ), + 'default' => __( '$', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'price_tag_currency_position', + array( + 'type' => Controls_Manager::SELECT, + 'label' => __( 'Currency Position', 'themeisle-companion' ), + 'default' => 'left', + 'options' => array( + 'left' => __( 'Before', 'themeisle-companion' ), + 'right' => __( 'After', 'themeisle-companion' ), + ), + ) + ); + + $this->add_control( + 'price_tag_period', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Period', 'themeisle-companion' ), + 'placeholder' => __( '/month', 'themeisle-companion' ), + 'default' => __( '/month', 'themeisle-companion' ), + 'separator' => 'before', + ) + ); + $this->end_controls_section(); // end section-price-tag + } + + /** + * Content > Features section. + */ + private function features_section() { + $this->start_controls_section( + 'section_features', + array( + 'label' => __( 'Features', 'themeisle-companion' ), + ) + ); + + $repeater = new Repeater(); + $repeater->add_control( + 'accent', + array( + 'label' => __( 'Accented Text', 'themeisle-companion' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'description' => __( 'Appears before feature text', 'themeisle-companion' ), + 'default' => __( 'Accent', 'themeisle-companion' ), + ) + ); + + $repeater->add_control( + 'text', + array( + 'label' => __( 'Text', 'themeisle-companion' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'placeholder' => __( 'Plan Features', 'themeisle-companion' ), + 'default' => __( 'Feature', 'themeisle-companion' ), + ) + ); + + $repeater->add_control( + 'feature_icon_new', + array( + 'label' => __( 'Icon', 'themeisle-companion' ), + 'type' => Controls_Manager::ICONS, + 'default' => array( + 'value' => 'fas fa-star', + 'library' => 'solid', + ), + 'fa4compatibility' => 'feature_icon', + ) + ); + + $this->add_control( + 'feature_list', + array( + 'label' => __( 'Plan Features', 'themeisle-companion' ), + 'type' => Controls_Manager::REPEATER, + 'default' => array( + array( + 'accent' => __( 'First', 'themeisle-companion' ), + 'text' => __( 'Feature', 'themeisle-companion' ), + ), + array( + 'accent' => __( 'Second', 'themeisle-companion' ), + 'text' => __( 'Feature', 'themeisle-companion' ), + ), + array( + 'accent' => __( 'Third', 'themeisle-companion' ), + 'text' => __( 'Feature', 'themeisle-companion' ), + ), + ), + 'fields' => $repeater->get_controls(), + 'title_field' => '{{ accent + " " + text }}', + ) + ); + + $this->add_responsive_control( + 'features_align', + array( + 'label' => __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-align-right', + ), + 'justify' => array( + 'title' => __( 'Justified', 'themeisle-companion' ), + 'icon' => 'fa fa-align-justify', + ), + ), + 'default' => 'center', + 'selectors' => array( + '{{WRAPPER}} .obfx-feature-list' => 'text-align: {{VALUE}};', + ), + ) + ); + + $this->end_controls_section(); // end section-features + } + + /** + * Content > Button section. + */ + private function button_section() { + $this->start_controls_section( + 'section_button', + array( + 'label' => __( 'Button', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_text', + array( + 'type' => Controls_Manager::TEXT, + 'label' => __( 'Text', 'themeisle-companion' ), + 'placeholder' => __( 'Buy Now', 'themeisle-companion' ), + 'default' => __( 'Buy Now', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_link', + array( + 'type' => Controls_Manager::URL, + 'label' => __( 'Link', 'themeisle-companion' ), + 'placeholder' => __( 'https://example.com', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_icon_new', + array( + 'type' => Controls_Manager::ICONS, + 'label' => __( 'Icon', 'themeisle-companion' ), + 'fa4compatibility' => 'button_icon', + ) + ); + + $this->add_control( + 'button_icon_align', + array( + 'type' => Controls_Manager::SELECT, + 'label' => __( 'Icon Position', 'themeisle-companion' ), + 'default' => 'left', + 'options' => array( + 'left' => __( 'Before', 'themeisle-companion' ), + 'right' => __( 'After', 'themeisle-companion' ), + ), + 'condition' => array( + 'button_icon!' => '', + ), + ) + ); + + $this->add_control( + 'button_icon_indent', + array( + 'type' => Controls_Manager::SLIDER, + 'label' => __( 'Icon Spacing', 'themeisle-companion' ), + 'range' => array( + 'px' => array( + 'max' => 50, + ), + ), + 'condition' => array( + 'button_icon!' => '', + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-button-icon-align-right i' => 'margin-left: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .obfx-button-icon-align-left i' => 'margin-right: {{SIZE}}{{UNIT}};', + ), + ) + ); + $this->end_controls_section(); // end section_button + } + + /** + * Style > Header section. + */ + private function header_style_section() { + $this->start_controls_section( + 'section_header_style', + array( + 'label' => __( 'Header', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_responsive_control( + 'header_padding', + array( + 'label' => __( 'Header Padding', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-title-wrapper' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'plan_title_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Title Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#464959', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-title' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'plan_title_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-pricing-table-title', + ) + ); + + $this->add_control( + 'plan_subtitle_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Subtitle Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#60647d', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-subtitle' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'plan_subtitle_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-pricing-table-subtitle', + ) + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'heading_section_bg', + 'label' => __( 'Section Background', 'themeisle-companion' ), + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-title-wrapper', + ) + ); + $this->end_controls_section(); // end section_header_style + } + + /** + * Style > Price Tag section. + */ + private function price_tag_style_section() { + $this->start_controls_section( + 'section_price_box', + array( + 'label' => __( 'Price Tag', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_responsive_control( + 'price_box_padding', + array( + 'type' => Controls_Manager::DIMENSIONS, + 'label' => __( 'Price Box Padding', 'themeisle-companion' ), + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-price-wrapper' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'pricing_section_bg', + 'label' => __( 'Section Background', 'themeisle-companion' ), + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-price-wrapper', + ) + ); + + $this->add_control( + 'price_tag_heading_currency', + array( + 'label' => __( 'Currency', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'currency_color', + array( + 'label' => __( 'Currency Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#60647d', + 'selectors' => array( + '{{WRAPPER}} .obfx-price-currency' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'currency_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-price-currency', + ) + ); + + $this->add_control( + 'price_tag_heading_price', + array( + 'label' => __( 'Price', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'price_text_color', + array( + 'label' => __( 'Price Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#60647d', + 'selectors' => array( + '{{WRAPPER}} .obfx-price' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'price_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-price', + ) + ); + + $this->add_control( + 'price_tag_heading_period', + array( + 'label' => __( 'Period', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'period_color', + array( + 'label' => __( 'Period Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#60647d', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-period' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'price_sub_text_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-pricing-period', + ) + ); + $this->end_controls_section(); // end pricing-section + } + + /** + * Style > Features section. + */ + private function features_style_section() { + $this->start_controls_section( + 'section_features_style', + array( + 'label' => __( 'Features', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'features_section_bg', + 'label' => __( 'Section Background', 'themeisle-companion' ), + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-feature-list', + ) + ); + + $this->add_responsive_control( + 'features_box_padding', + array( + 'type' => Controls_Manager::DIMENSIONS, + 'label' => __( 'Features List Padding', 'themeisle-companion' ), + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-feature-list' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'features_accented_heading', + array( + 'label' => __( 'Accented', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'features_accented_text_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Accented Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#60647d', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-accented' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'features_accented_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-pricing-table-accented', + ) + ); + + $this->add_control( + 'features_features_heading', + array( + 'label' => __( 'Features', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'features_text_color', + array( + 'label' => __( 'Features Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#b1b3c0', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-feature' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'features_features_typography', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + 'selector' => '{{WRAPPER}} .obfx-pricing-table-feature', + ) + ); + + $this->add_control( + 'features_icons_heading', + array( + 'label' => __( 'Icons', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'features_icon_color', + array( + 'label' => __( 'Icon Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#b1b3c0', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-feature-icon' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_responsive_control( + 'features_icon_size', + array( + 'type' => Controls_Manager::SLIDER, + 'label' => __( 'Icon Size', 'themeisle-companion' ), + 'default' => array( + 'size' => 16, + ), + 'range' => array( + 'px' => array( + 'max' => 100, + ), + ), + 'selectors' => array( + '{{WRAPPER}} i.obfx-pricing-table-feature-icon' => 'font-size: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} img.obfx-pricing-table-feature-icon' => 'width: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'features_icon_indent', + array( + 'type' => Controls_Manager::SLIDER, + 'label' => __( 'Icon Spacing', 'themeisle-companion' ), + 'default' => array( + 'size' => 5, + ), + 'range' => array( + 'px' => array( + 'max' => 50, + ), + ), + 'selectors' => array( + '{{WRAPPER}} i.obfx-pricing-table-feature-icon' => 'margin-right: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->end_controls_section(); // end section_features_style + } + + /** + * Style > Button section. + */ + private function button_style_section() { + $this->start_controls_section( + 'section_button_style', + array( + 'label' => __( 'Button', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'button_section_bg', + 'label' => __( 'Section Background', 'themeisle-companion' ), + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-pricing-table-button-wrapper', + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'typography', + 'label' => __( 'Typography', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ), + 'selector' => '{{WRAPPER}} .obfx-pricing-table-button-wrapper', + ) + ); + + $this->add_control( + 'border_radius', + array( + 'label' => __( 'Border Radius', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'text_padding', + array( + 'label' => __( 'Padding', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', 'em', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->add_responsive_control( + 'button_icon_size', + array( + 'type' => Controls_Manager::SLIDER, + 'label' => __( 'Icon Size', 'themeisle-companion' ), + 'default' => array( + 'size' => 16, + ), + 'range' => array( + 'px' => array( + 'max' => 100, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button-wrapper i' => 'font-size: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .obfx-pricing-table-button-wrapper img' => 'width: {{SIZE}}{{UNIT}};', + ), + ) + ); + + // Add the tabbed control. + $this->tabbed_button_controls(); + + $this->end_controls_section(); // end section_button_style + } + + /** + * Tabs for the Style > Button section. + */ + private function tabbed_button_controls() { + $this->start_controls_tabs( 'tabs_background' ); + + $this->start_controls_tab( + 'tab_background_normal', + array( + 'label' => __( 'Normal', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_text_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Text Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#fff', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button' => 'color: {{VALUE}};', + ), + ) + ); + $this->add_control( + 'button_bg_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Background Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#93c64f', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'button_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-pricing-table-button', + 'separator' => '', + ) + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_background_hover', + array( + 'label' => __( 'Hover', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'button_hover_text_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Text Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#fff', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button:hover' => 'color: {{VALUE}};', + ), + ) + ); + $this->add_control( + 'button_hover_bg_color', + array( + 'type' => Controls_Manager::COLOR, + 'label' => __( 'Background Color', 'themeisle-companion' ), + 'global' => array( + 'default' => Global_Colors::COLOR_PRIMARY, + ), + 'default' => '#74c600', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button:hover' => 'background-color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'button_hover_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-pricing-table-button:hover', + 'separator' => '', + ) + ); + + $this->add_control( + 'background_hover_transition', + array( + 'label' => __( 'Transition Duration', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 0.3, + ), + 'range' => array( + 'px' => array( + 'max' => 3, + 'step' => 0.1, + ), + ), + 'render_type' => 'ui', + 'selectors' => array( + '{{WRAPPER}} .obfx-pricing-table-button' => 'transition: all {{SIZE}}s ease;', + ), + ) + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + } + + /** + * Render function to output the pricing table. + */ + protected function render() { + $settings = $this->get_settings(); + + $this->add_render_attribute( 'title', 'class', 'obfx-pricing-table-title' ); + $this->add_render_attribute( 'subtitle', 'class', 'obfx-pricing-table-subtitle' ); + $this->add_render_attribute( 'button', 'class', 'obfx-pricing-table-button' ); + // $this->add_render_attribute( 'button_icon', 'class', $settings['button_icon'] ); + $this->add_render_attribute( 'button_icon_align', 'class', 'obfx-button-icon-align-' . $settings['button_icon_align'] ); + if ( ! empty( $settings['button_link']['url'] ) ) { + $this->add_render_attribute( 'button', 'href', $settings['button_link']['url'] ); + + if ( ! empty( $settings['button_link']['is_external'] ) ) { + $this->add_render_attribute( 'button', 'target', '_blank' ); + } + if ( ! empty( $settings['button_link']['nofollow'] ) ) { + $this->add_render_attribute( 'button', 'rel', 'nofollow' ); + } + } + + $output = ''; + + $output .= '
'; + + if ( ! empty( $settings['title'] ) || ! empty( $settings['subtitle'] ) ) { + $output .= '
'; + if ( ! empty( $settings['title'] ) ) { + // Start of title tag. + $output .= '<' . esc_html( $settings['title_tag'] ) . ' ' . $this->get_render_attribute_string( 'title' ) . '>'; + + // Title string. + $output .= esc_html( $settings['title'] ); + + // End of title tag. + $output .= ''; + } + if ( ! empty( $settings['subtitle'] ) ) { + // Start of subtitle tag. + $output .= '<' . esc_html( $settings['subtitle_tag'] ) . ' ' . $this->get_render_attribute_string( 'subtitle' ) . '>'; + + // Subtitle string. + $output .= esc_html( $settings['subtitle'] ); + + // End of subtitle tag. + $output .= ''; + + } + + $output .= '
'; + } + + if ( ! empty( $settings['price_tag_text'] ) || ! empty( $settings['price_tag_currency'] ) || ! empty( $settings['price_tag_period'] ) ) { + $output .= '
'; + + if ( ! empty( $settings['price_tag_currency'] ) && ( $settings['price_tag_currency_position'] == 'left' ) ) { + $output .= '' . esc_html( $settings['price_tag_currency'] ) . ''; + } + + if ( ( isset( $settings['price_tag_text'] ) && $settings['price_tag_text'] === '0' ) || ! empty( $settings['price_tag_text'] ) ) { + $output .= '' . esc_html( $settings['price_tag_text'] ) . ''; + } + + if ( ! empty( $settings['price_tag_currency'] ) && ( $settings['price_tag_currency_position'] == 'right' ) ) { + $output .= '' . esc_html( $settings['price_tag_currency'] ) . ''; + } + + if ( ! empty( $settings['price_tag_period'] ) ) { + $output .= '' . esc_html( $settings['price_tag_period'] ) . ''; + } + + $output .= '
'; + } + + if ( count( $settings['feature_list'] ) ) { + $output .= ''; + } + + if ( ! empty( $settings['button_text'] ) ) { + $output .= ' '; + + } + $output .= '
'; + + echo $output; + } + + private function display_button_icon( $settings ) { + $output = ''; + if ( empty( $settings['button_icon'] ) || isset( $settings['__fa4_migrated']['button_icon_new'] ) ) { + if ( isset( $settings['button_icon_new']['value']['url'] ) ) { + $output .= 'get_render_attribute_string( 'button_icon_align' ) . ' >'; + $output .= '' . esc_attr( get_post_meta( $settings['button_icon_new']['value']['id'], '_wp_attachment_image_alt', true ) ) . ''; + $output .= ''; + } else { + $output .= 'get_render_attribute_string( 'button_icon_align' ) . ' >'; + $output .= ''; + $output .= ''; + } + } else { + $output .= 'get_render_attribute_string( 'button_icon_align' ) . ' >'; + $output .= ''; + $output .= ''; + } + return $output; + } +} + diff --git a/obfx_modules/elementor-extra-widgets/widgets/elementor/services.php b/obfx_modules/elementor-extra-widgets/widgets/elementor/services.php new file mode 100644 index 00000000..e0ce4e30 --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/widgets/elementor/services.php @@ -0,0 +1,709 @@ +services_content(); + $this->style_icon(); + $this->style_grid_options(); + } + + /** + * Content controls + */ + private function services_content() { + $this->start_controls_section( + 'section_content', + array( + 'label' => __( 'Services', 'themeisle-companion' ), + ) + ); + + $repeater = new Repeater(); + $repeater->add_control( + 'type', + array( + 'label' => __( 'Type', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'label_block' => true, + 'default' => 'icon', + 'options' => array( + 'icon' => array( + 'title' => __( 'Icon', 'themeisle-companion' ), + 'icon' => 'fa fa-icons', + ), + 'image' => array( + 'title' => __( 'Image', 'themeisle-companion' ), + 'icon' => 'fa fa-photo', + ), + ), + ) + ); + + $repeater->add_control( + 'title', + array( + 'label' => __( 'Title & Description', 'themeisle-companion' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'default' => __( 'Service Title', 'themeisle-companion' ), + ) + ); + + $repeater->add_control( + 'text', + array( + 'type' => Controls_Manager::TEXTAREA, + 'placeholder' => __( 'Plan Features', 'themeisle-companion' ), + 'default' => __( 'Feature', 'themeisle-companion' ), + ) + ); + + $repeater->add_control( + 'icon_new', + array( + 'label' => __( 'Icon', 'themeisle-companion' ), + 'type' => Controls_Manager::ICONS, + 'default' => array( + 'value' => 'fas fa-gem', + 'library' => 'solid', + ), + 'fa4compatibility' => 'icon', + 'condition' => array( + 'type' => 'icon', + ), + ) + ); + + $repeater->add_control( + 'color', + array( + 'label' => __( 'Icon Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'label_block' => false, + 'default' => '#333333', + 'condition' => array( + 'type' => 'icon', + ), + ) + ); + + $repeater->add_control( + 'image', + array( + 'label' => __( 'Image', 'themeisle-companion' ), + 'type' => Controls_Manager::MEDIA, + 'condition' => array( + 'type' => 'image', + ), + ) + ); + + $repeater->add_control( + 'link', + array( + 'label' => __( 'Link to', 'themeisle-companion' ), + 'type' => Controls_Manager::URL, + 'separator' => 'before', + 'placeholder' => __( 'https://example.com', 'themeisle-companion' ), + ) + ); + + $this->add_control( + 'services_list', + array( + 'label' => __( 'Services', 'themeisle-companion' ), + 'type' => Controls_Manager::REPEATER, + 'default' => array( + array( + 'title' => __( 'Award-Winning​', 'themeisle-companion' ), + 'text' => __( 'Add some text here to describe your services to the page visitors.​', 'themeisle-companion' ), + 'icon_new' => array( + 'value' => 'fas fa-trophy', + 'library' => 'solid', + ), + 'color' => '#333333', + 'type' => 'icon', + ), + array( + 'title' => __( 'Professional​', 'themeisle-companion' ), + 'text' => __( 'Add some text here to describe your services to the page visitors.​', 'themeisle-companion' ), + 'icon_new' => array( + 'value' => 'fas fa-suitcase', + 'library' => 'solid', + ), + 'color' => '#333333', + 'type' => 'icon', + ), + array( + 'title' => __( 'Consulting​', 'themeisle-companion' ), + 'text' => __( 'Add some text here to describe your services to the page visitors.​', 'themeisle-companion' ), + 'icon_new' => array( + 'value' => 'fas fa-handshake', + 'library' => 'solid', + ), + 'color' => '#333333', + 'type' => 'icon', + ), + ), + 'fields' => $repeater->get_controls(), + 'title_field' => '{{title}}', + ) + ); + + $this->add_control( + 'align', + array( + 'label' => ' ' . __( 'Icon Position', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-angle-left', + ), + 'top' => array( + 'title' => __( 'Top', 'themeisle-companion' ), + 'icon' => 'fa fa-angle-up', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-angle-right', + ), + ), + 'default' => 'top', + 'prefix_class' => 'obfx-position-', + 'toggle' => false, + ) + ); + + // Columns. + $this->add_responsive_control( + 'grid_columns', + array( + 'type' => Controls_Manager::SELECT, + 'label' => ' ' . __( 'Columns', 'themeisle-companion' ), + 'default' => 3, + 'tablet_default' => 2, + 'mobile_default' => 1, + 'options' => array( + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + ), + ) + ); + $this->end_controls_section(); + } + + /** + * Icon Style Controls + */ + private function style_icon() { + $this->start_controls_section( + 'section_style_icon', + array( + 'label' => __( 'Icon / Image', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + $this->add_control( + 'icon_space', + array( + 'label' => __( 'Spacing', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 15, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 300, + ), + ), + 'selectors' => array( + '{{WRAPPER}}.obfx-position-right .obfx-icon, {{WRAPPER}}.obfx-position-right .obfx-image' => 'margin-left: {{SIZE}}{{UNIT}};', + '{{WRAPPER}}.obfx-position-left .obfx-icon, {{WRAPPER}}.obfx-position-left .obfx-image' => 'margin-right: {{SIZE}}{{UNIT}};', + '{{WRAPPER}}.obfx-position-top .obfx-icon, {{WRAPPER}}.obfx-position-top .obfx-image' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ), + ) + ); + $this->add_control( + 'icon_size', + array( + 'label' => __( 'Size', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'range' => array( + 'px' => array( + 'min' => 6, + 'max' => 300, + ), + ), + 'default' => array( + 'size' => 35, + ), + 'selectors' => array( + '{{WRAPPER}} i.obfx-icon' => 'font-size: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} img.obfx-icon' => 'width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .obfx-image' => 'max-width: {{SIZE}}{{UNIT}};', + ), + ) + ); + $this->end_controls_section(); + $this->start_controls_section( + 'section_style_content', + array( + 'label' => __( 'Content', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + $this->add_responsive_control( + 'text_align', + array( + 'label' => __( 'Alignment', 'themeisle-companion' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'center', + 'options' => array( + 'left' => array( + 'title' => __( 'Left', 'themeisle-companion' ), + 'icon' => 'fa fa-align-left', + ), + 'center' => array( + 'title' => __( 'Center', 'themeisle-companion' ), + 'icon' => 'fa fa-align-center', + ), + 'right' => array( + 'title' => __( 'Right', 'themeisle-companion' ), + 'icon' => 'fa fa-align-right', + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid .obfx-grid-container .obfx-grid-wrapper .obfx-service-box' => 'text-align: {{VALUE}}; justify-content: {{VALUE}};', + '{{WRAPPER}} .obfx-grid .obfx-grid-container .obfx-grid-wrapper .obfx-service-box .obfx-service-text' => 'text-align: {{VALUE}};', + ), + ) + ); + + $this->add_control( + 'heading_title', + array( + 'label' => __( 'Title', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_responsive_control( + 'title_bottom_space', + array( + 'label' => __( 'Spacing', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 300, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-service-title' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ), + ) + ); + + $this->add_control( + 'title_color', + array( + 'label' => __( 'Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => array( + '{{WRAPPER}} .obfx-service-title' => 'color: {{VALUE}};', + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'title_typography', + 'selector' => '{{WRAPPER}} .obfx-service-title', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ), + ) + ); + + $this->add_control( + 'heading_description', + array( + 'label' => __( 'Description', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + $this->add_control( + 'description_color', + array( + 'label' => __( 'Color', 'themeisle-companion' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => array( + '{{WRAPPER}} .obfx-service-text' => 'color: {{VALUE}};', + ), + 'global' => array( + 'default' => Global_Colors::COLOR_TEXT, + ), + ) + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + array( + 'name' => 'description_typography', + 'selector' => '{{WRAPPER}} .obfx-service-text', + 'global' => array( + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ), + ) + ); + + $this->end_controls_section(); + } + + /** + * Grid Style Controls + */ + private function style_grid_options() { + $this->start_controls_section( + 'section_grid_style', + array( + 'label' => __( 'Grid', 'themeisle-companion' ), + 'tab' => Controls_Manager::TAB_STYLE, + ) + ); + + // Columns margin. + $this->add_control( + 'grid_style_columns_margin', + array( + 'label' => __( 'Columns margin', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 15, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 100, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-wrapper' => 'padding-right: calc( {{SIZE}}{{UNIT}} ); padding-left: calc( {{SIZE}}{{UNIT}} );', + '{{WRAPPER}} .obfx-grid-container' => 'margin-left: calc( -{{SIZE}}{{UNIT}} ); margin-right: calc( -{{SIZE}}{{UNIT}} );', + ), + ) + ); + + // Row margin. + $this->add_control( + 'grid_style_rows_margin', + array( + 'label' => __( 'Rows margin', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 30, + ), + 'range' => array( + 'px' => array( + 'min' => 0, + 'max' => 100, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-wrapper' => 'padding-bottom: {{SIZE}}{{UNIT}};', + ), + ) + ); + + // Background. + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'grid_style_background', + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-grid', + ) + ); + + // Items options. + $this->add_control( + 'grid_items_style_heading', + array( + 'label' => __( 'Items', 'themeisle-companion' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ) + ); + + // Items internal padding. + $this->add_control( + 'grid_items_style_padding', + array( + 'label' => __( 'Padding', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + // Items border radius. + $this->add_control( + 'grid_items_style_border_radius', + array( + 'label' => __( 'Border Radius', 'themeisle-companion' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => array( 'px', '%' ), + 'selectors' => array( + '{{WRAPPER}} .obfx-grid-col' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ), + ) + ); + + $this->items_style_tabs(); + $this->end_controls_section(); + } + + /** + * Items Style Controls + */ + private function items_style_tabs() { + $this->start_controls_tabs( 'tabs_background' ); + + $this->start_controls_tab( + 'tab_background_normal', + array( + 'label' => __( 'Normal', 'themeisle-companion' ), + ) + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'grid_items_background', + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-service-box', + ) + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'grid_items_box_shadow', + 'selector' => '{{WRAPPER}} .obfx-service-box', + ) + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_background_hover', + array( + 'label' => __( 'Hover', 'themeisle-companion' ), + ) + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + array( + 'name' => 'grid_items_background_hover', + 'types' => array( 'classic', 'gradient' ), + 'selector' => '{{WRAPPER}} .obfx-service-box:hover', + ) + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + array( + 'name' => 'grid_items_box_shadow_hover', + 'selector' => '{{WRAPPER}} .obfx-service-box:hover', + ) + ); + + $this->add_control( + 'hover_transition', + array( + 'label' => __( 'Transition Duration', 'themeisle-companion' ), + 'type' => Controls_Manager::SLIDER, + 'default' => array( + 'size' => 0.3, + ), + 'range' => array( + 'px' => array( + 'max' => 3, + 'step' => 0.1, + ), + ), + 'selectors' => array( + '{{WRAPPER}} .obfx-service-box' => 'transition: all {{SIZE}}s ease;', + ), + ) + ); + $this->end_controls_tab(); + + $this->end_controls_tabs(); + } + + /** + * Render function to output the pricing table. + */ + protected function render() { + $settings = $this->get_settings(); + + echo '
'; + foreach ( $settings['services_list'] as $service ) { + if ( ! empty( $service['link']['url'] ) ) { + $this->add_render_attribute( 'link', 'href', $service['link']['url'] ); + + if ( $service['link']['is_external'] ) { + $this->add_render_attribute( 'link', 'target', '_blank' ); + } + + if ( $service['link']['nofollow'] ) { + $this->add_render_attribute( 'link', 'rel', 'nofollow' ); + } + } ?> +
+ '; + } + ?> +
+ ' . esc_attr( get_post_meta( $service['icon_new']['value']['id'], '_wp_attachment_image_alt', true ) ) . ''; + } else { + echo ''; + } + } else { + echo ''; + } + } elseif ( $service['type'] === 'image' && ! empty( $service['image']['url'] ) ) { + ?> + <?php echo esc_attr( get_post_meta( $service['image']['id'], '_wp_attachment_image_alt', true ) ); ?> + +
+ +

+ +

+ +
+ +
+ '; + } + ?> +
+
'; + } +} diff --git a/obfx_modules/elementor-extra-widgets/widgets/woo/best-products.php b/obfx_modules/elementor-extra-widgets/widgets/woo/best-products.php new file mode 100644 index 00000000..df093371 --- /dev/null +++ b/obfx_modules/elementor-extra-widgets/widgets/woo/best-products.php @@ -0,0 +1,161 @@ + 'woo_best_products', + 'description' => __( 'Woo Best Selling Products - designed for use with the Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'woo-best-products', __( 'Woo Best Selling Products', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'woo_best_products'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + if ( ! $this->is_preview() ) { + self::$cache = wp_cache_get( 'woo_best_products', 'widget' ); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( self::$cache[ $args['widget_id'] ] ) ) { + echo self::$cache[ $args['widget_id'] ]; + + return; + } + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + if ( '' == $title ) { + $title = __( 'Best Sellers', 'themeisle-companion' ); + } + + $limit = ( ! empty( $instance['limit'] ) ) ? absint( $instance['limit'] ) : 4; + if ( '' == $limit ) { + $limit = 4; + } + $columns = ( ! empty( $instance['columns'] ) ) ? absint( $instance['columns'] ) : 4; + + if ( '' == $columns ) { + $columns = 4; + } + + $args = apply_filters( + 'elementor-addon-widgets_product_categories_args', + array_merge( + array( + 'limit' => $limit, + 'columns' => $columns, + 'title' => $title, + 'orderby' => 'date', + 'order' => 'desc', + ), + $args + ) + ); + + ob_start(); + + if ( isset( $args['before_widget'] ) ) { + echo $args['before_widget']; + } + + echo '
'; + + do_action( 'storepage_homepage_before_best_selling_products' ); + echo '

' . wp_kses_post( $args['title'] ) . '

'; + + do_action( 'storepage_homepage_after_best_selling_products_title' ); + echo $this->do_shortcode( + 'best_selling_products', + array( + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + ) + ); + do_action( 'storepage_homepage_after_best_selling_products' ); + + echo '
'; + + if ( isset( $args['after_widget'] ) ) { + echo $args['after_widget']; + } + + if ( ! $this->is_preview() ) { + self::$cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'woo_best_products', self::$cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['limit'] = (int) $new_instance['limit']; + $instance['columns'] = (int) ( $new_instance['columns'] ); + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['woo_best_products'] ) ) { + delete_option( 'woo_best_products' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'woo_best_products', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $limit = isset( $instance['limit'] ) ? absint( $instance['limit'] ) : 4; + $columns = isset( $instance['columns '] ) ? absint( $instance['columns '] ) : 4; ?> +

+ + +

+ +

+ +

+ +

+ + +

+ 'woo_featured_products', + 'description' => __( 'Woo Featured Products - designed for use with the Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'woo-featured-products', __( 'Woo Featured Products', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'woo_featured_products'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'woo_featured_products', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + if ( '' == $title ) { + $title = __( 'Recommended For You', 'themeisle-companion' ); + } + + $limit = ( ! empty( $instance['limit'] ) ) ? absint( $instance['limit'] ) : 4; + if ( '' == $limit ) { + $limit = 4; + } + + $columns = ( ! empty( $instance['columns'] ) ) ? absint( $instance['columns'] ) : 4; + if ( '' == $columns ) { + $columns = 4; + } + + $args = apply_filters( + 'elementor-addon-widgets_product_categories_args', + array_merge( + array( + 'limit' => $limit, + 'columns' => $columns, + 'title' => $title, + 'orderby' => 'date', + 'order' => 'desc', + ), + $args + ) + ); + + if ( isset( $args['before_widget'] ) ) { + echo $args['before_widget']; + } + + echo ''; + + if ( isset( $args['after_widget'] ) ) { + echo $args['after_widget']; + } + + if ( ! $this->is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'woo_featured_products', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['limit'] = (int) $new_instance['limit']; + $instance['columns'] = (int) $new_instance['columns']; + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['woo_featured_products'] ) ) { + delete_option( 'woo_featured_products' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'woo_featured_products', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $limit = isset( $instance['limit'] ) ? absint( $instance['limit'] ) : 4; + $columns = isset( $instance['columns '] ) ? absint( $instance['columns '] ) : 4; ?> +

+ + +

+ +

+ +

+ +

+ +

+ 'woo_popular_products', + 'description' => __( 'Woo Popular Products - designed for use with the Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'woo-popular-products', __( 'Woo Popular Products', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'woo_popular_products'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'woo_popular_products', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + if ( '' == $title ) { + $title = __( 'Fan Favorites', 'themeisle-companion' ); + } + + $limit = ( ! empty( $instance['limit'] ) ) ? absint( $instance['limit'] ) : 4; + if ( '' == $limit ) { + $limit = 4; + } + $columns = ( ! empty( $instance['columns'] ) ) ? absint( $instance['columns'] ) : 4; + + if ( '' == $columns ) { + $columns = 4; + } + + $args = apply_filters( + 'elementor-addon-widgets_product_categories_args', + array_merge( + array( + 'limit' => $limit, + 'columns' => $columns, + 'title' => $title, + 'orderby' => 'date', + 'order' => 'desc', + ), + $args + ) + ); + + if ( isset( $args['before_widget'] ) ) { + echo $args['before_widget']; + } + + // echo ''; + + if ( isset( $args['after_widget'] ) ) { + echo $args['after_widget']; + } + + if ( ! $this->is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'woo_popular_products', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['limit'] = (int) $new_instance['limit']; + $instance['columns'] = (int) ( $new_instance['columns'] ); + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['woo_popular_products'] ) ) { + delete_option( 'woo_popular_products' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'woo_popular_products', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $limit = isset( $instance['limit'] ) ? absint( $instance['limit'] ) : 4; + $columns = isset( $instance['columns '] ) ? absint( $instance['columns '] ) : 4; ?> +

+ + +

+ +

+ +

+ +

+ +

+ 'woo_product_categories', + 'description' => __( 'Woo Product Categories - designed for use with the Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'woo-product-categories', __( 'Woo Product Categories', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'woo_product_categories'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'woo_product_categories', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + if ( '' == $title ) { + $title = __( 'Shop By Categories', 'themeisle-companion' ); + } + + $limit = ( ! empty( $instance['limit'] ) ) ? absint( $instance['limit'] ) : 3; + if ( '' == $limit ) { + $limit = 3; + } + $columns = ( ! empty( $instance['columns'] ) ) ? absint( $instance['columns'] ) : 3; + + if ( '' == $columns ) { + $columns = 3; + } + + $args = apply_filters( + 'eaw_product_categories_args', + array_merge( + array( + 'limit' => $limit, + 'columns' => $columns, + 'child_categories' => 0, + 'orderby' => 'name', + 'title' => $title, + ), + $args + ) + ); + + if ( isset( $args['before_widget'] ) ) { + echo $args['before_widget']; + } + + // echo '
'; + echo '
'; + + do_action( 'storepage_homepage_before_product_categories' ); + + echo '

' . wp_kses_post( $args['title'] ) . '

'; + + do_action( 'storepage_homepage_after_product_categories_title' ); + + echo $this->do_shortcode( + 'product_categories', + array( + 'number' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'parent' => esc_attr( $args['child_categories'] ), + ) + ); + + do_action( 'storepage_homepage_after_product_categories' ); + + echo '
'; + // echo '
'; + + if ( isset( $args['after_widget'] ) ) { + echo $args['after_widget']; + } + + if ( ! $this->is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'woo_product_categories', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['limit'] = (int) $new_instance['limit']; + $instance['columns'] = (int) ( $new_instance['columns'] ); + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['woo_product_categories'] ) ) { + delete_option( 'woo_product_categories' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'woo_product_categories', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $limit = isset( $instance['limit'] ) ? absint( $instance['limit'] ) : 3; + $columns = isset( $instance['columns '] ) ? absint( $instance['columns '] ) : 3; ?> +

+ + +

+ +

+ +

+ +

+ +

+ 'woo_recent_products', + 'description' => __( 'Woo Recent Products - designed for use with the Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'woo-recent-products', __( 'Woo Recent Products', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'woo_recent_products'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'woo_recent_products', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + if ( '' == $title ) { + $title = __( 'New In', 'themeisle-companion' ); + } + + $limit = ( ! empty( $instance['limit'] ) ) ? absint( $instance['limit'] ) : 4; + if ( '' == $limit ) { + $limit = 4; + } + $columns = ( ! empty( $instance['columns'] ) ) ? absint( $instance['columns'] ) : 4; + + if ( '' == $columns ) { + $columns = 4; + } + + $args = apply_filters( + 'elementor-addon-widgets_product_categories_args', + array_merge( + array( + 'limit' => $limit, + 'columns' => $columns, + 'title' => $title, + ), + $args + ) + ); + + if ( isset( $args['before_widget'] ) ) { + echo $args['before_widget']; + } + + // echo '
'; + echo '
'; + + do_action( 'elementor-addon-widgets_homepage_before_recent_products' ); + + echo '

' . wp_kses_post( $args['title'] ) . '

'; + + do_action( 'elementor-addon-widgets_homepage_after_recent_products_title' ); + + echo $this->do_shortcode( + 'recent_products', + array( + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + ) + ); + + do_action( 'elementor-addon-widgets_homepage_after_recent_products' ); + + echo '
'; + // echo '
'; + + if ( isset( $args['after_widget'] ) ) { + echo $args['after_widget']; + } + + if ( ! $this->is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'woo_recent_products', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['limit'] = (int) $new_instance['limit']; + $instance['columns'] = (int) ( $new_instance['columns'] ); + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['woo_recent_products'] ) ) { + delete_option( 'woo_recent_products' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'woo_recent_products', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $limit = isset( $instance['limit'] ) ? absint( $instance['limit'] ) : 4; + $columns = isset( $instance['columns '] ) ? absint( $instance['columns '] ) : 4; ?> +

+ + +

+ +

+ +

+ +

+ +

+ 'woo_sale_products', + 'description' => __( 'Woo On Sale Products - designed for use with the Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'woo-sale-products', __( 'Woo On Sale Products', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'woo_sale_products'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'woo_sale_products', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + if ( '' == $title ) { + $title = __( 'On Sale', 'themeisle-companion' ); + } + + $limit = ( ! empty( $instance['limit'] ) ) ? absint( $instance['limit'] ) : 4; + if ( '' == $limit ) { + $limit = 4; + } + $columns = ( ! empty( $instance['columns'] ) ) ? absint( $instance['columns'] ) : 4; + + if ( '' == $columns ) { + $columns = 4; + } + + $args = apply_filters( + 'elementor-addon-widgets_product_categories_args', + array_merge( + array( + 'limit' => $limit, + 'columns' => $columns, + 'title' => $title, + ), + $args + ) + ); + + if ( isset( $args['before_widget'] ) ) { + echo $args['before_widget']; + } + + // echo '
'; + echo '
'; + + do_action( 'storepage_homepage_before_on_sale_products' ); + + echo '

' . wp_kses_post( $args['title'] ) . '

'; + + do_action( 'storepage_homepage_after_on_sale_products_title' ); + + echo $this->do_shortcode( + 'sale_products', + array( + 'limit' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + ) + ); + + do_action( 'storepage_homepage_after_on_sale_products' ); + + echo '
'; + // echo '
'; + + if ( isset( $args['after_widget'] ) ) { + echo $args['after_widget']; + } + + if ( ! $this->is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'woo_sale_products', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['limit'] = (int) $new_instance['limit']; + $instance['columns'] = (int) ( $new_instance['columns'] ); + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['woo_sale_products'] ) ) { + delete_option( 'woo_sale_products' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'woo_sale_products', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $limit = isset( $instance['limit'] ) ? absint( $instance['limit'] ) : 4; + $columns = isset( $instance['columns '] ) ? absint( $instance['columns '] ) : 4; ?> +

+ + +

+ +

+ +

+ +

+ + +

+ 'widget_recent_posts_plus', + 'description' => __( 'Recent posts with featured image - ideal for use with Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'eaw-recent-posts-plus', __( 'EAW: Elementor Posts By Category', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'widget_recent_entries_plus'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'widget_recent_posts_plus', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + $number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 3; + if ( ! $number ) { + $number = 3; + } + + $category = isset( $instance['category'] ) ? $instance['category'] : ''; + + $show_excerpt = isset( $instance['show_excerpt'] ) ? $instance['show_excerpt'] : false; + $excerptcount = ( ! empty( $instance['excerptcount'] ) ) ? absint( $instance['excerptcount'] ) : 20; + + if ( '' == $excerptcount || '0' == $excerptcount ) { + $excerptcount = 20; + } + + $eawp = new WP_Query( + apply_filters( + 'eaw_widget_posts_plus_args', + array( + 'posts_per_page' => $number, + 'cat' => $category, + 'no_found_rows' => true, + 'post_status' => 'publish', + 'ignore_sticky_posts' => true, + ) + ) + ); + + if ( $eawp->have_posts() ) { + + echo $args['before_widget']; + if ( $title ) { + echo $args['before_title'] . $title . $args['after_title']; + } + while ( $eawp->have_posts() ) : + $eawp->the_post(); ?> +
+ +
+

+

+

+ +

+
+
+ is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'widget_recent_posts_plus', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['number'] = (int) $new_instance['number']; + $instance['category'] = wp_strip_all_tags( $new_instance['category'] ); + $instance['excerptcount'] = (int) ( $new_instance['excerptcount'] ); + $instance['show_excerpt'] = isset( $new_instance['show_excerpt'] ) ? (bool) $new_instance['show_excerpt'] : false; + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['widget_recent_entries_plus'] ) ) { + delete_option( 'widget_recent_entries_plus' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'widget_recent_posts_plus', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 3; + $excerptcount = isset( $instance['excerptcount '] ) ? absint( $instance['excerptcount '] ) : 20; + $show_excerpt = isset( $instance['show_excerpt'] ) ? (bool) $instance['show_excerpt'] : false; + $category = isset( $instance['category'] ) ? $instance['category'] : ''; + ?> +

+ + +

+ +

+ +

+ +

+ + 'title', + 'hide_empty' => false, + 'name' => $this->get_field_name( 'category' ), + 'id' => 'rpjc_widget_cat_recent_posts_category', + 'class' => 'widefat', + 'selected' => $category, + ) + ); + ?> +

+ +

+ id="get_field_id( 'show_excerpt' ); ?>" + name="get_field_name( 'show_excerpt' ); ?>"/> + +

+ +

+ +

+ 'widget_recent_posts', + 'description' => __( 'Recent posts with featured image - ideal for use with Elementor Page Builder plugin', 'themeisle-companion' ), + 'customize_selective_refresh' => true, + ); + + parent::__construct( 'eaw-recent-posts', __( 'EAW: Elementor Recent Posts', 'themeisle-companion' ), $widget_ops ); + $this->alt_option_name = 'widget_recent_entries'; + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + $cache = array(); + if ( ! $this->is_preview() ) { + $cache = wp_cache_get( 'widget_recent_posts', 'widget' ); + } + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( ! isset( $args['widget_id'] ) ) { + $args['widget_id'] = $this->id; + } + + if ( isset( $cache[ $args['widget_id'] ] ) ) { + echo $cache[ $args['widget_id'] ]; + + return; + } + + ob_start(); + + $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; + $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); + + $number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 3; + if ( ! $number ) { + $number = 3; + } + $show_excerpt = isset( $instance['show_excerpt'] ) ? $instance['show_excerpt'] : false; + $excerptcount = ( ! empty( $instance['excerptcount'] ) ) ? absint( $instance['excerptcount'] ) : 20; + + if ( '' == $excerptcount || '0' == $excerptcount ) { + $excerptcount = 20; + } + + $eawp = new WP_Query( + apply_filters( + 'eaw_widget_posts_args', + array( + 'posts_per_page' => $number, + 'no_found_rows' => true, + 'post_status' => 'publish', + 'ignore_sticky_posts' => true, + ) + ) + ); + + if ( $eawp->have_posts() ) { + echo $args['before_widget']; + + if ( $title ) { + echo $args['before_title'] . $title . $args['after_title']; + } + + while ( $eawp->have_posts() ) : + $eawp->the_post(); ?> +
+ +
+

+

+

+ +

+
+
+ is_preview() ) { + $cache[ $args['widget_id'] ] = ob_get_flush(); + wp_cache_set( 'widget_recent_posts', $cache, 'widget' ); + } else { + ob_end_flush(); + } + } + + public function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['number'] = (int) $new_instance['number']; + $instance['excerptcount'] = (int) ( $new_instance['excerptcount'] ); + $instance['show_excerpt'] = isset( $new_instance['show_excerpt'] ) ? (bool) $new_instance['show_excerpt'] : false; + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset( $alloptions['widget_recent_entries'] ) ) { + delete_option( 'widget_recent_entries' ); + } + + return $instance; + } + + /** + * @access public + */ + public function flush_widget_cache() { + wp_cache_delete( 'widget_recent_posts', 'widget' ); + } + + /** + * @param array $instance + */ + public function form( $instance ) { + $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; + $number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 3; + $excerptcount = isset( $instance['excerptcount '] ) ? absint( $instance['excerptcount '] ) : 20; + $show_excerpt = isset( $instance['show_excerpt'] ) ? (bool) $instance['show_excerpt'] : false; + ?> +

+ + +

+ +

+ +

+ +

+ id="get_field_id( 'show_excerpt' ); ?>" + name="get_field_name( 'show_excerpt' ); ?>"/> + +

+ +

+ +

+ name = __( 'Header Footer Scripts', 'themeisle-companion' ); - $this->description = __( 'An easy way to add scripts, such as tracking and analytics scripts, to the header and footer of your website, as well as in the body of your posts and pages.', 'themeisle-companion' ); - $this->meta_controls = array( + $this->name = __( 'Header Footer Scripts', 'themeisle-companion' ); + $this->description = __( 'An easy way to add scripts, such as tracking and analytics scripts, to the header and footer of your website, as well as in the body of your posts and pages.', 'themeisle-companion' ); + $this->meta_controls = array( 'obfx-header-scripts' => array( 'type' => 'textarea', 'label' => __( 'Header scripts', 'themeisle-companion' ), diff --git a/obfx_modules/menu-icons/init.php b/obfx_modules/menu-icons/init.php index 31248bea..60c6534e 100644 --- a/obfx_modules/menu-icons/init.php +++ b/obfx_modules/menu-icons/init.php @@ -42,8 +42,8 @@ public function __construct() { * @access public */ public function set_module_strings() { - $this->name = __( 'Menu Icons', 'themeisle-companion' ); - $this->description = __( 'Module to define menu icons for navigation.', 'themeisle-companion' ); + $this->name = __( 'Menu Icons', 'themeisle-companion' ); + $this->description = __( 'Module to define menu icons for navigation.', 'themeisle-companion' ); } diff --git a/obfx_modules/mystock-import/init.php b/obfx_modules/mystock-import/init.php index 12035adf..416281c3 100644 --- a/obfx_modules/mystock-import/init.php +++ b/obfx_modules/mystock-import/init.php @@ -63,8 +63,8 @@ public function __construct() { * @access public */ public function set_module_strings() { - $this->name = __( 'Mystock Import', 'themeisle-companion' ); - $this->description = __( 'Module to import images directly from', 'themeisle-companion' ) . sprintf( ' mystock.photos', 'https://mystock.photos' ); + $this->name = __( 'Mystock Import', 'themeisle-companion' ); + $this->description = __( 'Module to import images directly from', 'themeisle-companion' ) . sprintf( ' mystock.photos', 'https://mystock.photos' ); } diff --git a/obfx_modules/template-directory/init.php b/obfx_modules/template-directory/init.php index f4606eb4..b867503d 100644 --- a/obfx_modules/template-directory/init.php +++ b/obfx_modules/template-directory/init.php @@ -38,8 +38,8 @@ public function __construct() { * @access public */ public function set_module_strings() { - $this->name = __( 'Template Directory Module', 'themeisle-companion' ); - $this->description = __( 'The awesome template directory is aiming to provide a wide range of templates that you can import straight into your website.', 'themeisle-companion' ); + $this->name = __( 'Template Directory Module', 'themeisle-companion' ); + $this->description = __( 'The awesome template directory is aiming to provide a wide range of templates that you can import straight into your website.', 'themeisle-companion' ); } /** diff --git a/phpcs.xml b/phpcs.xml index 4f536d2e..7e211f27 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -42,6 +42,8 @@ dist/* artifact/* assets/* + obfx_modules/elementor-extra-widgets/ + obfx_modules/content-forms/ \ No newline at end of file