corvée(dépendances) ajoute Carbon Fields

This commit is contained in:
gcch 2024-08-09 18:45:01 +02:00
commit 62368587e5
459 changed files with 72750 additions and 26 deletions

View file

@ -53,7 +53,9 @@
"wpackagist-plugin/woocommerce": "^9.1", "wpackagist-plugin/woocommerce": "^9.1",
"wpackagist-plugin/falcon": "^2.8", "wpackagist-plugin/falcon": "^2.8",
"wpackagist-plugin/polylang": "^3.6", "wpackagist-plugin/polylang": "^3.6",
"wpackagist-plugin/query-monitor": "^3.16" "wpackagist-plugin/query-monitor": "^3.16",
"mnsami/composer-custom-directory-installer": "^2.0",
"htmlburger/carbon-fields": "^3.6"
}, },
"require-dev": { "require-dev": {
"squizlabs/php_codesniffer": "^3.7.1", "squizlabs/php_codesniffer": "^3.7.1",
@ -64,22 +66,18 @@
"preferred-install": "dist", "preferred-install": "dist",
"allow-plugins": { "allow-plugins": {
"composer/installers": true, "composer/installers": true,
"roots/wordpress-core-installer": true "roots/wordpress-core-installer": true,
"mnsami/composer-custom-directory-installer": true
} }
}, },
"minimum-stability": "dev", "minimum-stability": "dev",
"prefer-stable": true, "prefer-stable": true,
"extra": { "extra": {
"installer-paths": { "installer-paths": {
"web/app/mu-plugins/{$name}/": [ "web/vendor/{$vendor}/{$name}": ["htmlburger/carbon-fields"],
"type:wordpress-muplugin" "web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
], "web/app/plugins/{$name}/": ["type:wordpress-plugin"],
"web/app/plugins/{$name}/": [ "web/app/themes/{$name}/": ["type:wordpress-theme"]
"type:wordpress-plugin"
],
"web/app/themes/{$name}/": [
"type:wordpress-theme"
]
}, },
"wordpress-install-dir": "web/wp" "wordpress-install-dir": "web/wp"
}, },

303
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "29554f918bd6b158ebcc9e47012076e1", "content-hash": "028568610be8aa5617070402717dc8a1",
"packages": [ "packages": [
{ {
"name": "composer/installers", "name": "composer/installers",
@ -214,6 +214,202 @@
], ],
"time": "2024-07-20T21:45:45+00:00" "time": "2024-07-20T21:45:45+00:00"
}, },
{
"name": "htmlburger/carbon-fields",
"version": "v3.6.5",
"source": {
"type": "git",
"url": "https://github.com/htmlburger/carbon-fields.git",
"reference": "b18f8e2a2cc4cc976306eb867ad1d740a8e7c1d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/htmlburger/carbon-fields/zipball/b18f8e2a2cc4cc976306eb867ad1d740a8e7c1d9",
"reference": "b18f8e2a2cc4cc976306eb867ad1d740a8e7c1d9",
"shasum": ""
},
"require": {
"php": ">=5.6.20"
},
"require-dev": {
"mockery/mockery": "1.3.6",
"phpunit/phpunit": "7.5.20|9.6.3",
"yoast/phpunit-polyfills": "^1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Carbon_Fields\\": "core/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-only"
],
"authors": [
{
"name": "htmlBurger",
"email": "wordpress@htmlburger.com",
"homepage": "https://htmlburger.com/",
"role": "Developer"
},
{
"name": "Miroslav Mitev",
"email": "mmitev.2create@gmail.com",
"role": "Developer"
},
{
"name": "Atanas Angelov",
"email": "atanas.angelov.dev@gmail.com",
"role": "Developer"
},
{
"name": "Georgi Stoyanov",
"email": "stoyanov.gs@gmail.com",
"role": "Developer"
},
{
"name": "Plamen Kostadinov",
"email": "pkostadinov.2create@gmail.com",
"homepage": "http://plasmen.info/",
"role": "Developer"
},
{
"name": "Stanimir Panchev",
"email": "Stan4omir@gmail.com",
"role": "Developer"
},
{
"name": "Marin Atanasov",
"email": "contact@marinatanasov.com",
"homepage": "http://marinatanasov.com/",
"role": "Developer"
},
{
"name": "Siyan Panayotov",
"homepage": "http://siyanpanayotov.com/",
"role": "Developer"
},
{
"name": "Peter Petrov",
"email": "peter.petrov89@gmail.com",
"role": "Developer"
},
{
"name": "Stanimir Stoyanov",
"email": "stanimir.k.stoyanov@gmail.com",
"role": "Developer"
},
{
"name": "Kaloyan Ivanov",
"email": "kaloyanxivanov@gmail.com",
"homepage": "http://vilepixels.com/",
"role": "Developer"
},
{
"name": "Georgi Popov",
"homepage": "http://magadanski.com/",
"role": "Developer"
},
{
"name": "German Velchev",
"email": "germozy@gmail.com",
"role": "Developer"
},
{
"name": "Rashko Petrov",
"email": "brutalenemy666@gmail.com",
"homepage": "http://errorfactory.com/",
"role": "Developer"
},
{
"name": "Alexander Panayotov",
"email": "alexander.panayotov@gmail.com",
"homepage": "http://alexanderpanayotov.com/",
"role": "Developer"
},
{
"name": "Viktor Vasilev",
"email": "liberalcho@gmail.com",
"role": "Developer"
},
{
"name": "Georgi Georgiev",
"email": "george.georgiev96@gmail.com",
"role": "Developer"
},
{
"name": "Atanas Vasilev",
"email": "atanasvasilev91@gmail.com",
"role": "Developer"
}
],
"description": "WordPress developer-friendly custom fields for post types, taxonomy terms, users, comments, widgets, options and more.",
"homepage": "http://carbonfields.net/",
"support": {
"docs": "http://carbonfields.net/docs/",
"email": "wordpress@htmlburger.com",
"issues": "https://github.com/htmlburger/carbon-fields/issues",
"source": "https://github.com/htmlburger/carbon-fields"
},
"time": "2024-07-31T08:17:38+00:00"
},
{
"name": "mnsami/composer-custom-directory-installer",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/mnsami/composer-custom-directory-installer.git",
"reference": "85f66323978d0b1cb0e6acc7f69b3e7b912f82d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mnsami/composer-custom-directory-installer/zipball/85f66323978d0b1cb0e6acc7f69b3e7b912f82d9",
"reference": "85f66323978d0b1cb0e6acc7f69b3e7b912f82d9",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0",
"php": ">=5.3"
},
"type": "composer-plugin",
"extra": {
"class": [
"Composer\\CustomDirectoryInstaller\\LibraryPlugin",
"Composer\\CustomDirectoryInstaller\\PearPlugin",
"Composer\\CustomDirectoryInstaller\\PluginPlugin"
],
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-0": {
"Composer\\CustomDirectoryInstaller": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mina Nabil Sami",
"email": "mina.nsami@gmail.com"
}
],
"description": "A composer plugin, to help install packages of different types in custom paths.",
"keywords": [
"composer",
"composer-installer",
"composer-plugin"
],
"support": {
"issues": "https://github.com/mnsami/composer-custom-directory-installer/issues",
"source": "https://github.com/mnsami/composer-custom-directory-installer/tree/2.0.0"
},
"time": "2020-08-18T11:00:11+00:00"
},
{ {
"name": "oscarotero/env", "name": "oscarotero/env",
"version": "v2.1.0", "version": "v2.1.0",
@ -1093,6 +1289,82 @@
], ],
"time": "2024-05-31T15:07:36+00:00" "time": "2024-05-31T15:07:36+00:00"
}, },
{
"name": "symfony/polyfill-php81",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "3fb075789fb91f9ad9af537c4012d523085bd5af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af",
"reference": "3fb075789fb91f9ad9af537c4012d523085bd5af",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php81\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-06-19T12:30:46+00:00"
},
{ {
"name": "timber/timber", "name": "timber/timber",
"version": "v2.2.0", "version": "v2.2.0",
@ -1193,16 +1465,16 @@
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v3.10.3", "version": "v3.11.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/Twig.git",
"reference": "67f29781ffafa520b0bbfbd8384674b42db04572" "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572", "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
"reference": "67f29781ffafa520b0bbfbd8384674b42db04572", "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1210,7 +1482,8 @@
"symfony/deprecation-contracts": "^2.5|^3", "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8", "symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3", "symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php80": "^1.22" "symfony/polyfill-php80": "^1.22",
"symfony/polyfill-php81": "^1.29"
}, },
"require-dev": { "require-dev": {
"psr/container": "^1.0|^2.0", "psr/container": "^1.0|^2.0",
@ -1256,7 +1529,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.10.3" "source": "https://github.com/twigphp/Twig/tree/v3.11.0"
}, },
"funding": [ "funding": [
{ {
@ -1268,7 +1541,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-05-16T10:04:27+00:00" "time": "2024-08-08T16:15:16+00:00"
}, },
{ {
"name": "vlucas/phpdotenv", "name": "vlucas/phpdotenv",
@ -1452,12 +1725,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git", "url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "176422aa2c339a0f4e56b92862c67a94e2b584fb" "reference": "fe2777b484817ebbbe50ad685af7525560198c59"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/176422aa2c339a0f4e56b92862c67a94e2b584fb", "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/fe2777b484817ebbbe50ad685af7525560198c59",
"reference": "176422aa2c339a0f4e56b92862c67a94e2b584fb", "reference": "fe2777b484817ebbbe50ad685af7525560198c59",
"shasum": "" "shasum": ""
}, },
"conflict": { "conflict": {
@ -1554,7 +1827,7 @@
"codeigniter4/shield": "<1.0.0.0-beta8", "codeigniter4/shield": "<1.0.0.0-beta8",
"codiad/codiad": "<=2.8.4", "codiad/codiad": "<=2.8.4",
"composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7", "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7",
"concrete5/concrete5": "<=9.3.2", "concrete5/concrete5": "<9.3.3",
"concrete5/core": "<8.5.8|>=9,<9.1", "concrete5/core": "<8.5.8|>=9,<9.1",
"contao-components/mediaelement": ">=2.14.2,<2.21.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1",
"contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
@ -1973,8 +2246,8 @@
"serluck/phpwhois": "<=4.2.6", "serluck/phpwhois": "<=4.2.6",
"sfroemken/url_redirect": "<=1.2.1", "sfroemken/url_redirect": "<=1.2.1",
"sheng/yiicms": "<=1.2", "sheng/yiicms": "<=1.2",
"shopware/core": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", "shopware/core": "<=6.5.8.12|>=6.6,<=6.6.5",
"shopware/platform": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", "shopware/platform": "<=6.5.8.12|>=6.6,<=6.6.5",
"shopware/production": "<=6.3.5.2", "shopware/production": "<=6.3.5.2",
"shopware/shopware": "<=5.7.17", "shopware/shopware": "<=5.7.17",
"shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev",
@ -2259,7 +2532,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-08-05T22:04:39+00:00" "time": "2024-08-08T21:04:55+00:00"
}, },
{ {
"name": "squizlabs/php_codesniffer", "name": "squizlabs/php_codesniffer",

View file

@ -0,0 +1,26 @@
module.exports = {
presets: [
[ '@babel/preset-env', {
modules: false
} ],
[ '@babel/preset-react', {
pragma: 'wp.element.createElement',
pragmaFrag: 'wp.element.Fragment'
} ]
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-syntax-async-generators',
'@babel/plugin-transform-runtime'
],
env: {
production: {
plugins: [
[ '@wordpress/babel-plugin-makepot', {
output: 'languages/carbon-fields-ui.pot'
} ]
]
}
}
};

View file

@ -0,0 +1 @@
extends @wordpress/browserslist-config

View file

@ -0,0 +1,25 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
indent_size = 4
[{package.json,*.yml}]
indent_style = space
indent_size = 2
[composer.json]
indent_style = space
[*.md]
trim_trailing_whitespace = false

View file

@ -0,0 +1,135 @@
module.exports = {
env: {
es6: true,
browser: true
},
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
},
settings: {
react: {
version: '16.4'
}
},
extends: [
'wordpress',
'plugin:wordpress/esnext',
'plugin:react/recommended'
],
plugins: [
'wordpress',
'react'
],
rules: {
'operator-linebreak': [ 'error', 'before' ],
'array-bracket-spacing': [ 'error', 'always' ],
'arrow-parens': [ 'error', 'always' ],
'arrow-spacing': 'error',
'brace-style': [ 'error', '1tbs' ],
'camelcase': [ 'error', { properties: 'never' } ],
'comma-spacing': 'error',
'comma-style': 'error',
'computed-property-spacing': [ 'error', 'always' ],
'dot-notation': 'error',
'eol-last': 'error',
'eqeqeq': 'error',
'func-call-spacing': 'error',
'indent': [ 'error', 'tab', { SwitchCase: 1 } ],
'key-spacing': 'error',
'keyword-spacing': 'error',
'lines-around-comment': 'off',
'no-alert': 'error',
'no-bitwise': 'error',
'no-caller': 'error',
'no-console': 'error',
'no-debugger': 'error',
'no-dupe-args': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-else-return': 'error',
'no-eval': 'error',
'no-extra-semi': 'error',
'no-fallthrough': 'error',
'no-lonely-if': 'error',
'no-mixed-operators': 'error',
'no-mixed-spaces-and-tabs': 'error',
'no-multiple-empty-lines': [ 'error', { max: 1 } ],
'no-multi-spaces': 'error',
'no-multi-str': 'off',
'no-negated-in-lhs': 'error',
'no-nested-ternary': 'error',
'no-redeclare': 'error',
'no-shadow': [ 'error', { hoist: 'never' } ],
'no-undef': 'error',
'no-undef-init': 'error',
'no-unreachable': 'error',
'no-unsafe-negation': 'error',
'no-unused-expressions': 'error',
'no-unused-vars': 'error',
'no-useless-return': 'error',
'no-whitespace-before-property': 'error',
'object-curly-spacing': [ 'error', 'always' ],
'padded-blocks': [ 'error', 'never' ],
'quotes': [ 'error', 'single', { allowTemplateLiterals: true, avoidEscape: true } ],
'quote-props': [ 'error', 'as-needed' ],
'semi': 'error',
'semi-spacing': 'error',
'space-before-blocks': [ 'error', 'always' ],
'space-before-function-paren': [ 'error', {
anonymous: 'never',
named: 'never',
asyncArrow: 'always'
} ],
'space-in-parens': [ 'error', 'always' ],
'space-infix-ops': [ 'error', { int32Hint: false } ],
'space-unary-ops': [ 'error', {
overrides: {
'!': true,
yield: true
},
} ],
'valid-jsdoc': [ 'error', {
prefer: {
arg: 'param',
argument: 'param',
returns: 'return'
},
preferType: {
array: 'Array',
bool: 'boolean',
Boolean: 'boolean',
float: 'number',
Float: 'number',
int: 'number',
integer: 'number',
Integer: 'number',
Number: 'number',
object: 'Object',
String: 'string',
Void: 'void'
},
requireParamDescription: false,
requireReturn: true,
requireReturnDescription: false
} ],
'valid-typeof': 'error',
'yoda': 'off',
'react/display-name': 'off',
'react/jsx-curly-spacing': [ 'error', {
when: 'always',
children: true
} ],
'react/jsx-equals-spacing': 'error',
'react/jsx-indent': [ 'error', 'tab' ],
'react/jsx-indent-props': [ 'error', 'tab' ],
'react/jsx-key': 'error',
'react/jsx-tag-spacing': 'error',
'react/no-children-prop': 'off',
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off'
}
};

View file

@ -0,0 +1,5 @@
module.exports = {
hooks: {
'pre-commit': 'lint-staged'
}
};

View file

@ -0,0 +1,5 @@
module.exports = {
'packages/**/*.js': [
'eslint'
]
};

View file

@ -0,0 +1 @@
lts/*

View file

@ -0,0 +1,58 @@
<?php
/**
* @see https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata#PhpStormAdvancedMetadata-Factorymethods
*/
namespace PHPSTORM_META {
// Carbon_Fields::resolve()
override(
\Carbon_Fields\Carbon_Fields::resolve( 0 ),
map(
[
'container_condition_fulfillable_collection' => \Carbon_Fields\Container\Fulfillable\Fulfillable_Collection::class,
'container_condition_translator_json' => \Carbon_Fields\Container\Fulfillable\Translator\Json_Translator::class,
'container_repository' => \Carbon_Fields\Container\Repository::class,
'containers' => \Carbon_Fields\Pimple\Container::class,
'fields' => \Carbon_Fields\Pimple\Container::class,
'key_toolset' => \Carbon_Fields\Toolset\Key_Toolset::class,
'loader' => \Carbon_Fields\Loader\Loader::class,
'rest_api_decorator' => \Carbon_Fields\REST_API\Decorator::class,
'rest_api_router' => \Carbon_Fields\REST_API\Router::class,
'sidebar_manager' => \Carbon_Fields\Libraries\Sidebar_Manager\Sidebar_Manager::class,
'wp_toolset' => \Carbon_Fields\Toolset\WP_Toolset::class,
/* Events */
'event_emitter' => \Carbon_Fields\Event\Emitter::class,
'event_persistent_listener' => \Carbon_Fields\Event\PersistentListener::class,
'event_single_event_listener' => \Carbon_Fields\Event\SingleEventListener::class,
]
)
);
// Carbon_Fields::service()
override(
\Carbon_Fields\Carbon_Fields::service( 0 ),
map(
[
/* Services */
'legacy_storage' => \Carbon_Fields\Service\Legacy_Storage_Service_v_1_5::class,
'meta_query' => \Carbon_Fields\Service\Meta_Query_Service::class,
'rest_api' => \Carbon_Fields\Service\REST_API_Service::class,
'revisions' => \Carbon_Fields\Service\Revisions_Service::class,
]
)
);
// Pimple
override(
new \Carbon_Fields\Pimple\Container,
map(
[
'container_conditions' => \Carbon_Fields\Pimple\Container::class,
]
)
);
}

View file

@ -0,0 +1,5 @@
module.exports = {
plugins: {
'postcss-preset-env': {}
}
};

View file

@ -0,0 +1,42 @@
# Development environment
This setup is only meant for development use - for production follow [Quickstart](https://carbonfields.net/docs/carbon-fields-quickstart/?crb_version=2-1-0) instead.
1. Setup a blank WordPress installation
1. Add a new `carbon-fields` directory inside your theme of choice and switch to it
1. Fork this repository and clone your fork
1. Run `git checkout development`
1. Run `composer install`
1. Run `npm install` or `yarn install`
1. Run `npm run build` or `yarn run build`
1. Add the following code to the top of your functions.php file:
```php
use Carbon_Fields\Container;
use Carbon_Fields\Field;
add_action( 'carbon_fields_register_fields', 'crb_attach_theme_options' );
function crb_attach_theme_options() {
Container::make( 'theme_options', __( 'Theme Options', 'crb' ) )
->add_fields( array(
Field::make( 'text', 'crb_text', 'Text Field' ),
) );
}
add_action( 'after_setup_theme', 'crb_load' );
function crb_load() {
require_once( 'carbon-fields/vendor/autoload.php' );
\Carbon_Fields\Carbon_Fields::boot();
}
```
# Preparation
1. Make sure your local branches are up to date
1. Always start your contribution branches from the `development` branch
1. If you are making JavaScript contributions, run `npm run start` or `yarn start` to run the dev build task (tracks file changes)
## Pull Request Process
1. Target the `development` branch for pull requests
1. Include a detailed description of your contribution
1. Make sure you follow the current codestyle

View file

@ -0,0 +1,26 @@
## Version
- Carbon Fields:
- WordPress:
- PHP:
## Expected Behavior
_Please enter the expected behavior here_
## Actual Behavior
_Please enter the actual, unexpected behavior here_
## Container definition
```php
// Please add your entire container defintion here so issues
// are easy to reproduce
```
## Steps to Reproduce the Problem
1.
1.
1.
## Comments
_Please add any other comments here_

View file

@ -0,0 +1,24 @@
# Carbon Fields [![Build Status](https://travis-ci.org/htmlburger/carbon-fields.svg?branch=master)](https://travis-ci.org/htmlburger/carbon-fields) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/htmlburger/carbon-fields/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/htmlburger/carbon-fields/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/htmlburger/carbon-fields/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/htmlburger/carbon-fields/?branch=master) [![Gitter chat](https://badges.gitter.im/carbon-fields/Lobby.png)](https://gitter.im/carbon-fields/Lobby)
### About
[Carbon Fields](http://carbonfields.net/) - developer-oriented library for WordPress custom fields for all types of WordPress content.
Carbon fields can be used as a composer package for easy creation of custom fields in the WordPress administration panel.
Custom fields can be created for post types, taxonomy terms, users, comments, options, navigation menus and even widgets.
Supports PHP 5.6.20 or higher.
### Quickstart
See [Quickstart](https://github.com/htmlburger/carbon-fields-docs/tree/master/documentation/10-quickstart.md)
### Documentation & Other Resources
* [Website](http://carbonfields.net/)
* [Documentation (website)](https://docs.carbonfields.net/)
* [Documentation (GitHub)](https://github.com/htmlburger/carbon-fields-docs)
* [FAQ](http://carbonfields.net/faq/)
* [Support](http://carbonfields.net/support/)
* [GitHub Repository](https://github.com/htmlburger/carbon-fields)

View file

@ -0,0 +1,35 @@
/* ==========================================================================
Colors
========================================================================== */
$color-black: #000;
$color-white: #fff;
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
$wp-color-blue: #0073aa;
$wp-color-medium-blue: #00a0d2;
$wp-color-accent-red: #dc3232;
$wp-color-ultra-dark-gray: #191e23;
$wp-color-dark-gray: #23282d;
$wp-color-base-gray: #32373c;
$wp-color-dark-silver-gray: #82878c;
$wp-color-gray-light-800: lighten($wp-color-base-gray, 52%);
$wp-color-gray-light-500: lighten($wp-color-base-gray, 68%);
$wp-color-gray-light-200: lighten($wp-color-base-gray, 74%);
$wp-color-gray-light-100: lighten($wp-color-base-gray, 77%);
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
$gb-dark-gray-900: #191e23;
$gb-dark-gray-600: #40464d;
$gb-dark-gray-500: #555d66;
$gb-dark-gray-150: #8d96a0;
$gb-light-gray-500: #e2e4e7;
$gb-light-gray-200: #f3f4f5;
$gb-dark-opacity-light-500: rgba(#9197a2, 0.25);
$gb-dark-opacity-light-200: rgba(#8b8b96, .1);

View file

@ -0,0 +1,7 @@
/* ==========================================================================
Fonts
========================================================================== */
$wp-font: -apple-system, BlinkMacSystemFont,"Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell,"Helvetica Neue", sans-serif;
$wp-font-size: 13px;
$wp-line-height: 1.4;

View file

@ -0,0 +1,18 @@
/* ==========================================================================
Variables
========================================================================== */
$transition-base: .1s linear;
$size-base: 4px;
/* ==========================================================================
WordPress Variables
========================================================================== */
$wp-radius-round: 3px;
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
$gb-radius-round-rectangle: 4px;

View file

@ -0,0 +1,9 @@
/**
* External dependencies.
*/
const path = require( 'path' );
module.exports = {
classicBuildPath: path.resolve( __dirname, '..', 'build', 'classic' ),
gutenbergBuildPath: path.resolve( __dirname, '..', 'build', 'gutenberg' ),
};

View file

@ -0,0 +1,85 @@
/**
* External dependencies.
*/
const path = require( 'path' );
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
const OptimizeCssAssetsPlugin = require( 'optimize-css-assets-webpack-plugin' );
const TerserPlugin = require( 'terser-webpack-plugin' );
/**
* Indicates if we're running the build process in production mode.
*
* @type {Boolean}
*/
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
output: {
filename: isProduction ? '[name].min.js' : '[name].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 3
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
},
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve( __dirname, '../assets/styles/*.scss' )
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin( {
filename: isProduction ? '[name].min.css' : '[name].css'
} ),
...(
isProduction
? [
new OptimizeCssAssetsPlugin( {
cssProcessorPluginOptions: {
preset: [ 'default', { discardComments: { removeAll: true } } ]
}
} ),
new TerserPlugin( {
cache: true,
parallel: true
} )
]
: []
)
],
stats: {
modules: false,
hash: false,
builtAt: false,
children: false
}
};

View file

@ -0,0 +1,36 @@
/**
* External dependencies.
*/
const { merge } = require( 'webpack-merge' );
/**
* Internal dependencies.
*/
const base = require( './webpack.base' );
const paths = require( './paths' );
const wpPackages = require( './wp-packages' );
module.exports = [
merge( base, {
entry: {
blocks: './packages/blocks/index.js'
},
output: {
path: paths.gutenbergBuildPath,
},
externals: Object.assign( {}, wpPackages.externals, {
'react': [ 'cf', 'vendor', 'react' ],
'react-dom': [ 'cf', 'vendor', 'react-dom' ],
'nanoid': [ 'cf', 'vendor', 'nanoid' ],
'immer': [ 'cf', 'vendor', 'immer' ],
'@wordpress/api-fetch': [ 'wp', 'apiFetch' ],
'@wordpress/components': [ 'wp', 'components' ],
'@wordpress/blocks': [ 'wp', 'blocks' ],
'@wordpress/editor': [ 'wp', 'editor' ],
'@wordpress/i18n': [ 'wp', 'i18n' ],
'@wordpress/date': [ 'wp', 'date' ],
'@carbon-fields/core': 'cf.core',
'lodash': [ 'lodash' ]
} )
} )
];

View file

@ -0,0 +1,54 @@
/**
* External dependencies.
*/
const webpack = require( 'webpack' );
const { merge } = require( 'webpack-merge' );
/**
* Internal dependencies.
*/
const base = require( './webpack.base' );
const paths = require( './paths' );
const wpPackages = require( './wp-packages' );
const config = {
entry: {
core: './packages/core/index.js'
},
output: {
library: [ 'cf', '[name]' ],
libraryTarget: 'this'
},
externals: {
'react': [ 'cf', 'vendor', 'react' ],
'react-dom': [ 'cf', 'vendor', 'react-dom' ],
'refract-callbag': [ 'cf', 'vendor', 'refract-callbag' ],
'callbag-basics': [ 'cf', 'vendor', 'callbag-basics' ],
'classnames': [ 'cf', 'vendor', 'classnames' ],
'immer': [ 'cf', 'vendor', 'immer' ]
}
};
module.exports = [
merge( base, config, {
output: {
path: paths.gutenbergBuildPath
},
externals: Object.assign( {}, wpPackages.externals, {
'lodash': [ 'lodash' ]
} )
} ),
merge( base, config, {
output: {
path: paths.classicBuildPath
},
externals: Object.assign( {}, wpPackages.proxyExternals, {
'lodash': [ 'cf', 'vendor', 'lodash' ]
} ),
plugins: [
new webpack.ProvidePlugin( {
'wp.element': '@wordpress/element'
} )
]
} )
];

View file

@ -0,0 +1,56 @@
/**
* External dependencies.
*/
const webpack = require( 'webpack' );
const { merge } = require( 'webpack-merge' );
/**
* Internal dependencies.
*/
const base = require( './webpack.base' );
const paths = require( './paths' );
const wpPackages = require( './wp-packages' );
const config = {
entry: {
metaboxes: './packages/metaboxes/index.js'
},
output: {
library: [ 'cf', '[name]' ],
libraryTarget: 'this'
},
externals: {
'react': [ 'cf', 'vendor', 'react' ],
'react-dom': [ 'cf', 'vendor', 'react-dom' ],
'nanoid': [ 'cf', 'vendor', 'nanoid' ],
'refract-callbag': [ 'cf', 'vendor', 'refract-callbag' ],
'callbag-basics': [ 'cf', 'vendor', 'callbag-basics' ],
'classnames': [ 'cf', 'vendor', 'classnames' ],
'immer': [ 'cf', 'vendor', 'immer' ],
'@carbon-fields/core': [ 'cf', 'core' ]
}
};
module.exports = [
merge( base, config, {
output: {
path: paths.gutenbergBuildPath
},
externals: Object.assign( {}, wpPackages.externals, {
'lodash': [ 'lodash' ]
} )
} ),
merge( base, config, {
output: {
path: paths.classicBuildPath
},
externals: Object.assign( {}, wpPackages.proxyExternals, {
'lodash': [ 'cf', 'vendor', 'lodash' ]
} ),
plugins: [
new webpack.ProvidePlugin( {
'wp.element': '@wordpress/element'
} )
]
} )
];

View file

@ -0,0 +1,40 @@
/**
* External dependencies.
*/
const webpack = require( 'webpack' );
const { merge } = require( 'webpack-merge' );
/**
* Internal dependencies.
*/
const base = require( './webpack.base' );
const paths = require( './paths' );
const wpPackages = require( './wp-packages' );
const config = {
entry: {
vendor: './packages/vendor/index.js'
}
};
module.exports = [
merge( base, config, {
output: {
path: paths.gutenbergBuildPath
},
externals: Object.assign( {}, wpPackages.externals, {
'lodash': 'lodash',
'react': 'React',
'react-dom': 'ReactDOM',
'jquery': 'jQuery',
} )
} ),
merge( base, config, {
output: {
path: paths.classicBuildPath
},
plugins: [
new webpack.ProvidePlugin( wpPackages.providers )
]
} )
];

View file

@ -0,0 +1,55 @@
/**
* The WordPress packages used across the code and exposed globally on `cf.vendor` variable.
*
* @type {string[]}
*/
module.exports.packages = [
'@wordpress/compose',
'@wordpress/element',
'@wordpress/hooks',
'@wordpress/data',
'@wordpress/i18n'
];
/**
* Get the packages as an external configuration.
*
* @type {string[]}
*/
module.exports.externals = module.exports.packages.reduce( ( externals, package ) => {
externals[ package ] = [
'wp',
package.replace( '@wordpress/', '' )
];
return externals;
}, {} );
/**
* Get the packages as an external configuration.
* This variant is useful for the classic bundles where we
* provide those dependencies manually.
*
* @type {string[]}
*/
module.exports.proxyExternals = module.exports.packages.reduce( ( externals, package ) => {
externals[ package ] = [
'cf',
'vendor',
package
];
return externals;
}, {} );
/**
* Get the packages as a provider configuration.
* The providers should be used in combination with `proxyExternals` configuration.
*
* @type {Object}
*/
module.exports.providers = module.exports.packages.reduce( ( providers, package ) => {
providers[ module.exports.externals[ package ].join( '.' ) ] = package;
return providers;
}, {} );

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,478 @@
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Complex
========================================================================== */
.postbox .cf-complex__inserter-menu, body[class*=taxonomy-] .cf-complex__inserter-menu {
margin: 0;
border-radius: 3px;
background-color: #191e23;
}
.postbox .cf-complex__inserter-menu:before, body[class*=taxonomy-] .cf-complex__inserter-menu:before {
position: absolute;
top: 50%;
right: 100%;
width: 0;
height: 0;
border-width: 5px 5px 5px 0;
border-style: solid;
border-color: transparent #191e23;
margin-top: -5px;
content: "";
}
.postbox .cf-complex__inserter-item, body[class*=taxonomy-] .cf-complex__inserter-item {
font-weight: 600;
color: #fff;
transition: color 0.1s linear;
}
.postbox .cf-complex__inserter-item:hover, body[class*=taxonomy-] .cf-complex__inserter-item:hover {
color: #00a0d2;
}
.postbox .cf-complex__tabs .cf-complex__inserter-button, body[class*=taxonomy-] .cf-complex__tabs .cf-complex__inserter-button {
font-weight: 600;
color: #23282d;
}
.postbox .cf-complex__tabs-item, body[class*=taxonomy] .cf-complex__tabs-item {
font-weight: 600;
color: #23282d;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Field
========================================================================== */
.cf-container .cf-field {
flex: 1 1 100%;
padding: 12px;
border-width: 0 1px 0 0;
border-style: solid;
border-color: #e2e4e7;
}
.cf-container .cf-field + .cf-field {
border-top-width: 1px;
}
.term-php .cf-container__fields > .cf-field:not(.cf-field--has-width) > .cf-field__head, .cf-container-user-meta .cf-container__fields > .cf-field > .cf-field__head {
position: absolute;
left: 0;
font-weight: 600;
}
.cf-container .cf-field__label {
padding-bottom: 6.5px;
font-weight: 600;
color: #23282d;
}
.cf-container-term-meta .cf-field__label, .cf-container-user-meta .cf-field__label {
margin: 0 !important;
}
.cf-field__help {
display: inline-block;
color: #666;
margin-top: 10px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Multiselect
========================================================================== */
.postbox .cf-multiselect__control {
border-color: #ddd;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
}
.postbox .cf-multiselect__control--is-focused, .postbox .cf-multiselect__control--is-focused:hover {
box-shadow: 0 0 2px rgba(0, 115, 170, 0.8);
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Media Gallery
========================================================================== */
.postbox .cf-media-gallery__inner {
border: 1px solid #e2e4e7;
}
.postbox .cf-media-gallery__actions {
border-top: 1px solid #e2e4e7;
}
.cf-container-term-meta .cf-media-gallery__actions {
padding-left: 0;
}
.cf-container-term-meta .cf-media-gallery__list {
margin: 0 -8px;
max-height: 285px;
}
.cf-container-term-meta .cf-media-gallery__item {
flex-basis: 20%;
}
.postbox .cf-media-gallery__item-inner, .cf-container-term-meta .cf-media-gallery__item-inner {
border: 1px solid #e2e4e7;
}
.postbox .cf-media-gallery__item-preview, .cf-container-term-meta .cf-media-gallery__item-preview {
background-color: #f3f4f5;
}
.postbox .cf-media-gallery__item-name, .cf-container-term-meta .cf-media-gallery__item-name {
border-top: 1px solid #e2e4e7;
background-color: #f3f4f5;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Radio
========================================================================== */
.inside .cf-radio-image .cf-radio__input:focus ~ .cf-radio__label {
box-shadow: 0 0 2px rgba(0, 160, 210, 0.8);
}
.inside .cf-radio-image__image {
border: 1px solid #b5bcc2;
}
.inside .cf-radio__input:focus ~ .cf-radio__label .cf-radio-image__image, .inside .cf-radio__input:checked ~ .cf-radio__label .cf-radio-image__image {
outline: 4px solid #00a0d2;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Widget
========================================================================== */
.cf-container-widget {
margin-bottom: 13px;
}
.cf-container-widget .cf-field {
margin: 1em 0 0;
padding: 0;
border-width: 0;
}
.cf-container-widget .cf-field + .cf-field {
border-top-width: 0;
}
.cf-container-widget .cf-complex__group-body {
border-width: 1px 1px 1px 1px;
margin-top: 0;
}
.cf-container-widget .cf-complex__group-body .cf-field {
padding: 12px;
}
.cf-container-widget .cf-complex__group-body .cf-field + .cf-field {
border-width: 1px 0 0 0;
padding-top: 1em;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Theme Options
========================================================================== */
.carbon-theme-options #post-body.columns-2 #postbox-container-1.fixed, .carbon-network #post-body.columns-2 #postbox-container-1.fixed {
position: fixed;
right: 0;
margin-right: 20px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
User Meta
========================================================================== */
.cf-container-user-meta {
max-width: 600px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Container
========================================================================== */
.carbon-box.hide-if-js:not([hidden]) {
display: block;
}
#poststuff .carbon-box .inside,
.carbon-box .inside {
padding: 0;
margin: 0;
}
.cf-container--plain {
display: block;
}
.cf-container--tabbed {
display: flex;
}
.cf-container--tabbed-horizontal {
flex-direction: column;
}
.cf-container--tabbed-vertical {
flex-direction: row;
}
.cf-container__fields {
display: flex;
flex-wrap: wrap;
flex: 1;
margin: 0 -1px 0 0;
background-color: #fff;
}
.cf-container__fields[hidden] {
display: none;
}
.block-editor .cf-container__fields {
border-left: 1px solid #e2e4e7;
}
.cf-container-term-meta .cf-container__fields, .cf-container-user-meta .cf-container__fields {
border-width: 0 0 1px 1px;
border-style: solid;
border-color: #e2e4e7;
margin: 0;
}
.cf-container__tabs {
position: relative;
z-index: 1;
background-color: #fbfbfc;
}
.cf-container__tabs-list {
display: flex;
flex-wrap: wrap;
margin: 0 0 -1px;
}
.cf-container__tabs-list .cf-container__tabs-item {
display: flex;
align-items: center;
border: 1px solid #e2e4e7;
margin: 0 8px 0 0;
background-color: #fbfbfc;
font-size: 13px;
cursor: pointer;
transition: background-color 0.1s linear, border-color 0.1s linear;
}
.cf-container__tabs-list .cf-container__tabs-item button {
background: 0;
border: 0;
padding: 10px 12px;
margin: 0;
flex: 1;
cursor: pointer;
display: flex;
align-items: center;
}
.cf-container__tabs-list .cf-container__tabs-item button span {
margin-right: 5px;
}
.cf-container__tabs-list .cf-container__tabs-item:hover {
background-color: #fff;
}
.cf-container__tabs-list .cf-container__tabs-item--current {
background-color: #fff;
border-bottom-color: #fff;
}
.cf-container__tabs--tabbed-horizontal {
padding: 12px 12px 0;
border-bottom: 1px solid #e2e4e7;
}
.cf-container__tabs--tabbed-horizontal .cf-container__tabs-list {
display: flex;
flex-direction: row;
}
.cf-container__tabs--tabbed-vertical {
width: 300px;
border-right: 1px solid #e2e4e7;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list {
display: flex;
flex-direction: column;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item {
margin: 0;
justify-content: flex-start;
border: 0;
border-top: 1px solid #e2e4e7;
border-bottom: 1px solid #e2e4e7;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item:first-of-type {
border-top: 0;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item button {
text-align: left;
font-weight: 500;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item + .cf-container__tabs-item {
border-top: 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,808 @@
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Association
========================================================================== */
.block-editor .cf-association__cols {
border-top-width: 1px;
margin-top: 4px;
}
.edit-post-sidebar .cf-association__cols {
border-color: #8d96a0;
flex-direction: column;
}
.edit-post-sidebar .cf-association__cols::before {
background-color: #8d96a0;
display: none;
}
.edit-post-sidebar .cf-association__counter {
display: none;
}
.edit-post-sidebar .cf-association__option {
height: 40px;
}
.edit-post-sidebar .cf-association__option + .cf-association__option {
border-top-color: #8d96a0;
}
.edit-post-sidebar .cf-association__option-thumb {
display: none;
}
.edit-post-sidebar .cf-association__option-content {
align-items: flex-start;
flex-direction: column;
min-width: 0;
}
.edit-post-sidebar .cf-association__option-title {
width: 100%;
}
.edit-post-sidebar .cf-association__col:first-child .cf-association__option-actions {
min-width: 0;
}
.edit-post-sidebar .cf-association__option-actions {
margin-left: auto;
}
.edit-post-sidebar .cf-association__option-action--edit {
display: none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Complex
========================================================================== */
.cf-complex__placeholder-label {
font-size: 13px;
line-height: 1.4;
}
.block-editor .cf-complex__inserter-menu {
z-index: 10;
list-style: none outside none;
border: 1px solid #e2e4e7;
box-shadow: 0 3px 30px rgba(25, 30, 35, 0.1);
background-color: #fff;
}
.block-editor .cf-complex__inserter-menu::before, .block-editor .cf-complex__inserter-menu::after {
position: absolute;
top: 50%;
right: 100%;
width: 0;
height: 0;
border-width: 8px 8px 8px 0;
border-style: solid;
margin-top: -8px;
content: "";
}
.block-editor .cf-complex__inserter-menu::before {
border-color: transparent #e2e4e7;
margin-right: 1px;
}
.block-editor .cf-complex__inserter-menu::after {
border-color: transparent #fff;
}
.block-editor .cf-complex__inserter-item {
color: #40464d;
}
.block-editor .cf-complex__inserter-item:hover {
color: #191e23;
}
.edit-post-sidebar .cf-complex__tabs .cf-complex__inserter-button {
border-color: #8d96a0;
}
.block-editor .cf-complex__tabs-item {
color: #555d66;
}
.block-editor .cf-complex__tabs-item--current {
color: #191e23;
}
.edit-post-sidebar .cf-complex__tabs-item {
border-color: #8d96a0;
}
.edit-post-sidebar .cf-complex__group-head {
border-color: #8d96a0;
}
.edit-post-sidebar .cf-complex__group-body {
display: block;
border-color: #8d96a0;
}
.edit-post-sidebar .cf-complex__group-actions--tabbed {
border-color: #8d96a0;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Field
========================================================================== */
.block-editor .cf-field {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
font-size: 13px;
line-height: 1.4;
color: #555d66;
padding: 8px;
min-width: 0;
}
.wp-block-widget-area .cf-field {
padding: 6.5px 20px;
}
.edit-post-sidebar .cf-block__fields > .cf-field {
padding: 4px 0 0;
}
.block-editor .cf-complex .cf-field {
border-width: 1px 1px 0 0;
border-style: solid;
border-color: #e2e4e7;
}
.edit-post-sidebar .cf-complex .cf-field {
border-color: #8d96a0;
}
.cf-field__label {
font-size: 13px;
font-weight: 600;
color: #23282d;
}
.block-editor .cf-field__label {
margin-bottom: 4px;
}
.wp-block-widget-area .cf-field__label {
margin-bottom: 6.5px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
DateTime
========================================================================== */
.edit-post-sidebar .cf-datetime__inner {
position: relative;
}
.edit-post-sidebar .cf-datetime__inner::before {
position: absolute;
top: 50%;
left: 9px;
display: inline-block;
margin-top: -10px;
}
.wp-block .cf-field .cf-datetime__input {
min-width: 0;
border-color: #e2e4e7;
border-radius: 0;
}
.wp-block .cf-field .cf-datetime__input:focus {
box-shadow: none;
}
.edit-post-sidebar .cf-field .cf-datetime__input {
padding-left: 35px;
}
.wp-block .cf-datetime__button {
height: auto;
border-color: #e2e4e7;
}
.edit-post-sidebar .cf-datetime__button {
display: none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
File
========================================================================== */
.edit-post-sidebar .cf-file__inner {
border-color: #8d96a0;
}
.edit-post-sidebar .cf-file__content {
border-color: #8d96a0;
}
.edit-post-sidebar .cf-file__name {
border-color: #8d96a0;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Map
========================================================================== */
.edit-post-sidebar .cf-map__canvas {
border-color: #8d96a0;
border-top-width: 1px;
margin-top: 4px;
}
.block-editor .cf-map__search[focus-within] ~ .cf-map__canvas {
border-color: #00a0d2;
}
.block-editor .cf-map__search:focus-within ~ .cf-map__canvas {
border-color: #00a0d2;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Multiselect
========================================================================== */
.wp-block .cf-multiselect__control {
border-radius: 0;
}
.edit-post-sidebar .cf-multiselect__control, .edit-post-sidebar .cf-multiselect__control:hover {
border-color: #8d96a0;
}
.edit-post-sidebar .cf-multiselect__control--is-focused, .edit-post-sidebar .cf-multiselect__control--is-focused:hover {
border-color: #00a0d2;
box-shadow: 0 0 0 1px #00a0d2;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Media Gallery
========================================================================== */
@media (min-width: 1440px) {
.block-editor .cf-media-gallery__item {
flex-basis: 16.6667%;
}
}
@media (min-width: 1680px) {
.block-editor .cf-media-gallery__item {
flex-basis: 16.6667%;
}
}
.edit-post-sidebar .cf-media-gallery__item {
flex-basis: 50%;
}
.wp-block .cf-media-gallery__inner {
border: 1px solid #e2e4e7;
}
.edit-post-sidebar .cf-media-gallery__inner {
border: 1px solid #8d96a0;
}
.wp-block .cf-media-gallery__actions {
border-top: 1px solid #e2e4e7;
}
.edit-post-sidebar .cf-media-gallery__actions {
border-top: 1px solid #8d96a0;
}
.wp-block .cf-media-gallery__item-inner {
border: 1px solid #e2e4e7;
}
.edit-post-sidebar .cf-media-gallery__item-inner {
border: 1px solid #8d96a0;
}
.block-editor .cf-media-gallery__item-preview {
background-color: #f3f4f5;
}
.block-editor .cf-media-gallery__item-name {
background-color: #f3f4f5;
}
.wp-block .cf-media-gallery__item-name {
border-top: 1px solid #e2e4e7;
}
.edit-post-sidebar .cf-media-gallery__item-name {
border-top: 1px solid #8d96a0;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
oEmbed
========================================================================== */
.edit-post-sidebar .cf-oembed__preview {
border-color: #8d96a0;
border-top-width: 1px;
margin-top: 4px;
}
.block-editor .cf-oembed[focus-within] .cf-oembed__preview {
border-color: #00a0d2;
}
.block-editor .cf-oembed:focus-within .cf-oembed__preview {
border-color: #00a0d2;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Radio
========================================================================== */
.wp-block .cf-radio__list {
list-style: none outside none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Radio Image
========================================================================== */
.block-editor .cf-radio__list-item {
margin: 0;
}
@media (min-width: 1440px) {
.wp-block .cf-radio-image .cf-radio__list-item {
flex-basis: 25%;
}
}
@media (min-width: 1680px) {
.wp-block .cf-radio-image .cf-radio__list-item {
flex-basis: 25%;
}
}
.edit-post-sidebar .cf-radio-image .cf-radio__list-item {
flex-basis: 33.3333%;
}
.wp-block .cf-radio-image__image {
border: 1px solid #e2e4e7;
}
.edit-post-sidebar .cf-radio-image__image {
border: 1px solid #8d96a0;
}
.block-editor .cf-radio__input:focus ~ .cf-radio__label .cf-radio-image__image, .block-editor .cf-radio__input:checked ~ .cf-radio__label .cf-radio-image__image {
outline: 2px solid #00a0d2;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Select
========================================================================== */
.wp-block .cf-field .cf-select__input {
border-color: #e2e4e7;
border-radius: 0;
}
.wp-block .cf-field .cf-select__input:focus {
box-shadow: none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Set
========================================================================== */
.wp-block .cf-set__list {
list-style: none outside none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Separator
========================================================================== */
.block-editor .cf-separator h3 {
margin: 0;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Text
========================================================================== */
.wp-block .cf-field .cf-text__input {
border-color: #e2e4e7;
border-radius: 0;
}
.wp-block .cf-field .cf-text__input:focus {
box-shadow: none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Textarea
========================================================================== */
.wp-block .cf-field .cf-textarea__input {
border-color: #e2e4e7;
border-radius: 0;
transition: border-color 0.1s linear;
}
.wp-block .cf-field .cf-textarea__input:focus {
border-color: #00a0d2;
box-shadow: none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ------------------------------------------------------------ *\
Block Preview iFrame
\* ------------------------------------------------------------ */
body.block-editor-iframe__body .cf-block-preview {
display: block;
}
body.block-editor-iframe__body .cf-block__fields[\:has\(.cf-block-preview\)] .cf-field:not(.cf-block-preview) {
display: none;
}
body.block-editor-iframe__body .cf-block__fields:has(.cf-block-preview) .cf-field:not(.cf-block-preview) {
display: none;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Block
========================================================================== */
.cf-block__tabs {
margin-bottom: 16px;
}
.wp-block .cf-block__tabs-list {
display: flex;
padding: 0;
margin: 0;
list-style: none outside none;
}
.cf-block__tabs-item {
padding: 8px;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
font-size: 13px;
line-height: 1;
cursor: pointer;
}
.cf-block__tabs-item--current {
box-shadow: 0 3px 0 #00a0d2;
}
.cf-block__fields {
display: flex;
flex-wrap: wrap;
}
.cf-block__fields[hidden] {
display: none;
}
.wp-block .cf-block__fields {
margin: -8px;
}
.cf-block__preview {
min-height: 100px;
}
.cf-block__inner-blocks .block-list-appender {
margin-top: 32px;
margin-bottom: 32px;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,5 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,478 @@
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Complex
========================================================================== */
.postbox .cf-complex__inserter-menu, body[class*=taxonomy-] .cf-complex__inserter-menu {
margin: 0;
border-radius: 3px;
background-color: #191e23;
}
.postbox .cf-complex__inserter-menu:before, body[class*=taxonomy-] .cf-complex__inserter-menu:before {
position: absolute;
top: 50%;
right: 100%;
width: 0;
height: 0;
border-width: 5px 5px 5px 0;
border-style: solid;
border-color: transparent #191e23;
margin-top: -5px;
content: "";
}
.postbox .cf-complex__inserter-item, body[class*=taxonomy-] .cf-complex__inserter-item {
font-weight: 600;
color: #fff;
transition: color 0.1s linear;
}
.postbox .cf-complex__inserter-item:hover, body[class*=taxonomy-] .cf-complex__inserter-item:hover {
color: #00a0d2;
}
.postbox .cf-complex__tabs .cf-complex__inserter-button, body[class*=taxonomy-] .cf-complex__tabs .cf-complex__inserter-button {
font-weight: 600;
color: #23282d;
}
.postbox .cf-complex__tabs-item, body[class*=taxonomy] .cf-complex__tabs-item {
font-weight: 600;
color: #23282d;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Field
========================================================================== */
.cf-container .cf-field {
flex: 1 1 100%;
padding: 12px;
border-width: 0 1px 0 0;
border-style: solid;
border-color: #e2e4e7;
}
.cf-container .cf-field + .cf-field {
border-top-width: 1px;
}
.term-php .cf-container__fields > .cf-field:not(.cf-field--has-width) > .cf-field__head, .cf-container-user-meta .cf-container__fields > .cf-field > .cf-field__head {
position: absolute;
left: 0;
font-weight: 600;
}
.cf-container .cf-field__label {
padding-bottom: 6.5px;
font-weight: 600;
color: #23282d;
}
.cf-container-term-meta .cf-field__label, .cf-container-user-meta .cf-field__label {
margin: 0 !important;
}
.cf-field__help {
display: inline-block;
color: #666;
margin-top: 10px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Multiselect
========================================================================== */
.postbox .cf-multiselect__control {
border-color: #ddd;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
}
.postbox .cf-multiselect__control--is-focused, .postbox .cf-multiselect__control--is-focused:hover {
box-shadow: 0 0 2px rgba(0, 115, 170, 0.8);
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Media Gallery
========================================================================== */
.postbox .cf-media-gallery__inner {
border: 1px solid #e2e4e7;
}
.postbox .cf-media-gallery__actions {
border-top: 1px solid #e2e4e7;
}
.cf-container-term-meta .cf-media-gallery__actions {
padding-left: 0;
}
.cf-container-term-meta .cf-media-gallery__list {
margin: 0 -8px;
max-height: 285px;
}
.cf-container-term-meta .cf-media-gallery__item {
flex-basis: 20%;
}
.postbox .cf-media-gallery__item-inner, .cf-container-term-meta .cf-media-gallery__item-inner {
border: 1px solid #e2e4e7;
}
.postbox .cf-media-gallery__item-preview, .cf-container-term-meta .cf-media-gallery__item-preview {
background-color: #f3f4f5;
}
.postbox .cf-media-gallery__item-name, .cf-container-term-meta .cf-media-gallery__item-name {
border-top: 1px solid #e2e4e7;
background-color: #f3f4f5;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Radio
========================================================================== */
.inside .cf-radio-image .cf-radio__input:focus ~ .cf-radio__label {
box-shadow: 0 0 2px rgba(0, 160, 210, 0.8);
}
.inside .cf-radio-image__image {
border: 1px solid #b5bcc2;
}
.inside .cf-radio__input:focus ~ .cf-radio__label .cf-radio-image__image, .inside .cf-radio__input:checked ~ .cf-radio__label .cf-radio-image__image {
outline: 4px solid #00a0d2;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Widget
========================================================================== */
.cf-container-widget {
margin-bottom: 13px;
}
.cf-container-widget .cf-field {
margin: 1em 0 0;
padding: 0;
border-width: 0;
}
.cf-container-widget .cf-field + .cf-field {
border-top-width: 0;
}
.cf-container-widget .cf-complex__group-body {
border-width: 1px 1px 1px 1px;
margin-top: 0;
}
.cf-container-widget .cf-complex__group-body .cf-field {
padding: 12px;
}
.cf-container-widget .cf-complex__group-body .cf-field + .cf-field {
border-width: 1px 0 0 0;
padding-top: 1em;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Theme Options
========================================================================== */
.carbon-theme-options #post-body.columns-2 #postbox-container-1.fixed, .carbon-network #post-body.columns-2 #postbox-container-1.fixed {
position: fixed;
right: 0;
margin-right: 20px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
User Meta
========================================================================== */
.cf-container-user-meta {
max-width: 600px;
}
/* ==========================================================================
Colors
========================================================================== */
/* ==========================================================================
WordPress Colors - https://make.wordpress.org/design/handbook/design-guide/foundations/colors/
========================================================================== */
/* ==========================================================================
Gutenberg Colors - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_colors.scss
========================================================================== */
/* ==========================================================================
Fonts
========================================================================== */
/* ==========================================================================
Variables
========================================================================== */
/* ==========================================================================
WordPress Variables
========================================================================== */
/* ==========================================================================
Gutenberg Variables - https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss
========================================================================== */
/* ==========================================================================
Container
========================================================================== */
.carbon-box.hide-if-js:not([hidden]) {
display: block;
}
#poststuff .carbon-box .inside,
.carbon-box .inside {
padding: 0;
margin: 0;
}
.cf-container--plain {
display: block;
}
.cf-container--tabbed {
display: flex;
}
.cf-container--tabbed-horizontal {
flex-direction: column;
}
.cf-container--tabbed-vertical {
flex-direction: row;
}
.cf-container__fields {
display: flex;
flex-wrap: wrap;
flex: 1;
margin: 0 -1px 0 0;
background-color: #fff;
}
.cf-container__fields[hidden] {
display: none;
}
.block-editor .cf-container__fields {
border-left: 1px solid #e2e4e7;
}
.cf-container-term-meta .cf-container__fields, .cf-container-user-meta .cf-container__fields {
border-width: 0 0 1px 1px;
border-style: solid;
border-color: #e2e4e7;
margin: 0;
}
.cf-container__tabs {
position: relative;
z-index: 1;
background-color: #fbfbfc;
}
.cf-container__tabs-list {
display: flex;
flex-wrap: wrap;
margin: 0 0 -1px;
}
.cf-container__tabs-list .cf-container__tabs-item {
display: flex;
align-items: center;
border: 1px solid #e2e4e7;
margin: 0 8px 0 0;
background-color: #fbfbfc;
font-size: 13px;
cursor: pointer;
transition: background-color 0.1s linear, border-color 0.1s linear;
}
.cf-container__tabs-list .cf-container__tabs-item button {
background: 0;
border: 0;
padding: 10px 12px;
margin: 0;
flex: 1;
cursor: pointer;
display: flex;
align-items: center;
}
.cf-container__tabs-list .cf-container__tabs-item button span {
margin-right: 5px;
}
.cf-container__tabs-list .cf-container__tabs-item:hover {
background-color: #fff;
}
.cf-container__tabs-list .cf-container__tabs-item--current {
background-color: #fff;
border-bottom-color: #fff;
}
.cf-container__tabs--tabbed-horizontal {
padding: 12px 12px 0;
border-bottom: 1px solid #e2e4e7;
}
.cf-container__tabs--tabbed-horizontal .cf-container__tabs-list {
display: flex;
flex-direction: row;
}
.cf-container__tabs--tabbed-vertical {
width: 300px;
border-right: 1px solid #e2e4e7;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list {
display: flex;
flex-direction: column;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item {
margin: 0;
justify-content: flex-start;
border: 0;
border-top: 1px solid #e2e4e7;
border-bottom: 1px solid #e2e4e7;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item:first-of-type {
border-top: 0;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item button {
text-align: left;
font-weight: 500;
}
.cf-container__tabs--tabbed-vertical .cf-container__tabs-list .cf-container__tabs-item + .cf-container__tabs-item {
border-top: 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,20 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

View file

@ -0,0 +1,123 @@
{
"name": "htmlburger/carbon-fields",
"description": "WordPress developer-friendly custom fields for post types, taxonomy terms, users, comments, widgets, options and more.",
"license": "GPL-2.0-only",
"homepage": "http://carbonfields.net/",
"authors": [
{
"name": "htmlBurger",
"email": "wordpress@htmlburger.com",
"homepage": "https://htmlburger.com/",
"role": "Developer"
},
{
"name": "Miroslav Mitev",
"email": "mmitev.2create@gmail.com",
"role": "Developer"
},
{
"name": "Atanas Angelov",
"email": "atanas.angelov.dev@gmail.com",
"role": "Developer"
},
{
"name": "Georgi Stoyanov",
"email": "stoyanov.gs@gmail.com",
"role": "Developer"
},
{
"name": "Plamen Kostadinov",
"email": "pkostadinov.2create@gmail.com",
"homepage": "http://plasmen.info/",
"role": "Developer"
},
{
"name": "Stanimir Panchev",
"email": "Stan4omir@gmail.com",
"role": "Developer"
},
{
"name": "Marin Atanasov",
"email": "contact@marinatanasov.com",
"homepage": "http://marinatanasov.com/",
"role": "Developer"
},
{
"name": "Siyan Panayotov",
"homepage": "http://siyanpanayotov.com/",
"role": "Developer"
},
{
"name": "Peter Petrov",
"email": "peter.petrov89@gmail.com",
"role": "Developer"
},
{
"name": "Stanimir Stoyanov",
"email": "stanimir.k.stoyanov@gmail.com",
"role": "Developer"
},
{
"name": "Kaloyan Ivanov",
"email": "kaloyanxivanov@gmail.com",
"homepage": "http://vilepixels.com/",
"role": "Developer"
},
{
"name": "Georgi Popov",
"homepage": "http://magadanski.com/",
"role": "Developer"
},
{
"name": "German Velchev",
"email": "germozy@gmail.com",
"role": "Developer"
},
{
"name": "Rashko Petrov",
"email": "brutalenemy666@gmail.com",
"homepage": "http://errorfactory.com/",
"role": "Developer"
},
{
"name": "Alexander Panayotov",
"email": "alexander.panayotov@gmail.com",
"homepage": "http://alexanderpanayotov.com/",
"role": "Developer"
},
{
"name": "Viktor Vasilev",
"email": "liberalcho@gmail.com",
"role": "Developer"
},
{
"name": "Georgi Georgiev",
"email": "george.georgiev96@gmail.com",
"role": "Developer"
},
{
"name": "Atanas Vasilev",
"email": "atanasvasilev91@gmail.com",
"role": "Developer"
}
],
"support": {
"source": "https://github.com/htmlburger/carbon-fields",
"issues": "https://github.com/htmlburger/carbon-fields/issues",
"docs": "http://carbonfields.net/docs/",
"email": "wordpress@htmlburger.com"
},
"autoload": {
"psr-4": {
"Carbon_Fields\\": "core/"
}
},
"require": {
"php": ">=5.6.20"
},
"require-dev": {
"phpunit/phpunit": "7.5.20|9.6.3",
"mockery/mockery": "1.3.6",
"yoast/phpunit-polyfills": "^1.0"
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace Carbon_Fields;
# Define version constant
if ( ! defined( __NAMESPACE__ . '\VERSION' ) ) {
define( __NAMESPACE__ . '\VERSION', '3.6.5' );
}
# Define root directory
if ( ! defined( __NAMESPACE__ . '\DIR' ) ) {
define( __NAMESPACE__ . '\DIR', __DIR__ );
}
# Define root URL
if ( ! defined( __NAMESPACE__ . '\URL' ) ) {
define( __NAMESPACE__ . '\URL', Carbon_Fields::directory_to_url( \Carbon_Fields\DIR ) );
}
# Define whether to compact input fields into a single one to avoid hitting max_input_vars
if ( ! defined( __NAMESPACE__ . '\COMPACT_INPUT' ) ) {
define( __NAMESPACE__ . '\COMPACT_INPUT', true );
}
# Define whether to compact input fields into a single one to avoid hitting max_input_vars
if ( ! defined( __NAMESPACE__ . '\COMPACT_INPUT_KEY' ) ) {
define( __NAMESPACE__ . '\COMPACT_INPUT_KEY', 'carbon_fields_compact_input' );
}

View file

@ -0,0 +1,16 @@
<?php
namespace Carbon_Fields;
/**
* Block proxy factory class.
* Used for shorter namespace access when creating a block.
*/
class Block extends Container {
/**
* {@inheritDoc}
*/
public static function make() {
return call_user_func_array( array( parent::class, 'make' ), array_merge( array( 'block' ), func_get_args() ) );
}
}

View file

@ -0,0 +1,389 @@
<?php
namespace Carbon_Fields;
use Carbon_Fields\Pimple\Container as PimpleContainer;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Loader\Loader;
use Carbon_Fields\Container\Repository as ContainerRepository;
use Carbon_Fields\Toolset\Key_Toolset;
use Carbon_Fields\Toolset\WP_Toolset;
use Carbon_Fields\Service\Meta_Query_Service;
use Carbon_Fields\Service\Legacy_Storage_Service_v_1_5;
use Carbon_Fields\Service\Revisions_Service;
use Carbon_Fields\Service\REST_API_Service;
use Carbon_Fields\Libraries\Sidebar_Manager\Sidebar_Manager;
use Carbon_Fields\REST_API\Router as REST_API_Router;
use Carbon_Fields\REST_API\Decorator as REST_API_Decorator;
use Carbon_Fields\Event\Emitter;
use Carbon_Fields\Event\PersistentListener;
use Carbon_Fields\Event\SingleEventListener;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Holds a static reference to the ioc container
*/
final class Carbon_Fields {
/**
* An event emitter to facilitate events before the WordPress environment is guaranteed to be loaded
*
* @var Emitter
*/
protected $emitter;
/**
* Flag if Carbon Fields has been booted
*
* @var bool
*/
public $booted = false;
/**
* Inversion of Control container instance
*
* @var PimpleContainer
*/
public $ioc = null;
/**
* Singleton implementation
*
* @return Carbon_Fields
*/
public static function instance() {
static $instance = null;
if ( $instance === null ) {
$instance = new static();
}
return $instance;
}
/**
* Constructor
*/
private function __construct() {
$this->install( $this->get_default_ioc() );
}
/**
* Resolve a dependency through IoC
*
* @param string $key
* @param string|null $subcontainer Subcontainer to look into
* @return mixed
*/
public static function resolve( $key, $subcontainer = null ) {
$ioc = static::instance()->ioc;
if ( $subcontainer !== null ) {
if ( ! isset( $ioc[ $subcontainer ] ) ) {
return null;
}
$ioc = $ioc[ $subcontainer ];
}
return $ioc[ $key ];
}
/**
* Resolve a dependency through IoC with arguments
*
* @param string $identifier Key to resolve from the container
* @param array $arguments Key-value array of arguments
* @param string $subcontainer The container to resolve from
* @return mixed
*/
public static function resolve_with_arguments( $identifier, $arguments, $subcontainer = null ) {
$local_container = $subcontainer ? static::resolve( $subcontainer ) : static::instance()->ioc;
$container = new PimpleContainer();
$container['root_container'] = static::instance()->ioc;
$container['local_container'] = $local_container;
$container['arguments'] = $arguments;
$container['object'] = $local_container->raw( $identifier );
return $container['object'];
}
/**
* Resolve a service through IoC
*
* @param string $service_name
* @return mixed
*/
public static function service( $service_name ) {
return static::resolve( $service_name, 'services' );
}
/**
* Check if a dependency is registered
*
* @param string $key
* @param string|null $subcontainer Subcontainer to look into
* @return bool
*/
public static function has( $key, $subcontainer = null ) {
$ioc = static::instance()->ioc;
if ( $subcontainer !== null ) {
if ( ! isset( $ioc[ $subcontainer ] ) ) {
return false;
}
$ioc = $ioc[ $subcontainer ];
}
return isset( $ioc[ $key ] );
}
/**
* Extend Carbon Fields by adding a new entity (container condition etc.)
*
* @param string $class Extension class name
* @param string $extender Extending callable
*/
public static function extend( $class, $extender ) {
$type_dictionary = array(
'_Container' => 'containers',
'_Field' => 'fields',
'_Condition' => 'container_conditions',
);
$extension_suffix = '';
$extension_subcontainer = '';
foreach ( $type_dictionary as $suffix => $subcontainer ) {
if ( substr( $class, -strlen( $suffix ) ) === $suffix ) {
$extension_suffix = $suffix;
$extension_subcontainer = $subcontainer;
}
}
if ( empty( $extension_suffix ) ) {
Incorrect_Syntax_Exception::raise( 'Could not determine "' . $class . '" extension type. Extension classes must have one of the following suffixes: ' . implode( ', ', array_keys( $type_dictionary ) ) );
return;
}
$identifier = Helper::class_to_type( $class, $extension_suffix );
$ioc = static::instance()->ioc[ $extension_subcontainer ];
$ioc[ $identifier ] = $ioc->factory( $extender );
}
/**
* Replace the ioc container for Carbon_Fields\Carbon_Fields
*
* @param PimpleContainer $ioc
*/
public function install( PimpleContainer $ioc ) {
$this->ioc = $ioc;
}
/**
* Boot Carbon Fields with default IoC dependencies
*/
public static function boot() {
if ( static::is_booted() ) {
return;
}
if ( defined( __NAMESPACE__ . '\VERSION' ) ) {
return; // Possibly attempting to load multiple versions of Carbon Fields; bail in favor of already loaded version
}
static::resolve( 'loader' )->boot();
static::instance()->booted = true;
static::instance()->get_emitter()->emit( 'loaded' );
do_action( 'carbon_fields_loaded' );
}
/**
* Check if Carbon Fields has booted
*/
public static function is_booted() {
return static::instance()->booted;
}
/**
* Throw exception if Carbon Fields has not been booted
*/
public static function verify_boot() {
if ( ! static::is_booted() ) {
throw new \Exception( 'You must call Carbon_Fields\Carbon_Fields::boot() in a suitable WordPress hook before using Carbon Fields.' );
}
}
/**
* Throw exception if fields have not been registered yet
*/
public static function verify_fields_registered() {
$register_action = 'carbon_fields_register_fields';
$registered_action = 'carbon_fields_fields_registered';
if ( ! doing_action( $register_action ) && ! doing_action( $registered_action ) && did_action( $registered_action ) === 0 ) {
Incorrect_Syntax_Exception::raise( 'Attempted to access a field before the ' . $register_action . ' and ' . $registered_action . ' actions have fired yet.' );
}
}
/**
* Resolve the public url of a directory inside WordPress
*
* @param string $directory
* @return string
*/
public static function directory_to_url( $directory ) {
$url = \trailingslashit( $directory );
$count = 0;
# Sanitize directory separator on Windows
$url = str_replace( '\\' ,'/', $url );
$possible_locations = array(
WP_PLUGIN_DIR => \plugins_url(), # If installed as a plugin
WP_CONTENT_DIR => \content_url(), # If anywhere in wp-content
ABSPATH => \site_url( '/' ), # If anywhere else within the WordPress installation
);
foreach ( $possible_locations as $test_dir => $test_url ) {
$test_dir_normalized = str_replace( '\\' ,'/', $test_dir );
$url = str_replace( $test_dir_normalized, $test_url, $url, $count );
if ( $count > 0 ) {
return \untrailingslashit( $url );
}
}
return ''; // return empty string to avoid exposing half-parsed paths
}
/**
* Get the event emitter
*
* @return Emitter
*/
public function get_emitter() {
if ( $this->emitter === null ) {
$this->emitter = static::resolve( 'event_emitter' );
}
return $this->emitter;
}
/**
* Add a listener to an event
*
* @param string $event
* @param Event\Listener $listener
* @return Event\Listener $listener
*/
public static function add_listener( $event, $listener ) {
return static::instance()->get_emitter()->add_listener( $event, $listener );
}
/**
* Remove a listener from any event
*
* @param Event\Listener $listener
*/
public static function remove_listener( $listener ) {
static::instance()->get_emitter()->remove_listener( $listener );
}
/**
* Add a persistent listener to an event
*
* @param string $event The event to listen for
* @param string $callable The callable to call when the event is broadcasted
* @return Event\Listener
*/
public static function on( $event, $callable ) {
return static::instance()->get_emitter()->on( $event, $callable );
}
/**
* Add a one-time listener to an event
*
* @param string $event The event to listen for
* @param string $callable The callable to call when the event is broadcasted
* @return Event\Listener
*/
public static function once( $event, $callable ) {
return static::instance()->get_emitter()->once( $event, $callable );
}
/**
* Get default IoC container dependencies
*
* @return PimpleContainer
*/
protected static function get_default_ioc() {
$ioc = new PimpleContainer();
$ioc['loader'] = function( $ioc ) {
return new Loader( $ioc['sidebar_manager'], $ioc['container_repository'] );
};
$ioc['container_repository'] = function() {
return new ContainerRepository();
};
$ioc['containers'] = function() {
return new PimpleContainer();
};
$ioc['fields'] = function() {
return new PimpleContainer();
};
$ioc['key_toolset'] = function() {
return new Key_Toolset();
};
$ioc['wp_toolset'] = function() {
return new WP_Toolset();
};
$ioc['sidebar_manager'] = function() {
return new Sidebar_Manager();
};
$ioc['rest_api_router'] = function( $ioc ) {
return new REST_API_Router( $ioc['container_repository'] );
};
$ioc['rest_api_decorator'] = function( $ioc ) {
return new REST_API_Decorator( $ioc['container_repository'] );
};
/* Services */
$ioc['services'] = function() {
return new PimpleContainer();
};
$ioc['services']['revisions'] = function() use ( $ioc ) {
return new Revisions_Service();
};
$ioc['services']['meta_query'] = function() use ( $ioc ) {
return new Meta_Query_Service( $ioc['container_repository'], $ioc['key_toolset'] );
};
$ioc['services']['legacy_storage'] = function() use ( $ioc ) {
return new Legacy_Storage_Service_v_1_5( $ioc['container_repository'], $ioc['key_toolset'] );
};
$ioc['services']['rest_api'] = function() use ( $ioc ) {
return new REST_API_Service( $ioc['rest_api_router'], $ioc['rest_api_decorator'] );
};
/* Events */
$ioc['event_emitter'] = function() {
return new Emitter();
};
$ioc['event_persistent_listener'] = function() {
return new PersistentListener();
};
$ioc['event_single_event_listener'] = function() {
return new SingleEventListener();
};
$ioc->register( new \Carbon_Fields\Provider\Container_Condition_Provider() );
return $ioc;
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace Carbon_Fields;
/**
* Container proxy factory class.
* Used for shorter namespace access when creating a container.
*
* @method static \Carbon_Fields\Container\Comment_Meta_Container make_comment_meta( string $id, string $name = null )
* @method static \Carbon_Fields\Container\Nav_Menu_Item_Container make_nav_menu_item( string $id, string $name = null )
* @method static \Carbon_Fields\Container\Network_Container make_network( string $id, string $name = null )
* @method static \Carbon_Fields\Container\Post_Meta_Container make_post_meta( string $id, string $name = null )
* @method static \Carbon_Fields\Container\Term_Meta_Container make_term_meta( string $id, string $name = null )
* @method static \Carbon_Fields\Container\Theme_Options_Container make_theme_options( string $id, string $name = null )
* @method static \Carbon_Fields\Container\User_Meta_Container make_user_meta( string $id, string $name = null )
*/
class Container {
/**
* A proxy for the abstract container factory method.
*
* @see \Carbon_Fields\Container\Container::factory()
* @return \Carbon_Fields\Container\Container
*/
public static function factory() {
return call_user_func_array( array( '\Carbon_Fields\Container\Container', 'factory' ), func_get_args() );
}
/**
* An alias of factory().
*
* @see \Carbon_Fields\Container\Container::factory()
* @return \Carbon_Fields\Container\Container
*/
public static function make() {
return call_user_func_array( array( static::class, 'factory' ), func_get_args() );
}
/**
* @param string $method
* @param array $arguments
*
* @return mixed
*/
public static function __callStatic( $method, $arguments ) {
if ( strpos( $method, 'make_' ) === 0 ) {
$raw_type = substr_replace( $method, '', 0, 5 );
array_unshift( $arguments, $raw_type );
return call_user_func_array( array( static::class, 'factory' ), $arguments );
} else {
trigger_error( sprintf( 'Call to undefined function: %s::%s().', static::class, $method ), E_USER_ERROR );
}
}
}

View file

@ -0,0 +1,499 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Datastore\Datastore;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Block_Container extends Container {
/**
* {@inheritDoc}
*/
public $settings = array(
'mode' => 'edit',
'preview' => true,
'parent' => null,
'icon' => 'block-default',
'inner_blocks' => array(
'enabled' => false,
'position' => 'above',
'template' => null,
'template_lock' => null,
'allowed_blocks' => null,
),
'category' => array(
'slug' => 'common',
),
);
/**
* Mode map for settings
*
* @see set_mode()
* @var array
*/
protected $mode_map = array(
'both' => array(
'mode' => 'edit',
'preview' => true,
),
'edit' => array(
'mode' => 'edit',
'preview' => false,
),
'preview' => array(
'mode' => 'preview',
'preview' => false,
),
);
/***
* Block type render callback.
*
* @var callable
*/
protected $render_callback;
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! $this->get_datastore() ) {
$this->set_datastore( Datastore::make( 'empty' ), $this->has_default_datastore() );
}
}
/**
* {@inheritDoc}
*/
public function init() {
add_action( 'init', array( $this, '_attach' ) );
}
/**
* {@inheritDoc}
*/
public function is_valid_save() {
// Return false because Gutenberg
// will handle saving.
return false;
}
/**
* {@inheritDoc}
*/
public function save( $data = null ) {
// Nothing to do here because
// the data is saved by Gutenberg.
}
/**
* {@inheritDoc}
*/
protected function get_environment_for_request() {
return array();
}
/**
* {@inheritDoc}
*/
public function is_valid_attach_for_request() {
return function_exists( 'register_block_type' );
}
/**
* {@inheritDoc}
*/
protected function get_environment_for_object( $object_id ) {
return array();
}
/**
* {@inheritDoc}
*/
public function is_valid_attach_for_object( $object_id = null ) {
return function_exists( 'register_block_type' );
}
/**
* {@inheritDoc}
*/
public function attach() {
add_filter( 'block_categories_all', array( $this, 'attach_block_category' ), 10, 2 );
$this->register_block();
}
/**
* Attach the category of the block type.
*
* @param array $categories
* @return array
*/
public function attach_block_category( $categories ) {
foreach ( $categories as $category ) {
if ( $category[ 'slug' ] === $this->settings[ 'category' ][ 'slug' ] ) {
return $categories;
}
}
return array_merge( $categories, array( $this->settings[ 'category' ] ) );
}
/**
* Set the description of the block type.
*
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#description-optional
*
* @param string $description
* @return Block_Container
*/
public function set_description( $description ) {
$this->settings[ 'description' ] = $description;
return $this;
}
/**
* Set the category of the block type.
*
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#category
*
* @param string $slug
* @param string $title
* @param string $icon
* @return Block_Container
*/
public function set_category( $slug, $title = null, $icon = null ) {
$this->settings[ 'category' ][ 'slug' ] = $slug;
$this->settings[ 'category' ][ 'icon' ] = $icon;
$this->settings[ 'category' ][ 'title' ] = $title ?: Helper::normalize_label( $slug );
return $this;
}
/**
* Set the icon of the block type.
*
* @see https://developer.wordpress.org/resource/dashicons
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#icon-optional
*
* @param string $icon
* @return Block_Container
*/
public function set_icon( $icon ) {
$this->settings[ 'icon' ] = $icon;
return $this;
}
/**
* Set the keywords of the block type.
*
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#keywords-optional
*
* @param array $keywords
* @return Block_Container
*/
public function set_keywords( $keywords = array() ) {
$this->settings[ 'keywords' ] = array_slice( $keywords, 0, 3 );
return $this;
}
/**
* Set a style handle.
*
* @param string $key
* @param string $handle
* @return Block_Container
*/
protected function set_style_handle( $key, $handle ) {
if ( ! wp_style_is( $handle, 'registered' ) ) {
throw new \Exception( __( "Style '$handle' is not registered.", 'crb' ) );
}
$this->settings[ $key ] = $handle;
return $this;
}
/**
* Set the style of the block type.
*
* @param string $handle
* @return Block_Container
*/
public function set_style( $handle ) {
return $this->set_style_handle( 'style', $handle );
}
/**
* Set the editor style of the block type.
*
* @param string $handle
* @return Block_Container
*/
public function set_editor_style( $handle ) {
return $this->set_style_handle( 'editor_style', $handle );
}
/**
* Set whether the preview mode is available for the block type.
*
* @param boolean $preview
* @return Block_Container
*/
public function set_preview_mode( $preview = true ) {
_deprecated_function( __FUNCTION__, '3.0', 'set_mode()' );
$mode = $preview ? 'both' : 'edit';
$this->set_mode( $mode );
return $this;
}
/**
* Set the mode for the block type.
*
* @param string $mode
* @return Block_Container
*/
public function set_mode( $mode ) {
$modes = array_keys( $this->mode_map );
if ( ! in_array( $mode, $modes ) ) {
Incorrect_Syntax_Exception::raise( 'The mode must be one of the following: ' . implode( ', ', $modes ) );
}
$this->settings[ 'mode' ] = $this->mode_map[ $mode ][ 'mode' ];
$this->settings[ 'preview' ] = $this->mode_map[ $mode ][ 'preview' ];
return $this;
}
/**
* Set the parent block(s) in which the block type can be inserted.
*
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#parent-optional
*
* @param string|string[]|null $parent
* @return Block_Container
*/
public function set_parent( $parent = null ) {
if ( ! is_array( $parent ) && ! is_string( $parent ) && ! is_null( $parent ) ) {
throw new \Exception( __( "The parent must be 'array', 'string' or 'null'.", 'crb' ) );
}
$this->settings[ 'parent' ] = is_string( $parent ) ? array( $parent ) : $parent;
return $this;
}
/**
* Set whether the inner blocks are available for the block type.
*
* @param boolean $inner_blocks
* @return Block_Container
*/
public function set_inner_blocks( $inner_blocks = true ) {
$this->settings[ 'inner_blocks' ][ 'enabled' ] = $inner_blocks;
return $this;
}
/**
* Set the position of the inner blocks to be rendered
* above or below the fields.
*
* @param string $position
* @return Block_Container
*/
public function set_inner_blocks_position( $position = 'above' ) {
if ( ! in_array( $position, [ 'above', 'below' ] ) ) {
throw new \Exception( __( "The position of inner blocks must be 'above' or 'below'.", 'crb' ) );
}
$this->settings[ 'inner_blocks' ][ 'position' ] = $position;
return $this;
}
/**
* Set the default template that should be rendered in inner blocks.
*
* @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#template
*
* @param array[]|null $template
* @return Block_Container
*/
public function set_inner_blocks_template( $template = null ) {
if ( ! is_array( $template ) && ! is_null( $template ) ) {
throw new \Exception( __( "The template must be an 'array' or 'null'.", 'crb' ) );
}
$this->settings[ 'inner_blocks' ][ 'template' ] = $template;
return $this;
}
/**
* Set the lock mode used by template of inner blocks.
*
* @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#templatelock
*
* @param string|boolean|null $lock
* @return Block_Container
*/
public function set_inner_blocks_template_lock( $lock = null ) {
if ( is_string( $lock ) && ! in_array( $lock, [ 'all', 'insert' ] ) ) {
throw new \Exception( __( "The template lock must be 'all', 'insert', 'false' or 'null'.", 'crb' ) );
}
$this->settings[ 'inner_blocks' ][ 'template_lock' ] = $lock;
return $this;
}
/**
* Set the list of allowed blocks that can be inserted.
*
* @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#allowedblocks
*
* @param string[]|null $blocks
* @return Block_Container
*/
public function set_allowed_inner_blocks( $blocks = null ) {
if ( ! is_array( $blocks ) && ! is_null( $blocks ) ) {
throw new \Exception( __( "The allowed blocks must be an 'array' or 'null'.", 'crb' ) );
}
if ( is_array( $blocks ) ) {
$this->settings[ 'inner_blocks' ][ 'allowed_blocks' ] = array_map( function ( $block ) {
if ( $block instanceof self ) {
return $block->get_block_type_name();
}
return $block;
}, $blocks );
} else {
$this->settings[ 'inner_blocks' ][ 'allowed_blocks' ] = $blocks;
}
return $this;
}
/**
* Set the render callback of the block type.
*
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/
*
* @param callable $render_callback
* @return Block_Container
*/
public function set_render_callback( $render_callback ) {
$this->render_callback = $render_callback;
return $this;
}
/**
* Get the post id where the block is used in.
* Try with the GET param, and if this is an
* AJAX request get previuos (admin) edit page.
*
* @return int $post_id
*/
public function get_post_id() {
$post_id = isset( $_GET['post'] ) && (int) $_GET['post'] > 0 ? (int) $_GET['post'] : null;
if ( ! empty( $post_id ) ) {
return $post_id;
}
$admin_url = isset( $_SERVER['HTTP_REFERER'] ) && ! empty( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : null;
if ( ! empty( $admin_url ) ) {
$parsed_url = parse_url( $admin_url );
if ( isset( $parsed_url['query']) && ! empty( $parsed_url['query'] ) ) {
$params = explode( '&', $parsed_url['query'] );
foreach ( $params as $param ) {
$param = explode( '=', $param );
if ( $param[0] === 'post' ) {
$post_id = $param[1];
}
}
}
}
if ( empty( $post_id ) ) {
$post_id = get_the_ID();
}
return $post_id;
}
/**
* Render the block type.
*
* @param array $attributes
* @param string $content
* @return string
*/
public function render_block( $attributes, $content ) {
$fields = $attributes['data'];
$post_id = $this->get_post_id();
// Unset the "data" property because we
// pass it as separate argument to the callback.
unset($attributes['data']);
ob_start();
call_user_func( $this->render_callback , $fields, $attributes, $content, $post_id );
return ob_get_clean();
}
/**
* Returns the block type name, e.g. "carbon-fields/testimonial"
*/
private function get_block_type_name() {
return str_replace( 'carbon-fields-container-', 'carbon-fields/', str_replace( '_', '-', $this->id ) );
}
/**
* Register the block type.
*
* @return void
*/
protected function register_block() {
if ( is_null( $this->render_callback ) ) {
throw new \Exception( __( "'render_callback' is required for the blocks.", 'crb' ) );
}
if ( ! is_callable( $this->render_callback ) ) {
throw new \Exception( __( "'render_callback' must be a callable.", 'crb' ) );
}
$style = isset( $this->settings[ 'style' ] ) ? $this->settings[ 'style' ] : null;
$editor_style = isset( $this->settings[ 'editor_style' ] ) ? $this->settings[ 'editor_style' ] : null;
$attributes = array_reduce( $this->get_fields(), function( $attributes, $field ) {
$attributes[ 'data' ][ 'default' ][ $field->get_base_name() ] = $field->get_default_value();
return $attributes;
}, array(
'data' => array(
'type' => 'object',
'default' => array(),
),
) );
register_block_type( $this->get_block_type_name(), array(
'style' => $style,
'editor_style' => $editor_style,
'attributes' => $attributes,
'render_callback' => array( $this, 'render_block' ),
) );
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container;
/**
* Broken container class.
* Used when a container gets misconfigured.
*/
class Broken_Container extends Container {
public function add_fields( $fields ) {}
public function init() {}
protected function is_valid_save() { return false; }
protected function get_environment_for_request() { return array(); }
public function is_valid_attach_for_request() { return false; }
protected function get_environment_for_object( $object_id ) { return array(); }
public function is_valid_attach_for_object( $object_id = null ) { return false; }
}

View file

@ -0,0 +1,159 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Datastore\Datastore;
use Carbon_Fields\Datastore\Meta_Datastore;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Comment meta container class.
*/
class Comment_Meta_Container extends Container {
protected $comment_id;
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! $this->get_datastore() ) {
$this->set_datastore( Datastore::make( 'comment_meta' ), $this->has_default_datastore() );
}
}
/**
* Perform instance initialization
*/
public function init() {
if ( isset( $_GET['c'] ) && $comment_id = absint( $_GET['c'] ) ) { // Input var okay.
$this->set_comment_id( $comment_id );
}
add_action( 'admin_init', array( $this, '_attach' ) );
add_action( 'edit_comment', array( $this, '_save' ) );
}
/**
* Checks whether the current save request is valid
*
* @return bool
*/
public function is_valid_save() {
if ( ! $this->verified_nonce_in_request() ) {
return false;
}
$params = func_get_args();
return $this->is_valid_attach_for_object( $params[0] );
}
/**
* Perform save operation after successful is_valid_save() check.
* The call is propagated to all fields in the container.
*
* @param int $comment_id ID of the comment against which save() is ran
*/
public function save( $comment_id = null ) {
// Unhook action to guarantee single save
remove_action( 'edit_comment', array( $this, '_save' ) );
$this->set_comment_id( $comment_id );
foreach ( $this->fields as $field ) {
$field->set_value_from_input( Helper::input() );
$field->save();
}
}
/**
* Get environment array for page request (in admin)
*
* @return array
*/
protected function get_environment_for_request() {
$input = stripslashes_deep( $_GET );
$environment = array(
'comment_id' => isset( $input['c'] ) ? intval( $input['c'] ) : 0,
);
return $environment;
}
/**
* Check container attachment rules against current page request (in admin)
*
* @return bool
*/
public function is_valid_attach_for_request() {
global $pagenow;
if ( $pagenow !== 'comment.php' ) {
return false;
}
return $this->static_conditions_pass();
}
/**
* Get environment array for object id
*
* @return array
*/
protected function get_environment_for_object( $object_id ) {
$environment = array(
'comment_id' => intval( $object_id ),
);
return $environment;
}
/**
* Check container attachment rules against object id
*
* @param int $object_id
* @return bool
*/
public function is_valid_attach_for_object( $object_id = null ) {
return $this->all_conditions_pass( intval( $object_id ) );
}
/**
* Add meta box to the comment
*/
public function attach() {
add_meta_box(
$this->get_id(),
$this->title,
array( $this, 'render' ),
'comment',
'normal',
'high'
);
}
/**
* Output the container markup
*/
public function render() {
include \Carbon_Fields\DIR . '/templates/Container/comment_meta.php';
}
/**
* Set the comment ID the container will operate with.
*
* @param int $comment_id
*/
protected function set_comment_id( $comment_id ) {
$this->comment_id = $comment_id;
$this->get_datastore()->set_object_id( $comment_id );
foreach ( $this->fields as $field ) {
$datastore = $field->get_datastore();
if ( $datastore->get_object_id() === 0 ) {
$datastore->set_object_id( $comment_id );
}
}
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if the current blog has a specific id
*/
class Blog_ID_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$blog_id = get_current_blog_id();
return $this->compare(
$blog_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Internal boolean (always true) condition
*/
class Boolean_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
return $this->compare(
true,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Any_Contain_Comparer extends Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array( 'IN', 'NOT IN' );
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
public function is_correct( $a, $comparison_operator, $b ) {
if ( ! is_array( $b ) ) {
Incorrect_Syntax_Exception::raise( 'Supplied comparison value is not an array: ' . print_r( $b, true ) );
return false;
}
$intersection = array_intersect( $a, $b );
switch ( $comparison_operator ) {
case 'IN':
return ! empty( $intersection );
case 'NOT IN':
return empty( $intersection );
}
return false;
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
class Any_Equality_Comparer extends Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array( '=', '!=' );
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
public function is_correct( $a, $comparison_operator, $b ) {
switch ( $comparison_operator ) {
case '=':
return in_array( $b, $a );
case '!=':
return ! in_array( $b, $a );
}
return false;
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
abstract class Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array();
/**
* Check if comparer supports the specified comparison sign
*
* @param string $comparison_operator
* @return bool
*/
public function supports_comparison_operator( $comparison_operator ) {
return in_array( $comparison_operator, $this->supported_comparison_operators );
}
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
abstract public function is_correct( $a, $comparison_operator, $b );
}

View file

@ -0,0 +1,38 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Contain_Comparer extends Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array( 'IN', 'NOT IN' );
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
public function is_correct( $a, $comparison_operator, $b ) {
if ( ! is_array( $b ) ) {
Incorrect_Syntax_Exception::raise( 'Supplied comparison value is not an array: ' . print_r( $b, true ) );
return false;
}
switch ( $comparison_operator ) {
case 'IN':
return in_array( $a, $b );
case 'NOT IN':
return ! in_array( $a, $b );
}
return false;
}
}

View file

@ -0,0 +1,36 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Custom_Comparer extends Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array( 'CUSTOM' );
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
public function is_correct( $a, $comparison_operator, $b ) {
if ( ! is_callable( $b ) ) {
Incorrect_Syntax_Exception::raise( 'Supplied comparison value is not a callable: ' . print_r( $b, true ) );
return false;
}
switch ( $comparison_operator ) {
case 'CUSTOM':
return (bool) $b( $a );
}
return false;
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
class Equality_Comparer extends Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array( '=', '!=' );
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
public function is_correct( $a, $comparison_operator, $b ) {
switch ( $comparison_operator ) {
case '=':
return $a == $b;
case '!=':
return $a != $b;
}
return false;
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Carbon_Fields\Container\Condition\Comparer;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Scalar_Comparer extends Comparer {
/**
* Supported comparison signs
*
* @var array<string>
*/
protected $supported_comparison_operators = array( '>', '>=', '<', '<=' );
/**
* Check if comparison is true for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
public function is_correct( $a, $comparison_operator, $b ) {
if ( ! is_scalar( $a ) ) {
Incorrect_Syntax_Exception::raise( 'Environment value for comparison is not scalar: ' . print_r( $a, true ) );
return false;
}
if ( ! is_scalar( $b ) ) {
Incorrect_Syntax_Exception::raise( 'Supplied comparison value is not scalar: ' . print_r( $b, true ) );
return false;
}
switch ( $comparison_operator ) {
case '>':
return $a > $b;
case '>=':
return $a >= $b;
case '<':
return $a < $b;
case '<=':
return $a <= $b;
}
return false;
}
}

View file

@ -0,0 +1,117 @@
<?php
namespace Carbon_Fields\Container\Condition;
use Carbon_Fields\Container\Fulfillable\Fulfillable;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Base container condition class
*/
abstract class Condition implements Fulfillable {
/**
* Condition value to check
*
* @var mixed
*/
protected $value;
/**
* Comparers to use for condition checking
*
* @var \Carbon_Fields\Container\Condition\Comparer\Comparer[]
*/
protected $comparers = array();
/**
* Comparison string to use
*
* @var string
*/
protected $comparison_operator = '';
/**
* Get the condition value
*
* @return mixed
*/
public function get_value() {
if ( $this->get_comparison_operator() !== 'CUSTOM' && $this->value instanceof \Closure ) {
return call_user_func( $this->value );
}
return $this->value;
}
/**
* Set the condition value
*
* @param mixed $value
* @return Condition $this
*/
public function set_value( $value ) {
$this->value = $value;
return $this;
}
/**
* Get the condition comparers
*
* @return \Carbon_Fields\Container\Condition\Comparer\Comparer[]
*/
protected function get_comparers() {
return $this->comparers;
}
/**
* Set the condition comparers
*
* @param \Carbon_Fields\Container\Condition\Comparer\Comparer[] $comparers
* @return Condition $this
*/
public function set_comparers( $comparers ) {
$this->comparers = $comparers;
return $this;
}
/**
* Find the first operator which supports $comparison_operator and check if it is correct for $a and $b
*
* @param mixed $a
* @param string $comparison_operator
* @param mixed $b
* @return bool
*/
protected function compare( $a, $comparison_operator, $b ) {
$comparers = $this->get_comparers();
foreach ( $comparers as $comparer ) {
if ( ! $comparer->supports_comparison_operator( $comparison_operator ) ) {
continue;
}
return $comparer->is_correct( $a, $comparison_operator, $b );
}
Incorrect_Syntax_Exception::raise( 'Unsupported container condition comparison operator used: ' . $comparison_operator );
return false;
}
/**
* Get comparison sign used
*
* @return string
*/
public function get_comparison_operator() {
return $this->comparison_operator;
}
/**
* Set comparison sign
*
* @param string $comparison_operator
* @return $this
*/
public function set_comparison_operator( $comparison_operator ) {
$this->comparison_operator = $comparison_operator;
return $this;
}
}

View file

@ -0,0 +1,21 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if user has a specific capability
*
* Operator "CUSTOM" is passed the user id
*/
class Current_User_Capability_Condition extends User_Capability_Condition {
/**
* Get user id from environment
*
* @param array $environment
* @return integer
*/
protected function get_user_id( $environment ) {
return get_current_user_id();
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if the currently logged in user has a specific id
*/
class Current_User_ID_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$user_id = get_current_user_id();
return $this->compare(
$user_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if the currently logged in user has a specific role
*
* Operator "CUSTOM" is passed an array of all user roles
*/
class Current_User_Role_Condition extends User_Role_Condition {
/**
* Get roles for a user from the environment
*
* @param array $environment
* @return array<string>
*/
protected function get_user_roles( $environment ) {
$user = wp_get_current_user();
$roles = $user ? $user->roles : array();
return $roles;
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace Carbon_Fields\Container\Condition;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Factory {
/**
* Container to resolve conditions from
*/
protected $ioc;
/**
* Constructor
*
* @param \Carbon_Fields\Pimple\Container $ioc
*/
public function __construct( $ioc ) {
$this->ioc = $ioc;
}
/**
* Get the type for the specified class
*
* @param string $class
* @return string
*/
public function get_type( $class ) {
return Helper::class_to_type( $class, '_Condition' );
}
/**
* Get an instance of the specified type
*
* @param string $type
* @return mixed
*/
public function make( $type ) {
$normalized_type = Helper::normalize_type( $type );
if ( isset( $this->ioc[ $normalized_type ] ) ) {
return $this->ioc[ $normalized_type ];
}
Incorrect_Syntax_Exception::raise( 'Unknown condition type "' . $type . '".' );
return null;
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if post has a specific ancestor
*
* Operator "CUSTOM" is passed an array of ancestor post ids
*/
class Post_Ancestor_ID_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_id = $environment['post_id'];
$post = $environment['post'];
$ancestors = array();
if ( $post ) {
$ancestors = array_map( 'intval', get_ancestors( $post_id, $post->post_type ) );
}
return $this->compare(
$ancestors,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check is post is of specific format
*
* Pass an empty string as the value for this condition in order to test if the post has no format assigned
*/
class Post_Format_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_id = $environment['post_id'];
$format = get_post_format( $post_id );
$format = ( $format ) ? $format : ''; // force an empty string for falsy values to ensure strict comparisons work
return $this->compare(
$format,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check for a specific post id
*/
class Post_ID_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_id = $environment['post_id'];
return $this->compare(
$post_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,32 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if a post is on a specific hierarchy level
*
* Level 1 is considered the root level. Passed values have a forced minimum value of 1.
*/
class Post_Level_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_id = $environment['post_id'];
$post_level = count( get_post_ancestors( $post_id ) ) + 1;
$value = $this->get_value();
if ( is_numeric( $value ) ) {
$value = max( 1, intval( $this->get_value() ) );
}
return $this->compare(
$post_level,
$this->get_comparison_operator(),
$value
);
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if post has a specific parent
*/
class Post_Parent_ID_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post = $environment['post'];
$post_parent_id = is_object( $post ) ? intval( $post->post_parent ) : 0;
return $this->compare(
$post_parent_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if post has a specific template
*
* Pass "default" as the value for the default post template
*/
class Post_Template_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_id = $environment['post_id'];
$is_page_for_posts = intval( $post_id ) === intval( get_option( 'page_for_posts' ) );
$post_template = get_post_meta( $post_id, '_wp_page_template', true );
if ( ! $post_template || $is_page_for_posts ) {
$post_template = 'default';
}
return $this->compare(
$post_template,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,90 @@
<?php
namespace Carbon_Fields\Container\Condition;
use Carbon_Fields\Toolset\WP_Toolset;
/**
* Check if a post has a specific term
*
* Accepts the following values:
* Operators "=" and "!=":
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...] // "slug", "term_id" etc. - see get_term_by()
* )
*
* Operators "IN" and "NOT IN":
* array(
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...]
* ),
* ...
* )
*
* Operator "CUSTOM" is passed the post id
*/
class Post_Term_Condition extends Term_Condition {
/**
* Check if a post has a term
*
* @param integer $post_id
* @param array $full_term_desriptor
* @return boolean
*/
protected function post_has_term( $post_id, $full_term_desriptor ) {
$term = $full_term_desriptor['term_object'];
return has_term( intval( $term->term_id ), $term->taxonomy, intval( $post_id ) );
}
/**
* Check if a post has any of the supplied terms
*
* @param integer $post_id
* @param array<array> $full_term_desriptors
* @return boolean
*/
protected function post_has_any_term( $post_id, $full_term_desriptors ) {
foreach ( $full_term_desriptors as $full_term_desriptor ) {
if ( $this->post_has_term( $post_id, $full_term_desriptor ) ) {
return true;
}
}
return false;
}
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_id = $environment['post_id'];
switch ( $this->get_comparison_operator() ) {
case '=':
return $this->post_has_term( $post_id, $this->get_value() );
break;
case '!=':
return ! $this->post_has_term( $post_id, $this->get_value() );
break;
case 'IN':
return $this->post_has_any_term( $post_id, $this->get_value() );
break;
case 'NOT IN':
return ! $this->post_has_any_term( $post_id, $this->get_value() );
break;
}
return $this->compare(
$post_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check is post is of specific type
*/
class Post_Type_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$post_type = $environment['post_type'];
return $this->compare(
$post_type,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,58 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if term has a specific ancestor
*
* Accepts the following values:
* Operators "=" and "!=":
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...] // "slug", "term_id" etc. - see get_term_by()
* )
*
* Operators "IN" and "NOT IN":
* array(
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...]
* ),
* ...
* )
*
* Operator "CUSTOM" is passed an array of ancestor term ids
*/
class Term_Ancestor_Condition extends Term_Condition {
public function is_fulfilled( $environment ) {
$term_id = $environment['term_id'];
$term = $environment['term'];
$ancestors = array();
if ( $term ) {
$ancestors = array_map( 'intval', get_ancestors( $term_id, $term->taxonomy ) );
}
$value = $this->get_value();
switch ( $this->get_comparison_operator() ) {
case '=': // fallthrough intended
case '!=':
$value = $this->get_term_id_from_full_term_descriptor( $value );
break;
case 'IN': // fallthrough intended
case 'NOT IN':
$value = $this->get_term_ids_from_full_term_descriptors( $value );
break;
}
return $this->compare(
$ancestors,
$this->get_comparison_operator(),
$value
);
}
}

View file

@ -0,0 +1,117 @@
<?php
namespace Carbon_Fields\Container\Condition;
use Carbon_Fields\Toolset\WP_Toolset;
/**
* Check for a specific term
*
* Accepts the following values:
* Operators "=" and "!=":
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...] // "slug", "term_id" etc. - see get_term_by()
* )
*
* Operators "IN" and "NOT IN":
* array(
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...]
* ),
* ...
* )
*
* Operator "CUSTOM" is passed the term_id
*/
class Term_Condition extends Condition {
/**
* WP_Toolset to fetch term data with
*
* @var WP_Toolset
*/
protected $wp_toolset;
/**
* Constructor
*/
public function __construct( $wp_toolset ) {
$this->wp_toolset = $wp_toolset;
}
/**
* Get the condition value
*
* @return mixed
*/
public function get_value() {
$value = parent::get_value();
if ( is_array( $value ) ) {
if ( isset( $value['value'] ) ) {
$value = $this->wp_toolset->wildcard_term_descriptor_to_full_term_descriptor( $value );
} else {
$value = array_map( array( $this->wp_toolset, 'wildcard_term_descriptor_to_full_term_descriptor' ), $value );
}
}
return $value;
}
/**
* Pluck term id from a full term descriptor
*
* @param array $full_term_descriptor
* @return integer
*/
protected function get_term_id_from_full_term_descriptor( $full_term_descriptor ) {
return intval( $full_term_descriptor['term_object']->term_id );
}
/**
* Pluck term ids from array of full term descriptors
*
* @param array $full_term_descriptors
* @return array<integer>
*/
protected function get_term_ids_from_full_term_descriptors( $full_term_descriptors ) {
return array_map( array( $this, 'get_term_id_from_full_term_descriptor' ), $full_term_descriptors );
}
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$term_id = $environment['term_id'];
switch ( $this->get_comparison_operator() ) {
case '=':
$value_term_id = $this->get_term_id_from_full_term_descriptor( $this->get_value() );
return $term_id == $value_term_id;
break;
case '!=':
$value_term_id = $this->get_term_id_from_full_term_descriptor( $this->get_value() );
return $term_id != $value_term_id;
break;
case 'IN':
$value_term_ids = $this->get_term_ids_from_full_term_descriptors( $this->get_value() );
return in_array( $term_id, $value_term_ids );
break;
case 'NOT IN':
$value_term_ids = $this->get_term_ids_from_full_term_descriptors( $this->get_value() );
return ! in_array( $term_id, $value_term_ids );
break;
}
return $this->compare(
$term_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if a term is on a specific hierarchy level
*
* Level 1 is considered the root level. Passed values have a forced minimum value of 1.
*/
class Term_Level_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$term = $environment['term'];
$term_level = 1;
if ( $term ) {
$term_level = count( get_ancestors( $term->term_id, $term->taxonomy, 'taxonomy' ) ) + 1;
}
$value = $this->get_value();
if ( is_numeric( $value ) ) {
$value = max( 1, intval( $this->get_value() ) );
}
return $this->compare(
$term_level,
$this->get_comparison_operator(),
$value
);
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if term has a specific parent
*
* Accepts the following values:
* Operators "=" and "!=":
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...] // "slug", "term_id" etc. - see get_term_by()
* )
*
* Operators "IN" and "NOT IN":
* array(
* array(
* 'value'=>...,
* 'taxonomy'=>...,
* ['field'=>...]
* ),
* ...
* )
*
* Operator "CUSTOM" is passed the parent term_id
*/
class Term_Parent_Condition extends Term_Condition {
public function is_fulfilled( $environment ) {
$term = $environment['term'];
$parent_term_id = $term ? intval( $term->parent ) : 0;
$value = $this->get_value();
switch ( $this->get_comparison_operator() ) {
case '=': // fallthrough intended
case '!=':
$value = $this->get_term_id_from_full_term_descriptor( $value );
break;
case 'IN': // fallthrough intended
case 'NOT IN':
$value = $this->get_term_ids_from_full_term_descriptors( $value );
break;
}
return $this->compare(
$parent_term_id,
$this->get_comparison_operator(),
$value
);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if term is of a specific taxonomy
*/
class Term_Taxonomy_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$taxonomy = $environment['taxonomy'];
return $this->compare(
$taxonomy,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,67 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if user has a specific capability
*
* Operator "CUSTOM" is passed the user id
*/
class User_Capability_Condition extends Condition {
/**
* Get user id from environment
*
* @param array $environment
* @return integer
*/
protected function get_user_id( $environment ) {
return $environment['user_id'];
}
/**
* Check if a user has any of the supplied capabilities
*
* @param integer $user_id
* @param array<string> $capabilities
* @return boolean
*/
protected function user_can_any( $user_id, $capabilities ) {
foreach ( $capabilities as $cap ) {
if ( user_can( $user_id, $cap ) ) {
return true;
}
}
return false;
}
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$user_id = $this->get_user_id( $environment );
switch ( $this->get_comparison_operator() ) {
case '=':
return user_can( $user_id, $this->get_value() );
break;
case '!=':
return ! user_can( $user_id, $this->get_value() );
break;
case 'IN':
return $this->user_can_any( $user_id, $this->get_value() );
break;
case 'NOT IN':
return ! $this->user_can_any( $user_id, $this->get_value() );
break;
}
return $this->compare(
$user_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check for a specific user id
*/
class User_ID_Condition extends Condition {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$user_id = $environment['user_id'];
return $this->compare(
$user_id,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace Carbon_Fields\Container\Condition;
/**
* Check if user has a specific role
*
* Operator "CUSTOM" is passed an array of all user roles
*/
class User_Role_Condition extends Condition {
/**
* Get roles for a user from the environment
*
* @param array $environment
* @return array<string>
*/
protected function get_user_roles( $environment ) {
return $environment['roles'];
}
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$roles = $this->get_user_roles( $environment );
return $this->compare(
$roles,
$this->get_comparison_operator(),
$this->get_value()
);
}
}

View file

@ -0,0 +1,918 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Carbon_Fields;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Field\Field;
use Carbon_Fields\Field\Group_Field;
use Carbon_Fields\Container\Fulfillable\Fulfillable_Collection;
use Carbon_Fields\Datastore\Datastore_Interface;
use Carbon_Fields\Datastore\Datastore_Holder_Interface;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Base container class.
* Defines the key container methods and their default implementations.
*/
abstract class Container implements Datastore_Holder_Interface {
/**
* Where to put a particular tab -- at the head or the tail. Tail by default
*/
const TABS_TAIL = 1;
const TABS_HEAD = 2;
/**
* Separator signifying field hierarchy relation
* Used when searching for fields in a specific complex field
*/
const HIERARCHY_FIELD_SEPARATOR = '/';
/**
* Separator signifying complex_field->group relation
* Used when searching for fields in a specific complex field group
*/
const HIERARCHY_GROUP_SEPARATOR = ':';
/**
* Visual layout type constants
*/
const LAYOUT_TABBED_HORIZONTAL = 'tabbed-horizontal';
const LAYOUT_TABBED_VERTICAL = 'tabbed-vertical';
/**
* Stores if the container is active on the current page
*
* @see activate()
* @var bool
*/
protected $active = false;
/**
* List of registered unique field names for this container instance
*
* @see register_field_name()
* @var array
*/
protected $registered_field_names = array();
/**
* Complex field layout
*
* @var string static::LAYOUT_* constant
*/
protected $layout = self::LAYOUT_TABBED_HORIZONTAL;
/**
* Tabs available
*/
protected $tabs = array();
/**
* List of default container settings
*
* @see init()
* @var array
*/
public $settings = array();
/**
* Unique ID of the container
*
* @var string
*/
public $id;
/**
* Title of the container
*
* @var string
*/
public $title = '';
/**
* Type of the container
*
* @var string
*/
public $type;
/**
* List of notification messages to be displayed on the front-end
*
* @var array
*/
protected $notifications = array();
/**
* List of error messages to be displayed on the front-end
*
* @var array
*/
protected $errors = array();
/**
* List of container fields
*
* @see add_fields()
* @var array
*/
protected $fields = array();
/**
* Array of custom CSS classes.
*
* @see set_classes()
* @see get_classes()
* @var array<string>
*/
protected $classes = array();
/**
* Container datastores. Propagated to all container fields
*
* @see set_datastore()
* @see get_datastore()
* @var Datastore_Interface
*/
protected $datastore;
/**
* Flag whether the datastore is the default one or replaced with a custom one
*
* @see set_datastore()
* @see get_datastore()
* @var boolean
*/
protected $has_default_datastore = true;
/**
* Fulfillable_Collection to use when checking attachment/saving conditions
*
* @var Fulfillable_Collection
*/
protected $condition_collection;
/**
* Translator to use when translating conditions to json
*
* @var \Carbon_Fields\Container\Fulfillable\Translator\Translator
*/
protected $condition_translator;
/**
* Create a new container of type $type and name $name.
*
* @param string $raw_type
* @param string $id Unique id for the container. Optional
* @param string $name Human-readable name of the container
* @return Container $container
*/
public static function factory( $raw_type, $id, $name = '' ) {
// no name provided - switch input around as the id is optionally generated based on the name
if ( $name === '' ) {
$name = $id;
$id = '';
}
$type = Helper::normalize_type( $raw_type );
$repository = Carbon_Fields::resolve( 'container_repository' );
$id = $repository->get_unique_container_id( ( $id !== '' ) ? $id : $name );
if ( ! Helper::is_valid_entity_id( $id ) ) {
Incorrect_Syntax_Exception::raise( 'Container IDs can only contain lowercase alphanumeric characters, dashes and underscores ("' . $id . '" passed).' );
return null;
}
if ( ! $repository->is_unique_container_id( $id ) ) {
Incorrect_Syntax_Exception::raise( 'The passed container id is already taken ("' . $id . '" passed).' );
return null;
}
$container = null;
if ( Carbon_Fields::has( $type, 'containers' ) ) {
$container = Carbon_Fields::resolve_with_arguments( $type, array(
'id' => $id,
'name' => $name,
'type' => $type,
), 'containers' );
} else {
// Fallback to class name-based resolution
$class = Helper::type_to_class( $type, __NAMESPACE__, '_Container' );
if ( ! class_exists( $class ) ) {
Incorrect_Syntax_Exception::raise( 'Unknown container "' . $raw_type . '".' );
$class = __NAMESPACE__ . '\\Broken_Container';
}
$fulfillable_collection = Carbon_Fields::resolve( 'container_condition_fulfillable_collection' );
$condition_translator = Carbon_Fields::resolve( 'container_condition_translator_json' );
$container = new $class( $id, $name, $type, $fulfillable_collection, $condition_translator );
}
$repository->register_container( $container );
return $container;
}
/**
* An alias of factory().
*
* @see Container::factory()
* @return Container
*/
public static function make() {
return call_user_func_array( array( static::class, 'factory' ), func_get_args() );
}
/**
* Create a new container
*
* @param string $id Unique id of the container
* @param string $title Title of the container
* @param string $type Type of the container
* @param Fulfillable_Collection $condition_collection
* @param \Carbon_Fields\Container\Fulfillable\Translator\Translator $condition_translator
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
Carbon_Fields::verify_boot();
if ( empty( $title ) ) {
Incorrect_Syntax_Exception::raise( 'Empty container title is not supported' );
}
$this->id = $id;
$this->title = $title;
$this->type = $type;
$this->condition_collection = $condition_collection;
$this->condition_collection->set_condition_type_list(
array_merge( $this->get_condition_types( true ), $this->get_condition_types( false ) ),
true
);
$this->condition_translator = $condition_translator;
}
/**
* Return the container id
*
* @return string
*/
public function get_id() {
return $this->id;
}
/**
* Get array of all static condition types
*
* @param boolean $static
* @return array<string>
*/
protected function get_condition_types( $static ) {
$group = $static ? 'static' : 'dynamic';
$container_type = Helper::class_to_type( get_class( $this ), '_Container' );
$condition_types = array();
$condition_types = apply_filters( 'carbon_fields_' . $container_type . '_container_' . $group . '_condition_types', $condition_types, $container_type, $this );
$condition_types = apply_filters( 'carbon_fields_container_' . $group . '_condition_types', $condition_types, $container_type, $this );
return $condition_types;
}
/**
* Return whether the container is active
*/
public function is_active() {
return $this->active;
}
/**
* Activate the container and trigger an action
*/
protected function activate() {
$this->active = true;
$this->boot();
do_action( 'carbon_fields_container_activated', $this );
$fields = $this->get_fields();
foreach ( $fields as $field ) {
$field->activate();
}
}
/**
* Perform instance initialization
*/
abstract public function init();
/**
* Boot the container once it's attached.
*/
protected function boot() {
}
/**
* Load the value for each field in the container.
* Could be used internally during container rendering
*/
public function load() {
foreach ( $this->fields as $field ) {
$field->load();
}
}
/**
* Called first as part of the container save procedure.
* Responsible for checking the request validity and
* calling the container-specific save() method
*
* @see save()
* @see is_valid_save()
*/
public function _save() {
$param = func_get_args();
if ( call_user_func_array( array( $this, '_is_valid_save' ), $param ) ) {
call_user_func_array( array( $this, 'save' ), $param );
}
}
/**
* Load submitted data and save each field in the container
*
* @see is_valid_save()
*/
public function save( $data = null ) {
foreach ( $this->fields as $field ) {
$field->set_value_from_input( Helper::input() );
$field->save();
}
}
/**
* Checks whether the current save request is valid
*
* @return bool
*/
final protected function _is_valid_save() {
$params = func_get_args();
$is_valid_save = call_user_func_array( array( $this, 'is_valid_save' ), $params );
return apply_filters( 'carbon_fields_container_is_valid_save', $is_valid_save, $this );
}
/**
* Checks whether the current save request is valid
*
* @return bool
*/
abstract protected function is_valid_save();
/**
* Called first as part of the container attachment procedure.
* Responsible for checking it's OK to attach the container
* and if it is, calling the container-specific attach() method
*
* @see attach()
* @see is_valid_attach()
*/
public function _attach() {
if ( ! $this->is_valid_attach() ) {
return;
}
$param = func_get_args();
call_user_func_array( array( $this, 'attach' ), $param );
// Allow containers to initialize but not activate (useful in cases such as theme options)
if ( $this->should_activate() ) {
$this->activate();
}
}
/**
* Attach the container rendering and helping methods
* to concrete WordPress Action hooks
*/
public function attach() {}
/**
* Perform checks whether the container should be attached during the current request
*
* @return bool True if the container is allowed to be attached
*/
final public function is_valid_attach() {
$is_valid_attach = $this->is_valid_attach_for_request();
return apply_filters( 'carbon_fields_container_is_valid_attach', $is_valid_attach, $this );
}
/**
* Get environment array for page request (in admin)
*
* @return array
*/
abstract protected function get_environment_for_request();
/**
* Check container attachment rules against current page request (in admin)
*
* @return bool
*/
abstract protected function is_valid_attach_for_request();
/**
* Check if conditions pass for request
*
* @return bool
*/
protected function static_conditions_pass() {
$environment = $this->get_environment_for_request();
$static_condition_collection = $this->condition_collection->evaluate(
$this->get_condition_types( false ),
true
);
return $static_condition_collection->is_fulfilled( $environment );
}
/**
* Get environment array for object id
*
* @param integer $object_id
* @return array
*/
abstract protected function get_environment_for_object( $object_id );
/**
* Check container attachment rules against object id
*
* @param int $object_id
* @return bool
*/
abstract public function is_valid_attach_for_object( $object_id );
/**
* Check if all conditions pass for object
*
* @param integer $object_id
* @return bool
*/
protected function all_conditions_pass( $object_id ) {
$environment = $this->get_environment_for_object( $object_id );
return $this->condition_collection->is_fulfilled( $environment );
}
/**
* Whether this container is currently viewed.
*/
public function should_activate() {
return true;
}
/**
* Perform a check whether the current container has fields
*
* @return bool
*/
public function has_fields() {
return (bool) $this->fields;
}
/**
* Returns the private container array of fields.
* Use only if you are completely aware of what you are doing.
*
* @return Field[]
*/
public function get_fields() {
return $this->fields;
}
/**
* Return root field from container with specified name
*
* @example crb_complex
*
* @param string $field_name
* @return Field
*/
public function get_root_field_by_name( $field_name ) {
$fields = $this->get_fields();
foreach ( $fields as $field ) {
if ( $field->get_base_name() === $field_name ) {
return $field;
}
}
return null;
}
/**
* Get a regex to match field name patterns used to fetch specific fields
*
* @return string
*/
protected function get_field_pattern_regex() {
$field_name_characters = Helper::get_field_name_characters_pattern();
// matches:
// field_name
// field_name[0]
// field_name[0]:group_name
// field_name:group_name
$regex = '/
\A
(?P<field_name>[' . $field_name_characters . ']+)
(?:\[(?P<group_index>\d+)\])?
(?:' . preg_quote( static::HIERARCHY_GROUP_SEPARATOR, '/' ). '(?P<group_name>[' . $field_name_characters . ']+))?
\z
/x';
return $regex;
}
/**
* Return field from container with specified name
*
* @example $field_name = 'crb_complex/text_field'
* @example $field_name = 'crb_complex/complex_2'
* @example $field_name = 'crb_complex/complex_2:text_group/text_field'
* @example $field_name = 'crb_complex[3]/complex_2[1]:text_group/text_field'
*
* @param string $field_name
* @return Field
*/
public function get_field_by_name( $field_name ) {
$hierarchy = array_filter( explode( static::HIERARCHY_FIELD_SEPARATOR, $field_name ) );
$field = null;
$field_group = $this->get_fields();
$hierarchy_left = $hierarchy;
$field_pattern_regex = $this->get_field_pattern_regex();
$hierarchy_index = array();
while ( ! empty( $hierarchy_left ) ) {
$segment = array_shift( $hierarchy_left );
$segment_pieces = array();
if ( ! preg_match( $field_pattern_regex, $segment, $segment_pieces ) ) {
return null;
}
$segment_field_name = $segment_pieces['field_name'];
$segment_group_index = isset( $segment_pieces['group_index'] ) ? $segment_pieces['group_index'] : 0;
$segment_group_name = isset( $segment_pieces['group_name'] ) ? $segment_pieces['group_name'] : Group_Field::DEFAULT_GROUP_NAME;
foreach ( $field_group as $f ) {
if ( $f->get_base_name() !== $segment_field_name ) {
continue;
}
if ( empty( $hierarchy_left ) ) {
$field = clone $f;
$field->set_hierarchy_index( $hierarchy_index );
} else {
if ( ! ( $f instanceof \Carbon_Fields\Field\Complex_Field ) ) {
return null;
}
$group = $f->get_group_by_name( $segment_group_name );
if ( ! $group ) {
return null;
}
$field_group = $group->get_fields();
$hierarchy_index[] = $segment_group_index;
}
break;
}
}
return $field;
}
/**
* Perform checks whether there is a field registered with the name $name.
* If not, the field name is recorded.
*
* @param string $name
* @return boolean
*/
protected function register_field_name( $name ) {
if ( in_array( $name, $this->registered_field_names ) ) {
Incorrect_Syntax_Exception::raise( 'Field name "' . $name . '" already registered' );
return false;
}
$this->registered_field_names[] = $name;
return true;
}
/**
* Return whether the datastore instance is the default one or has been overriden
*
* @return boolean
*/
public function has_default_datastore() {
return $this->has_default_datastore;
}
/**
* Set datastore instance
*
* @param Datastore_Interface $datastore
* @param bool $set_as_default (optional)
* @return Container $this
*/
public function set_datastore( Datastore_Interface $datastore, $set_as_default = false ) {
if ( $set_as_default && ! $this->has_default_datastore() ) {
return $this; // datastore has been overriden with a custom one - abort changing to a default one
}
$this->datastore = $datastore;
$this->has_default_datastore = $set_as_default;
foreach ( $this->fields as $field ) {
$field->set_datastore( $this->get_datastore(), true );
}
return $this;
}
/**
* Get the DataStore instance
*
* @return Datastore_Interface $datastore
*/
public function get_datastore() {
return $this->datastore;
}
/**
* Return WordPress nonce name used to identify the current container instance
*
* @return string
*/
protected function get_nonce_name() {
return $this->get_id() . '_nonce';
}
/**
* Return WordPress nonce name used to identify the current container instance
*
* @return string
*/
protected function get_nonce_value() {
return wp_create_nonce( $this->get_nonce_name() );
}
/**
* Check if the nonce is present in the request and that it is verified
*
* @return bool
*/
protected function verified_nonce_in_request() {
$input = Helper::input();
$nonce_name = $this->get_nonce_name();
$nonce_value = isset( $input[ $nonce_name ] ) ? $input[ $nonce_name ] : '';
return wp_verify_nonce( $nonce_value, $nonce_name );
}
/**
* Internal function that creates the tab and associates it with particular field set
*
* @param string $tab_name
* @param array $fields
* @param int $queue_end
* @return object $this
*/
private function create_tab( $tab_name, $fields, $queue_end = self::TABS_TAIL ) {
if ( isset( $this->tabs[ $tab_name ] ) ) {
Incorrect_Syntax_Exception::raise( "Tab name duplication for $tab_name" );
}
if ( $queue_end === static::TABS_TAIL ) {
$this->tabs[ $tab_name ] = array();
} else if ( $queue_end === static::TABS_HEAD ) {
$this->tabs = array_merge(
array( $tab_name => array() ),
$this->tabs
);
}
foreach ( $fields as $field ) {
$field_name = $field->get_name();
$this->tabs[ $tab_name ][ $field_name ] = $field;
}
$this->settings['tabs'] = $this->get_tabs_json();
}
/**
* Whether the container is tabbed or not
*
* @return bool
*/
public function is_tabbed() {
return (bool) $this->tabs;
}
/**
* Retrieve all fields that are not defined under a specific tab
*
* @return array
*/
protected function get_untabbed_fields() {
$tabbed_fields_names = array();
foreach ( $this->tabs as $tab_fields ) {
$tabbed_fields_names = array_merge( $tabbed_fields_names, array_keys( $tab_fields ) );
}
$untabbed_fields = array_filter( $this->fields, function( $field ) use ( $tabbed_fields_names ) {
return ! in_array( $field->get_name(), $tabbed_fields_names );
} );
return $untabbed_fields;
}
/**
* Retrieve all tabs.
* Create a default tab if there are any untabbed fields.
*
* @return array
*/
protected function get_tabs() {
$untabbed_fields = $this->get_untabbed_fields();
if ( ! empty( $untabbed_fields ) ) {
$this->create_tab(
apply_filters( 'carbon_fields_untabbed_fields_tab_title', __( 'General', 'carbon-fields' ), $this ),
$untabbed_fields,
static::TABS_HEAD
);
}
return $this->tabs;
}
/**
* Build the tabs JSON
*
* @return array
*/
protected function get_tabs_json() {
$tabs_json = array();
$tabs = $this->get_tabs();
foreach ( $tabs as $tab_name => $fields ) {
foreach ( $fields as $field_name => $field ) {
$tabs_json[ $tab_name ][] = $field_name;
}
}
return $tabs_json;
}
/**
* Get custom CSS classes.
*
* @return array<string>
*/
public function get_classes() {
return $this->classes;
}
/**
* Set CSS classes that the container should use.
*
* @param string|array<string> $classes
* @return Container $this
*/
public function set_classes( $classes ) {
$this->classes = Helper::sanitize_classes( $classes );
return $this;
}
/**
* Returns an array that holds the container data, suitable for JSON representation.
*
* @param bool $load Should the value be loaded from the database or use the value from the current instance.
* @return array
*/
public function to_json( $load ) {
$conditions = $this->condition_collection->evaluate( $this->get_condition_types( true ), $this->get_environment_for_request(), array( 'CUSTOM' ) );
$conditions = $this->condition_translator->fulfillable_to_foreign( $conditions );
$container_data = array(
'id' => $this->get_id(),
'type' => $this->type,
'title' => $this->title,
'layout' => $this->layout,
'classes' => $this->get_classes(),
'settings' => $this->settings,
'conditions' => $conditions,
'fields' => array(),
'nonce' => array(
'name' => $this->get_nonce_name(),
'value' => $this->get_nonce_value(),
),
);
$fields = $this->get_fields();
foreach ( $fields as $field ) {
$field_data = $field->to_json( $load );
$container_data['fields'][] = $field_data;
}
return $container_data;
}
/**
* COMMON USAGE METHODS
*/
/**
* Append array of fields to the current fields set. All items of the array
* must be instances of Field and their names should be unique for all
* Carbon containers.
* If a field does not have DataStore already, the container datastore is
* assigned to them instead.
*
* @param array $fields
* @return Container $this
*/
public function add_fields( $fields ) {
foreach ( $fields as $field ) {
if ( ! ( $field instanceof Field ) ) {
Incorrect_Syntax_Exception::raise( 'Object must be of type Carbon_Fields\\Field\\Field' );
return $this;
}
$unique = $this->register_field_name( $field->get_name() );
if ( ! $unique ) {
return $this;
}
$field->set_context( $this->type );
if ( ! $field->get_datastore() ) {
$field->set_datastore( $this->get_datastore(), $this->has_default_datastore() );
}
}
$this->fields = array_merge( $this->fields, $fields );
return $this;
}
/**
* Configuration function for adding tab with fields
*
* @param string $tab_name
* @param array $fields
* @return Container $this
*/
public function add_tab( $tab_name, $fields ) {
$this->add_fields( $fields );
$this->create_tab( $tab_name, $fields );
return $this;
}
/**
* Proxy function to set attachment conditions
*
* @see Fulfillable_Collection::where()
* @return Container $this
*/
public function where() {
call_user_func_array( array( $this->condition_collection, 'where' ), func_get_args() );
return $this;
}
/**
* Proxy function to set attachment conditions
*
* @see Fulfillable_Collection::or_where()
* @return Container $this
*/
public function or_where() {
call_user_func_array( array( $this->condition_collection, 'or_where' ), func_get_args() );
return $this;
}
/**
* Modify the layout of this field.
*
* @param string $layout
* @return self $this
*/
public function set_layout( $layout ) {
$available_layouts = array(
static::LAYOUT_TABBED_HORIZONTAL,
static::LAYOUT_TABBED_VERTICAL,
);
if ( ! in_array( $layout, $available_layouts ) ) {
$error_message = 'Incorrect layout ``' . $layout . '" specified. ' .
'Available layouts: ' . implode( ', ', $available_layouts );
Incorrect_Syntax_Exception::raise( $error_message );
return $this;
}
$this->layout = $layout;
return $this;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace Carbon_Fields\Container\Fulfillable;
interface Fulfillable {
/**
* Check if the condition is fulfilled
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment );
}

View file

@ -0,0 +1,378 @@
<?php
namespace Carbon_Fields\Container\Fulfillable;
use Carbon_Fields\Container\Condition\Factory;
use Carbon_Fields\Container\Fulfillable\Translator\Array_Translator;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Fulfillable_Collection implements Fulfillable {
/**
* Condition factory used to translated condition types
*
* @var Factory
*/
protected $condition_factory;
/**
* Array translator used to support array representations of fulfillables
*
* @var Array_Translator
*/
protected $array_translator;
/**
* Array of fulfillables in this collection
*
* @var array<array>
*/
protected $fulfillables = array();
/**
* Array of supported fulfillable comparisons
*
* @var array<string>
*/
protected $supported_fulfillable_comparisons = array( 'AND', 'OR' );
/**
* Array of allowed condition types which propagate to child collections
*
* @var array<string>
*/
protected $condition_type_list = array();
/**
* Whether the condition type list is a whitelist or a blacklist
*
* @var bool
*/
protected $condition_type_list_whitelist = false;
/**
* Constructor
*
* @param Factory $condition_factory
* @param Array_Translator $array_translator
*/
public function __construct( Factory $condition_factory, Array_Translator $array_translator ) {
$this->condition_factory = $condition_factory;
$this->array_translator = $array_translator;
}
/**
* Create a new collection
*
* @return Fulfillable_Collection
*/
protected function create_collection() {
return \Carbon_Fields\Carbon_Fields::resolve( 'container_condition_fulfillable_collection' );
}
/**
* Get an array of the fulfillables in this collection
*
* @return array<Fulfillable>
*/
public function get_fulfillables() {
return $this->fulfillables;
}
/**
* Get array of allowed condition types
*
* @return array<string>
*/
public function get_condition_type_list() {
return $this->condition_type_list;
}
/**
* Set array of allowed condition types
* WARNING: this will NOT remove already added conditions which are no longer allowed
*
* @param array<string> $condition_type_list
* @param bool $whitelist
* @return Fulfillable_Collection $this
*/
public function set_condition_type_list( $condition_type_list, $whitelist ) {
$this->condition_type_list_whitelist = $whitelist;
$this->condition_type_list = $condition_type_list;
$this->propagate_condition_type_list();
return $this;
}
/**
* Check if conditions types list is a whitelist
*
* @return bool
*/
public function is_condition_type_list_whitelist() {
return $this->condition_type_list_whitelist;
}
/**
* Check if condition type is allowed
*
* @param string $condition_type
* @return bool
*/
public function is_condition_type_allowed( $condition_type ) {
$in_list = in_array( $condition_type, $this->get_condition_type_list() );
if ( $this->is_condition_type_list_whitelist() ) {
return $in_list;
}
return ! $in_list;
}
/**
* Propagate allowed condition types to child collections
*/
protected function propagate_condition_type_list() {
$condition_type_list = $this->get_condition_type_list();
$fulfillables = $this->get_fulfillables();
foreach ( $fulfillables as $fulfillable ) {
if ( $fulfillable['fulfillable'] instanceof Fulfillable_Collection ) {
$fulfillable['fulfillable']->set_condition_type_list( $condition_type_list, $this->is_condition_type_list_whitelist() );
}
}
}
/**
* Shorthand for where with OR comparison
*
* @param string|array|callable $condition_type
* @param string $comparison_operator Can be skipped. Defaults to "="
* @param mixed $value
* @return Fulfillable_Collection $this
*/
public function or_where( $condition_type, $comparison_operator = '=', $value = null ) {
$this->where( $condition_type, $comparison_operator, $value, 'OR' );
return $this;
}
/**
* Add fulfillable with optional comparison_operator
* This method assumes there is no fulfillable that can be compared with literal NULL
*
* @param string|array|callable $condition_type
* @param string $comparison_operator Can be skipped. Defaults to "="
* @param mixed $value
* @param string $fulfillable_comparison
* @return Fulfillable_Collection $this
*/
public function where( $condition_type, $comparison_operator = '=', $value = null, $fulfillable_comparison = 'AND' ) {
if ( is_array( $condition_type ) ) {
return $this->where_array( $condition_type, $fulfillable_comparison );
}
if ( $condition_type instanceof \Closure ) {
return $this->where_collection( $condition_type, $fulfillable_comparison );
}
if ( ! $this->is_condition_type_allowed( $condition_type ) ) {
Incorrect_Syntax_Exception::raise( 'Unsupported container condition used: ' . $condition_type );
return $this;
}
if ( $value === null ) {
// We do not have a supplied comparison_operator so we default to "="
$value = $comparison_operator;
$comparison_operator = '=';
}
$condition = $this->condition_factory->make( $condition_type );
$condition->set_comparison_operator( $comparison_operator );
$condition->set_value( $value );
$this->add_fulfillable( $condition, $fulfillable_comparison );
return $this;
}
/**
* Add a Fulfillable through array representation
*
* @param array $fulfillable_as_array
* @param string $fulfillable_comparison
* @return Fulfillable_Collection $this
*/
protected function where_array( $fulfillable_as_array, $fulfillable_comparison) {
$fulfillable = $this->array_translator->foreign_to_fulfillable( $fulfillable_as_array );
$this->add_fulfillable( $fulfillable, $fulfillable_comparison );
return $this;
}
/**
* Add a Fulfillable_Collection for nested logic
*
* @param callable $collection_callable
* @param string $fulfillable_comparison
* @return Fulfillable_Collection $this
*/
protected function where_collection( $collection_callable, $fulfillable_comparison) {
$collection = $this->create_collection();
$collection->set_condition_type_list( $this->get_condition_type_list(), $this->is_condition_type_list_whitelist() );
$collection_callable( $collection );
$this->add_fulfillable( $collection, $fulfillable_comparison );
return $this;
}
/**
* Add fulfillable to collection
*
* @param Fulfillable $fulfillable
* @param string $fulfillable_comparison See static::$supported_fulfillable_comparisons
*/
public function add_fulfillable( Fulfillable $fulfillable, $fulfillable_comparison ) {
if ( ! in_array( $fulfillable_comparison, $this->supported_fulfillable_comparisons ) ) {
Incorrect_Syntax_Exception::raise( 'Invalid fulfillable comparison passed: ' . $fulfillable_comparison );
return;
}
$this->fulfillables[] = array(
'fulfillable_comparison' => $fulfillable_comparison,
'fulfillable' => $fulfillable,
);
}
/**
* Remove fulfillable from collection
*
* @param Fulfillable $fulfillable
* @return bool Fulfillable found and removed
*/
public function remove_fulfillable( Fulfillable $fulfillable ) {
$fulfillables = $this->get_fulfillables();
foreach ( $fulfillables as $index => $fulfillable_tuple ) {
if ( $fulfillable_tuple['fulfillable'] === $fulfillable ) {
$fulfillables_copy = $fulfillables; // introduce a copy array to highlight array_splice mutation
array_splice( $fulfillables_copy, $index, 1 );
$this->fulfillables = array_values( $fulfillables_copy ); // make sure our array is indexed cleanly
return true;
}
}
return false;
}
/**
* Get a copy of the collection with conditions not in the whitelist filtered out
*
* @param array<string> $condition_whitelist
* @return Fulfillable_Collection
*/
public function filter( $condition_whitelist ) {
$fulfillables = $this->get_fulfillables();
$collection = $this->create_collection();
foreach ( $fulfillables as $fulfillable_tuple ) {
$fulfillable = $fulfillable_tuple['fulfillable'];
$fulfillable_comparison = $fulfillable_tuple['fulfillable_comparison'];
if ( $fulfillable instanceof Fulfillable_Collection ) {
$filtered_collection = $fulfillable->filter( $condition_whitelist );
$filtered_collection_fulfillables = $filtered_collection->get_fulfillables();
if ( empty( $filtered_collection_fulfillables ) ) {
continue; // skip empty collections to reduce clutter
}
$collection->add_fulfillable( $filtered_collection, $fulfillable_comparison );
} else {
$type = $this->condition_factory->get_type( get_class( $fulfillable ) );
if ( ! in_array( $type, $condition_whitelist ) ) {
continue;
}
$fulfillable_clone = clone $fulfillable;
$collection->add_fulfillable( $fulfillable_clone, $fulfillable_comparison );
}
}
return $collection;
}
/**
* Get a copy of the collection with passed conditions evaluated into boolean conditions
* Useful when evaluating only certain condition types but preserving the rest
* or when passing dynamic conditions to the front-end
*
* @param array<string> $condition_types
* @param array|boolean $environment Environment array or a boolean value to force on conditions
* @param array<string> $comparison_operators Array of comparison operators to evaluate regardless of condition type
* @param boolean $condition_types_blacklist Whether the condition list should act as a blacklist
* @param boolean $comparison_operators_blacklist Whether the comparison operators list should act as a blacklist
* @return Fulfillable_Collection
*/
public function evaluate( $condition_types, $environment, $comparison_operators = array(), $condition_types_blacklist = false, $comparison_operators_blacklist = false ) {
$fulfillables = $this->get_fulfillables();
$collection = $this->create_collection();
foreach ( $fulfillables as $fulfillable_tuple ) {
$fulfillable = $fulfillable_tuple['fulfillable'];
$fulfillable_comparison = $fulfillable_tuple['fulfillable_comparison'];
if ( $fulfillable instanceof Fulfillable_Collection ) {
$evaluated_collection = $fulfillable->evaluate( $condition_types, $environment, $comparison_operators, $condition_types_blacklist, $comparison_operators_blacklist );
$collection->add_fulfillable( $evaluated_collection, $fulfillable_comparison );
} else {
$type = $this->condition_factory->get_type( get_class( $fulfillable ) );
$comparison_operator = $fulfillable->get_comparison_operator();
$condition_type_match = in_array( $type, $condition_types );
if ( $condition_types_blacklist ) {
$condition_type_match = ! $condition_type_match;
}
$comparison_operator_match = in_array( $comparison_operator, $comparison_operators );
if ( $comparison_operators_blacklist ) {
$comparison_operator_match = ! $comparison_operator_match;
}
if ( $condition_type_match || $comparison_operator_match ) {
$boolean_condition = $this->condition_factory->make( 'boolean' );
$boolean_condition->set_comparison_operator( '=' );
$value = is_bool( $environment ) ? $environment : $fulfillable->is_fulfilled( $environment );
$boolean_condition->set_value( $value );
$collection->add_fulfillable( $boolean_condition, $fulfillable_comparison );
} else {
$collection->add_fulfillable( clone $fulfillable, $fulfillable_comparison );
}
}
}
return $collection;
}
/**
* Check if all fulfillables are fulfilled taking into account their fulfillable comparison
*
* @param array $environment
* @return bool
*/
public function is_fulfilled( $environment ) {
$fulfilled = true; // return true for empty collections
$fulfillables = $this->get_fulfillables();
foreach ( $fulfillables as $i => $fulfillable_tuple ) {
$fulfillable = $fulfillable_tuple['fulfillable'];
$fulfillable_comparison = $fulfillable_tuple['fulfillable_comparison'];
if ( $i === 0 ) {
// Ignore first comparison as we need a base fulfillment value
$fulfilled = $fulfillable->is_fulfilled( $environment );
continue;
}
// minor optimization - avoid unnecessary AND check if $fulfilled is currently false
// false && whatever is always false
if ( $fulfillable_comparison == 'AND' && $fulfilled ) {
$fulfilled = $fulfillable->is_fulfilled( $environment );
}
// minor optimization - avoid unnecessary OR check if $fulfilled is currently true
// true || whatever is always true
if ( $fulfillable_comparison == 'OR' && ! $fulfilled ) {
$fulfilled = $fulfillable->is_fulfilled( $environment );
}
}
return $fulfilled;
}
}

View file

@ -0,0 +1,129 @@
<?php
namespace Carbon_Fields\Container\Fulfillable\Translator;
use Carbon_Fields\Container\Condition\Factory;
use Carbon_Fields\Container\Fulfillable\Fulfillable_Collection;
use Carbon_Fields\Container\Condition\Condition;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
class Array_Translator extends Translator {
/**
* Condition factory used to translated condition types
*
* @var Factory
*/
protected $condition_factory;
/**
* Constructor
*
* @param Factory $condition_factory
*/
public function __construct( Factory $condition_factory ) {
$this->condition_factory = $condition_factory;
}
/**
* {@inheritDoc}
*/
protected function condition_to_foreign( Condition $condition ) {
return array(
'type' => $this->condition_factory->get_type( get_class( $condition ) ),
'compare' => $condition->get_comparison_operator(),
'value' => $condition->get_value(),
);
}
/**
* {@inheritDoc}
*/
protected function fulfillable_collection_to_foreign( Fulfillable_Collection $fulfillable_collection ) {
$fulfillables = $fulfillable_collection->get_fulfillables();
if ( empty( $fulfillables ) ) {
return array();
}
$collection = array(
'relation' => 'AND',
);
$relations = array();
foreach ( $fulfillables as $fulfillable_tuple ) {
$comparison = $fulfillable_tuple['fulfillable_comparison'];
$fulfillable = $fulfillable_tuple['fulfillable'];
if ( ! isset( $relations[ $comparison ] ) ) {
$relations[ $comparison ] = array();
}
$relations[ $comparison ][] = $this->fulfillable_to_foreign( $fulfillable );
}
if ( ! empty( $relations['OR'] ) ) {
$collection['relation'] = 'OR';
}
foreach ( $relations as $relation => $fulfillables ) {
$collection[] = array( 'relation' => $relation ) + $fulfillables;
}
if ( count( $relations ) === 1 ) {
// we only have one relation group so we simplify the fulfillables with 1 level
$collection = $collection[0];
}
return array_filter( $collection );
}
/**
* {@inheritDoc}
*/
public function foreign_to_fulfillable( $foreign ) {
if ( ! is_array( $foreign ) ) {
Incorrect_Syntax_Exception::raise( 'Invalid data passed to array condition translator: ' . print_r( $foreign, true ) );
return null;
}
if ( isset( $foreign['type'] ) ) {
return $this->foreign_to_native_condition( $foreign );
}
return $this->foreign_to_native_fulfillable_collection( $foreign );
}
/**
* Translate a Condition
*
* @param array $foreign
* @return Condition
*/
protected function foreign_to_native_condition( $foreign ) {
$condition_type = $foreign['type'];
$comparison_operator = isset( $foreign['compare'] ) ? $foreign['compare'] : '=';
$value = isset( $foreign['value'] ) ? $foreign['value'] : '';
$condition = $this->condition_factory->make( $condition_type );
$condition->set_comparison_operator( $comparison_operator );
$condition->set_value( $value );
return $condition;
}
/**
* Translate a Fulfillable_Collection
*
* @param array $foreign
* @return Fulfillable_Collection
*/
protected function foreign_to_native_fulfillable_collection( $foreign ) {
$fulfillable_comparison = isset( $foreign['relation'] ) ? $foreign['relation'] : 'AND';
$collection = \Carbon_Fields\Carbon_Fields::resolve( 'container_condition_fulfillable_collection' );
foreach ( $foreign as $key => $value ) {
if ( $key === 'relation' ) {
continue; // ignore the relation key - we are only interested in condition definitions
}
$collection->add_fulfillable( $this->foreign_to_fulfillable( $value ), $fulfillable_comparison );
}
return $collection;
}
}

View file

@ -0,0 +1,58 @@
<?php
namespace Carbon_Fields\Container\Fulfillable\Translator;
use Carbon_Fields\Container\Fulfillable\Fulfillable;
class Json_Translator extends Array_Translator {
/**
* {@inheritDoc}
*/
public function fulfillable_to_foreign( Fulfillable $fulfillable ) {
$result = parent::fulfillable_to_foreign( $fulfillable );
return $this->foreign_to_json( $result );
}
/**
* Make conditions friendly for json-based frontend.
*
* @param array $foreign
* @return array
*/
protected function foreign_to_json( $foreign ) {
if ( empty( $foreign ) ) {
return array(
'relation' => 'AND',
'conditions' => array(),
);
}
if ( ! isset( $foreign['relation'] ) ) {
return $foreign;
}
$conditions = array();
foreach ( $foreign as $key => $value ) {
if ( $key === 'relation' ) {
continue;
}
if ( isset( $value['relation'] ) ) {
$conditions[] = $this->foreign_to_json( $value );
} else {
if ( isset( $value['type'] ) ) {
$conditions[] = $value;
} else {
$conditions = array_merge( $conditions, $value );
}
}
}
return array(
'relation' => $foreign['relation'],
'conditions' => $conditions,
);
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace Carbon_Fields\Container\Fulfillable\Translator;
use Carbon_Fields\Container\Fulfillable\Fulfillable;
use Carbon_Fields\Container\Fulfillable\Fulfillable_Collection;
use Carbon_Fields\Container\Condition\Condition;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
abstract class Translator {
/**
* Translate a Fulfillable to foreign data
*
* @param Fulfillable $fulfillable
* @return mixed
*/
public function fulfillable_to_foreign( Fulfillable $fulfillable ) {
if ( $fulfillable instanceof Condition ) {
return $this->condition_to_foreign( $fulfillable );
}
if ( $fulfillable instanceof Fulfillable_Collection ) {
return $this->fulfillable_collection_to_foreign( $fulfillable );
}
Incorrect_Syntax_Exception::raise( 'Attempted to translate an unsupported object: ' . print_r( $fulfillable, true ) );
return null;
}
/**
* Translate a Condition to foreign data
*
* @param Condition $condition
* @return mixed
*/
abstract protected function condition_to_foreign( Condition $condition );
/**
* Translate a Fulfillable_Collection to foreign data
*
* @param Fulfillable_Collection $fulfillable_collection
* @return mixed
*/
abstract protected function fulfillable_collection_to_foreign( Fulfillable_Collection $fulfillable_collection );
/**
* Translate foreign data to a Fulfillable
*
* @param mixed $foreign
* @return Fulfillable
*/
abstract public function foreign_to_fulfillable( $foreign );
}

View file

@ -0,0 +1,229 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Datastore\Datastore;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Nav menu item fields container class.
*/
class Nav_Menu_Item_Container extends Container {
/**
* Array of container clones for every menu item
*
* @see init()
* @var int
*/
protected $menu_item_instances = array();
/**
* The menu item id this container is for
*
* @var int
*/
protected $menu_item_id = 0;
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! $this->get_datastore() ) {
$this->set_datastore( Datastore::make( 'nav_menu_item' ), $this->has_default_datastore() );
}
// Register the custom edit walker only once
$callable = array( static::class, 'edit_walker' );
if ( ! has_filter( 'wp_edit_nav_menu_walker', $callable ) ) {
add_filter( 'wp_edit_nav_menu_walker', $callable, 10, 2 );
}
}
/**
* Perform instance initialization
*
* @param int $menu_item_id Used to pass the correct menu_item_id to the Container object
*/
public function init( $menu_item_id = 0 ) {
$this->menu_item_id = $menu_item_id;
$this->get_datastore()->set_object_id( $this->menu_item_id );
$this->_attach();
// Only the base container should register for updating/rendering
if ( $this->menu_item_id === 0 ) {
add_action( 'wp_update_nav_menu_item', array( $this, 'update' ), 10, 3 );
add_action( 'carbon_fields_print_nav_menu_item_container_fields', array( $this, 'form' ), 10, 5 );
}
return $this;
}
/**
* Checks whether the current save request is valid
*
* @return bool
*/
public function is_valid_save() {
if ( ! $this->verified_nonce_in_request() ) {
return false;
}
$params = func_get_args();
return $this->is_valid_attach_for_object( $params[0] );
}
/**
* Perform save operation after successful is_valid_save() check.
* The call is propagated to all fields in the container.
*/
public function save( $data = null ) {
foreach ( $this->fields as $field ) {
$field->set_value_from_input( Helper::input() );
$field->save();
}
do_action( 'carbon_fields_nav_menu_item_container_saved', $this );
}
/**
* {@inheritDoc}
*/
public function is_active() {
return ( $this->active && $this->menu_item_id !== 0 );
}
/**
* Get environment array for page request (in admin)
*
* @return array
*/
protected function get_environment_for_request() {
return array();
}
/**
* Perform checks whether the container should be attached during the current request
*
* @return bool True if the container is allowed to be attached
*/
public function is_valid_attach_for_request() {
global $pagenow;
$input = Helper::input();
$ajax = defined( 'DOING_AJAX' ) ? DOING_AJAX : false;
$ajax_action = isset( $input['action'] ) ? $input['action'] : '';
$is_on_menu_page = ( $pagenow === 'nav-menus.php' );
$is_menu_ajax_request = ( $ajax && $ajax_action === 'add-menu-item' );
if ( ! $is_on_menu_page && ! $is_menu_ajax_request ) {
return false;
}
return $this->static_conditions_pass();
}
/**
* Get environment array for object id
*
* @return array
*/
protected function get_environment_for_object( $object_id ) {
return array();
}
/**
* Check container attachment rules against object id
*
* @param int $object_id
* @return bool
*/
public function is_valid_attach_for_object( $object_id = null ) {
$post = get_post( $object_id );
if ( ! $post ) {
return false;
}
if ( $post->post_type !== 'nav_menu_item' ) {
return false;
}
return $this->all_conditions_pass( intval( $post->ID ) );
}
/**
* Output the container markup
*/
public function render() {
include \Carbon_Fields\DIR . '/templates/Container/nav_menu_item.php';
}
/**
* Trigger Save for all instances
*/
public function update( $menu_id, $current_menu_item_id ) {
if ( ! $this->is_valid_attach_for_request() ) {
return;
}
$clone = $this->get_clone_for_menu_item( $current_menu_item_id, false );
$clone->_save( $current_menu_item_id );
}
/**
* Render custom fields inside each Nav Menu entry
*/
public function form( $item ) {
if ( ! $this->is_valid_attach_for_request() ) {
return;
}
$clone = $this->get_clone_for_menu_item( $item->ID );
$clone->render();
}
/**
* Create a clone of this container with its own datastore for every menu item
*/
protected function get_clone_for_menu_item( $menu_item_id, $load = true ) {
if ( ! isset( $this->menu_item_instances[ $menu_item_id ] ) ) {
$menu_item_datastore = Datastore::make( 'nav_menu_item' );
$menu_item_datastore->set_object_id( $menu_item_id );
$menu_item_field_prefix = $menu_item_datastore->get_garbage_prefix();
$custom_fields = array();
$fields = $this->get_fields();
foreach ( $fields as $field ) {
$tmp_field = clone $field;
$tmp_field->set_id( $menu_item_field_prefix . $tmp_field->get_id() );
$tmp_field->set_name( $menu_item_field_prefix . $tmp_field->get_name() );
$tmp_field->set_datastore( $menu_item_datastore, true );
$custom_fields[] = $tmp_field;
}
$container = Container::factory( $this->type, $menu_item_field_prefix . $this->get_id() )
->set_datastore( $menu_item_datastore, true )
->add_fields( $custom_fields )
->init( $menu_item_id );
if ( $load ) {
$container->load();
}
$this->menu_item_instances[ $menu_item_id ] = $container;
}
return $this->menu_item_instances[ $menu_item_id ];
}
/**
* Setup custom walker for the Nav Menu entries
*/
public static function edit_walker() {
return 'Carbon_Fields\\Walker\\Nav_Menu_Item_Edit_Walker';
}
}

View file

@ -0,0 +1,88 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Datastore\Datastore;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Theme options container class.
*/
class Network_Container extends Theme_Options_Container {
/**
* ID of the site the container is operating with
*
* @see init()
* @var int
*/
protected $site_id;
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! is_multisite() ) {
Incorrect_Syntax_Exception::raise( 'The "' . $title . '" container will not be available because your site is not a multisite.' );
return;
}
$this->set_datastore( Datastore::make( 'network' ), $this->has_default_datastore() );
$this->set_site_id( SITE_ID_CURRENT_SITE );
}
/**
* {@inheritDoc}
*/
public function init() {
$registered = $this->register_page();
if ( $registered ) {
add_action( 'network_admin_menu', array( $this, '_attach' ) );
}
}
/**
* Check if a site exists by id
*
* @param integer $id
* @return boolean
*/
protected function site_exists( $id ) {
if ( ! function_exists( 'get_blog_status' ) ) {
return false;
}
$blog_domain = get_blog_status( $id, 'domain' );
return ! empty( $blog_domain );
}
/**
* Get the site ID the container is operating with.
*
* @return integer
*/
public function get_site_id() {
return $this->site_id;
}
/**
* Set the site ID the container will operate with.
*
* @param int $id
* @return self $this
*/
public function set_site_id( $id ) {
$id = intval( $id );
if ( ! $this->site_exists( $id ) ) {
Incorrect_Syntax_Exception::raise( 'The specified site id #' . $id . ' does not exist' );
return $this;
}
$this->site_id = $id;
$this->datastore->set_object_id( $this->get_site_id() );
return $this;
}
}

View file

@ -0,0 +1,463 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Datastore\Datastore;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Field container designed to extend WordPress custom fields functionality,
* providing easier user interface to add, edit and delete text, media files,
* location information and more.
*/
class Post_Meta_Container extends Container {
/**
* ID of the post the container is working with
*
* @see init()
* @var int
*/
protected $post_id;
/**
* Post Types
*
*/
protected $post_types;
/**
* Determines whether revisions are disabled for this container
*
* @var bool
*/
protected $revisions_disabled = false;
/**
* List of default container settings
*
* @see init()
* @var array
*/
public $settings = array(
'meta_box_context' => 'normal',
'meta_box_priority' => 'high',
);
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! $this->get_datastore() ) {
$this->set_datastore( Datastore::make( 'post_meta' ), $this->has_default_datastore() );
}
}
/**
* Create DataStore instance, set post ID to operate with (if such exists).
* Bind attach() and save() to the appropriate WordPress actions.
*/
public function init() {
$input = stripslashes_deep( $_GET );
$request_post_id = isset( $input['post'] ) ? intval( $input['post'] ) : 0;
if ( $request_post_id > 0 ) {
$this->set_post_id( $request_post_id );
}
add_action( 'admin_init', array( $this, '_attach' ) );
add_action( 'save_post', array( $this, '_save' ) );
// support for attachments
add_action( 'add_attachment', array( $this, '_save' ) );
add_action( 'edit_attachment', array( $this, '_save' ) );
}
/**
* Checks whether the current save request is valid
* Possible errors are triggering save() for autosave requests
* or performing post save outside of the post edit page (like Quick Edit)
*
* @return bool
*/
public function is_valid_save() {
$params = func_get_args();
$post_id = $params[0];
$post_type = get_post_type( $post_id );
$wp_preview = ( ! empty( $_POST['wp-preview'] ) ) ? $_POST['wp-preview'] : '';
$in_preview = $wp_preview === 'dopreview';
$doing_autosave = defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE;
$is_revision = $post_type === 'revision';
if ( ( $doing_autosave || $is_revision ) && ( ! $in_preview || $this->revisions_disabled ) ) {
return false;
}
if ( ! $this->verified_nonce_in_request() ) {
return false;
}
return $this->is_valid_attach_for_object( $post_id );
}
/**
* Perform save operation after successful is_valid_save() check.
* The call is propagated to all fields in the container.
*
* @param int $post_id ID of the post against which save() is ran
*/
public function save( $post_id = null ) {
// Unhook action to garantee single save
remove_action( 'save_post', array( $this, '_save' ) );
$this->set_post_id( $post_id );
foreach ( $this->fields as $field ) {
$field->set_value_from_input( Helper::input() );
$field->save();
}
do_action( 'carbon_fields_post_meta_container_saved', $post_id, $this );
}
/**
* Get environment array for page request (in admin)
*
* @return array
*/
protected function get_environment_for_request() {
global $pagenow;
$input = stripslashes_deep( $_GET );
$request_post_type = isset( $input['post_type'] ) ? $input['post_type'] : '';
$post_type = '';
if ( $this->post_id ) {
$post_type = get_post_type( $this->post_id );
} elseif ( ! empty( $request_post_type ) ) {
$post_type = $request_post_type;
} elseif ( $pagenow === 'post-new.php' ) {
$post_type = 'post';
}
$post = get_post( $this->post_id );
$post = $post ? $post : null;
$environment = array(
'post_id' => $post ? $post->ID : 0,
'post_type' => $post ? $post->post_type : $post_type,
'post' => $post,
);
return $environment;
}
/**
* Perform checks whether the container should be attached during the current request
*
* @return bool True if the container is allowed to be attached
*/
public function is_valid_attach_for_request() {
global $pagenow;
if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' ) {
return false;
}
$environment = $this->get_environment_for_request();
if ( ! $environment['post_type'] ) {
return false;
}
return $this->static_conditions_pass();
}
/**
* Get environment array for object id
*
* @return array
*/
protected function get_environment_for_object( $object_id ) {
$post = get_post( intval( $object_id ) );
$post_type = $post->post_type;
if ( wp_is_post_revision( $post ) !== false ) {
$post = get_post( intval( $post->post_parent ) );
$post_type = $post->post_type;
}
$environment = array(
'post_id' => $post->ID,
'post' => $post,
'post_type' => $post_type,
);
return $environment;
}
/**
* Check container attachment rules against object id
*
* @param int $object_id
* @return bool
*/
public function is_valid_attach_for_object( $object_id = null ) {
$post = get_post( intval( $object_id ) );
if ( ! $post ) {
return false;
}
return $this->all_conditions_pass( intval( $post->ID ) );
}
/**
* Add meta box for each of the container post types
*/
public function attach() {
$this->post_types = $this->get_post_type_visibility();
foreach ( $this->post_types as $post_type ) {
add_meta_box(
$this->get_id(),
$this->title,
array( $this, 'render' ),
$post_type,
$this->settings['meta_box_context'],
$this->settings['meta_box_priority']
);
$container_id = $this->get_id();
add_filter( "postbox_classes_{$post_type}_{$container_id}", array( $this, 'add_postbox_classes' ) );
}
}
/**
* Classes to add to the post meta box
*/
public function add_postbox_classes( $classes ) {
$classes[] = 'carbon-box';
return $classes;
}
/**
* Output the container markup
*/
public function render() {
include \Carbon_Fields\DIR . '/templates/Container/post_meta.php';
}
/**
* Set the post ID the container will operate with.
*
* @param int $post_id
*/
public function set_post_id( $post_id ) {
$this->post_id = $post_id;
$this->get_datastore()->set_object_id( $post_id );
foreach ( $this->fields as $field ) {
$datastore = $field->get_datastore();
if ( $datastore->get_object_id() === 0 ) {
$datastore->set_object_id( $post_id );
}
}
}
/**
* Get array of post types this container can appear on conditionally
*
* @return array<string>
*/
public function get_post_type_visibility() {
$all_post_types = get_post_types();
$evaluated_collection = $this->condition_collection->evaluate( array( 'post_type' ), true, array(), true );
$shown_on = array();
foreach ( $all_post_types as $post_type ) {
$environment = array(
'post_type' => $post_type,
);
if ( $evaluated_collection->is_fulfilled( $environment ) ) {
$shown_on[] = $post_type;
}
}
return $shown_on;
}
/**
* COMMON USAGE METHODS
*/
/**
* Show the container only on particular page referenced by its path.
*
* @deprecated
* @param int|string $page page ID or page path
* @return object $this
*/
public function show_on_page( $page ) {
$page_id = absint( $page );
if ( $page_id && $page_id == $page ) {
$page_obj = get_post( $page_id );
} else {
$page_obj = get_page_by_path( $page );
}
$page_id = ( $page_obj ) ? $page_obj->ID : -1;
$this->where( 'post_id', '=', $page_id );
return $this;
}
/**
* Show the container only on pages whose parent is referenced by $parent_page_path.
*
* @deprecated
* @param string $parent_page_path
* @return object $this
*/
public function show_on_page_children( $parent_page_path ) {
$page = get_page_by_path( $parent_page_path );
$page_id = ( $page ) ? $page->ID : -1;
$this->where( 'post_parent_id', '=', $page_id );
return $this;
}
/**
* Show the container only on pages whose template has filename $template_path.
*
* @deprecated
* @param string|array $template_path
* @return object $this
*/
public function show_on_template( $template_path ) {
// Backwards compatibility where only pages support templates
if ( version_compare( get_bloginfo( 'version' ), '4.7', '<' ) ) {
$this->show_on_post_type( 'page' );
}
$template_paths = is_array( $template_path ) ? $template_path : array( $template_path );
$this->where( 'post_template', 'IN', $template_paths );
return $this;
}
/**
* Hide the container from pages whose template has filename $template_path.
*
* @deprecated
* @param string|array $template_path
* @return object $this
*/
public function hide_on_template( $template_path ) {
$template_paths = is_array( $template_path ) ? $template_path : array( $template_path );
$this->where( 'post_template', 'NOT IN', $template_paths );
return $this;
}
/**
* Show the container only on hierarchical posts of level $level.
* Levels start from 1 (top level post)
*
* @deprecated
* @param int $level
* @return object $this
*/
public function show_on_level( $level ) {
$this->where( 'post_level', '=', intval( $level ) );
return $this;
}
/**
* Show the container only on posts from the specified format.
* Learn more about {@link http://codex.wordpress.org/Post_Formats Post Formats (Codex)}
*
* @deprecated
* @param string|array $post_format Name of the format as listed on Codex
* @return object $this
*/
public function show_on_post_format( $post_format ) {
$post_formats = is_array( $post_format ) ? $post_format : array( $post_format );
$this->where( 'post_format', 'IN', $post_formats );
return $this;
}
/**
* Show the container only on posts from the specified type(s).
*
* @deprecated
* @param string|array $post_types
* @return object $this
*/
public function show_on_post_type( $post_types ) {
$post_types = is_array( $post_types ) ? $post_types : array( $post_types );
$this->where( 'post_type', 'IN', $post_types );
return $this;
}
/**
* Show the container only on posts from the specified category.
*
* @see show_on_taxonomy_term()
*
* @deprecated
* @param string $category_slug
* @return object $this
*/
public function show_on_category( $category_slug ) {
$this->where( 'post_term', '=', array(
'value' => $category_slug,
'field' => 'slug',
'taxonomy' => 'category',
) );
return $this;
}
/**
* Show the container only on posts which have term $term_slug from the $taxonomy_slug taxonomy.
*
* @deprecated
* @param string $taxonomy_slug
* @param string $term_slug
* @return object $this
*/
public function show_on_taxonomy_term( $term_slug, $taxonomy_slug ) {
$this->where( 'post_term', '=', array(
'value' => $term_slug,
'field' => 'slug',
'taxonomy' => $taxonomy_slug,
) );
return $this;
}
/**
* Sets the meta box container context
*
* @see https://codex.wordpress.org/Function_Reference/add_meta_box
* @param string $context ('normal', 'advanced', 'side' or the custom `carbon_fields_after_title`)
*/
public function set_context( $context ) {
$this->settings['meta_box_context'] = $context;
return $this;
}
/**
* Sets the meta box container priority
*
* @see https://codex.wordpress.org/Function_Reference/add_meta_box
* @param string $priority ('high', 'core', 'default' or 'low')
*/
public function set_priority( $priority ) {
$this->settings['meta_box_priority'] = $priority;
return $this;
}
public function set_revisions_disabled( $revisions_disabled ) {
$this->revisions_disabled = $revisions_disabled;
return $this;
}
public function get_revisions_disabled() {
return $this->revisions_disabled;
}
}

View file

@ -0,0 +1,246 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Keeps track of all instantiated containers
*/
class Repository {
/**
* List of registered unique container ids
*
* @see get_unique_container_id()
* @see register_unique_container_id()
* @see unregister_unique_container_id()
* @var array
*/
protected $registered_container_ids = array();
/**
* List of registered containers that should be initialized
*
* @see initialize_containers()
* @var array
*/
protected $pending_containers = array();
/**
* List of all containers
*
* @see _attach()
* @var array
*/
protected $containers = array();
/**
* Container id prefix
*
* @var string
*/
protected $container_id_prefix = 'carbon_fields_container_';
/**
* Container id prefix
*
* @var string
*/
protected $widget_id_wildcard_suffix = '-__i__';
/**
* Register a container with the repository
*
* @param Container $container
*/
public function register_container( Container $container ) {
$this->register_unique_container_id( $container->get_id() );
$this->containers[] = $container;
$this->pending_containers[] = $container;
}
/**
* Initialize registered containers
*
* @return Container[]
*/
public function initialize_containers() {
$initialized_containers = array();
while ( ( $container = array_shift( $this->pending_containers ) ) ) {
$container->init();
$initialized_containers[] = $container;
}
return $initialized_containers;
}
/**
* Return all containers
*
* @param string $type Container type to filter for
* @return Container[]
*/
public function get_containers( $type = null ) {
$raw_containers = $this->containers;
$containers = array();
if ( $type === null ) {
$containers = $raw_containers;
} else {
$normalized_type = Helper::normalize_type( $type );
foreach ( $raw_containers as $container ) {
if ( $container->type === $normalized_type ) {
$containers[] = $container;
}
}
}
return $containers;
}
/**
* Return field in a container with supplied id
*
* @param string $field_name
* @param string $container_id
* @param bool $include_nested_fields
* @return \Carbon_Fields\Field\Field
*/
public function get_field_in_container( $field_name, $container_id, $include_nested_fields = true ) {
$containers = $this->get_containers();
$field = null;
foreach ( $containers as $container ) {
if ( $container->get_id() !== $container_id ) {
continue;
}
if ( $include_nested_fields ) {
$field = $container->get_field_by_name( $field_name );
} else {
$field = $container->get_root_field_by_name( $field_name );
}
break;
}
return $field;
}
/**
* Return field in containers
*
* @param string $field_name
* @param string $container_type
* @param bool $include_nested_fields
* @return \Carbon_Fields\Field\Field
*/
public function get_field_in_containers( $field_name, $container_type = null, $include_nested_fields = true ) {
$containers = $this->get_containers( $container_type );
$field = null;
foreach ( $containers as $container ) {
if ( $include_nested_fields ) {
$field = $container->get_field_by_name( $field_name );
} else {
$field = $container->get_root_field_by_name( $field_name );
}
if ( $field ) {
break;
}
}
return $field;
}
/**
* Return all currently active containers
*
* @return Container[]
*/
public function get_active_containers() {
return array_filter( $this->containers, function( $container ) {
/** @var Container $container */
return $container->is_active();
} );
}
/**
* Check if container identificator id is unique
*
* @param string $id
* @return bool
*/
public function is_unique_container_id( $id ) {
return ! in_array( $id, $this->registered_container_ids );
}
/**
* Generate a unique container identificator id based on container title
*
* @param string $title
* @return string
*/
public function get_unique_container_id( $title ) {
$id = remove_accents( $title );
$id = strtolower( $id );
$id_prefix = $this->container_id_prefix;
if ( substr( $id, 0, strlen( $id_prefix ) ) === $id_prefix ) {
$id_prefix = '';
}
$wids = $this->widget_id_wildcard_suffix;
$id_suffix = '';
if ( substr( $id, -strlen( $wids ) ) === $wids ) {
$id_suffix = $wids;
$id = substr( $id, 0, -strlen( $wids ) );
}
$id = preg_replace( '~[\s]+~', '_', $id );
$id = preg_replace( '~[^\w\-\_]+~', '', $id );
// Remove multiple sequential underscores from the slug
$id = preg_replace( '~_+~', '_', $id );
// Sometimes we're unable to produce slug because the
// source language isn't latin; in those cases
// we just produce stable hash from the title
if (empty($id) || $id === '_') {
$id = substr( md5( $title ), 0, 8 );
}
$id = $id_prefix . $id . $id_suffix;
$base = $id;
$suffix = 0;
while ( ! $this->is_unique_container_id( $id ) ) {
$suffix++;
$id = $base . strval( $suffix );
}
return $id;
}
/**
* Add container identificator id to the list of unique container ids
*
* @param string $id
*/
protected function register_unique_container_id( $id ) {
if ( $this->is_unique_container_id( $id ) ) {
$this->registered_container_ids[] = $id;
}
}
/**
* Remove container identificator id from the list of unique container ids
*
* @param string $id
*/
protected function unregister_unique_container_id( $id ) {
if ( ! $this->is_unique_container_id( $id ) ) {
unset( $this->registered_container_ids[ array_search( $id, $this->registered_container_ids ) ] );
}
}
}

View file

@ -0,0 +1,231 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Helper\Helper;
use Carbon_Fields\Datastore\Datastore;
/**
* Term meta container class.
*/
class Term_Meta_Container extends Container {
protected $term_id;
public $settings = array();
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! $this->get_datastore() ) {
$this->set_datastore( Datastore::make( 'term_meta' ), $this->has_default_datastore() );
}
}
/**
* Bind attach() and save() to the appropriate WordPress actions.
*/
public function init() {
add_action( 'admin_init', array( $this, '_attach' ) );
add_action( 'init', array( $this, 'hook_to_taxonomies' ), 999999 );
}
/**
* Hook to relevant taxonomies
*/
public function hook_to_taxonomies() {
$taxonomies = $this->get_taxonomy_visibility();
foreach ( $taxonomies as $taxonomy ) {
add_action( 'edited_' . $taxonomy, array( $this, '_save' ), 10, 2 );
add_action( 'created_' . $taxonomy, array( $this, '_save' ), 10, 2 );
}
}
/**
* Checks whether the current save request is valid
*
* @return bool
*/
public function is_valid_save() {
if ( ! $this->verified_nonce_in_request() ) {
return false;
}
$params = func_get_args();
return $this->is_valid_attach_for_object( $params[0] );
}
/**
* Perform save operation after successful is_valid_save() check.
* The call is propagated to all fields in the container.
*
* @param int $term_id ID of the term against which save() is ran
*/
public function save( $term_id = null ) {
$this->set_term_id( $term_id );
foreach ( $this->fields as $field ) {
$field->set_value_from_input( Helper::input() );
$field->save();
}
do_action( 'carbon_fields_term_meta_container_saved', $term_id, $this );
}
/**
* Get environment array for page request (in admin)
*
* @return array
*/
protected function get_environment_for_request() {
$input = stripslashes_deep( $_GET );
$request_term_id = isset( $input['tag_ID'] ) ? intval( $input['tag_ID'] ) : 0;
$request_taxonomy = isset( $input['taxonomy'] ) ? $input['taxonomy'] : '';
$term = get_term( $request_term_id );
$term = ( $term && ! is_wp_error( $term ) ) ? $term : null;
$environment = array(
'term_id' => $term ? intval( $term->term_id ) : 0,
'term' => $term,
'taxonomy' => $term ? $term->taxonomy : $request_taxonomy,
);
return $environment;
}
/**
* Perform checks whether the container should be attached during the current request
*
* @return bool True if the container is allowed to be attached
*/
public function is_valid_attach_for_request() {
global $pagenow;
if ( $pagenow !== 'edit-tags.php' && $pagenow !== 'term.php' ) {
return false;
}
return $this->static_conditions_pass();
}
/**
* Get environment array for object id
*
* @return array
*/
protected function get_environment_for_object( $object_id ) {
$term = get_term( intval( $object_id ) );
$environment = array(
'term_id' => intval( $term->term_id ),
'term' => $term,
'taxonomy' => $term->taxonomy,
);
return $environment;
}
/**
* Check container attachment rules against object id
*
* @param int $object_id
* @return bool
*/
public function is_valid_attach_for_object( $object_id = null ) {
$term = get_term( $object_id );
$term = ( $term && ! is_wp_error( $term ) ) ? $term : null;
if ( ! $term ) {
return false;
}
return $this->all_conditions_pass( intval( $term->term_id ) );
}
/**
* Add term meta for each of the container taxonomies
*/
public function attach() {
$taxonomies = $this->get_taxonomy_visibility();
foreach ( $taxonomies as $taxonomy ) {
add_action( $taxonomy . '_edit_form_fields', array( $this, 'render' ), 10, 2 );
add_action( $taxonomy . '_add_form_fields', array( $this, 'render' ), 10, 2 );
}
}
/**
* Output the container markup
*/
public function render( $term = null ) {
if ( is_object( $term ) ) {
$this->set_term_id( $term->term_id );
}
include \Carbon_Fields\DIR . '/templates/Container/term_meta.php';
}
/**
* Set the term ID the container will operate with.
*
* @param int $term_id
*/
protected function set_term_id( $term_id ) {
$this->term_id = $term_id;
$this->get_datastore()->set_object_id( $term_id );
foreach ( $this->fields as $field ) {
$datastore = $field->get_datastore();
if ( $datastore->get_object_id() === 0 ) {
$datastore->set_object_id( $term_id );
}
}
}
/**
* Get array of taxonomies this container can appear on conditionally
*
* @return array<string>
*/
public function get_taxonomy_visibility() {
$all_taxonomies = get_taxonomies();
$evaluated_collection = $this->condition_collection->evaluate( array( 'term_taxonomy' ), true, array(), true );
$shown_on = array();
foreach ( $all_taxonomies as $taxonomy ) {
$environment = array(
'taxonomy' => $taxonomy,
);
if ( $evaluated_collection->is_fulfilled( $environment ) ) {
$shown_on[] = $taxonomy;
}
}
return $shown_on;
}
/**
* Show the container only on terms from the specified taxonomies.
*
* @deprecated
* @param string|array $taxonomies
* @return object $this
*/
public function show_on_taxonomy( $taxonomies ) {
$taxonomies = is_array( $taxonomies ) ? $taxonomies : array( $taxonomies );
$this->where( 'term_taxonomy', 'IN', $taxonomies );
return $this;
}
/**
* Show the container only on particular term level.
*
* @deprecated
* @param int $term_level
* @return object $this
*/
public function show_on_level( $term_level ) {
$this->where( 'term_level', '=', intval( $term_level ) );
return $this;
}
}

View file

@ -0,0 +1,329 @@
<?php
namespace Carbon_Fields\Container;
use Carbon_Fields\Datastore\Datastore;
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
/**
* Theme options container class.
*/
class Theme_Options_Container extends Container {
/**
* Array of registered page slugs to verify uniqueness with
*
* @var array
*/
protected static $registered_pages = array();
/**
* Array of container settings
*
* @var array
*/
public $settings = array(
'parent' => '',
'file' => '',
'icon' => '',
'menu_position' => null,
'menu_title' => null,
);
/**
* {@inheritDoc}
*/
public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
if ( ! $this->get_datastore() ) {
$this->set_datastore( Datastore::make( 'theme_options' ), $this->has_default_datastore() );
}
if ( apply_filters( 'carbon_fields_' . $type . '_container_admin_only_access', true, $title, $this ) ) {
$this->where( 'current_user_capability', '=', 'manage_options' );
}
}
/**
* Sanitize a title to a filename
*
* @param string $title
* @param string $extension
* @return string
*/
protected function title_to_filename( $title, $extension ) {
$title = sanitize_file_name( $title );
$title = strtolower( $title );
$title = remove_accents( $title );
$title = preg_replace( array(
'~\s+~',
'~[^\w\d-]+~u',
'~-+~',
), array(
'-',
'-',
'-',
), $title );
return $title . $extension;
}
/**
* Attach container as a theme options page/subpage.
*/
public function init() {
$registered = $this->register_page();
if ( $registered ) {
add_action( 'admin_menu', array( $this, '_attach' ) );
}
}
/**
* Checks whether the current save request is valid
*
* @return bool
*/
public function is_valid_save() {
if ( ! $this->verified_nonce_in_request() ) {
return false;
}
return $this->is_valid_attach_for_object( null );
}
/**
* Perform save operation after successful is_valid_save() check.
* The call is propagated to all fields in the container.
*
* @param mixed $user_data
*/
public function save( $user_data = null ) {
try {
parent::save( $user_data );
} catch ( Incorrect_Syntax_Exception $e ) {
$this->errors[] = $e->getMessage();
}
do_action( 'carbon_fields_' . $this->type . '_container_saved', $user_data, $this );
if ( ! headers_sent() ) {
wp_redirect( add_query_arg( array( 'settings-updated' => 'true' ) ) );
}
}
/**
* Get environment array for page request (in admin)
*
* @return array
*/
protected function get_environment_for_request() {
return array();
}
/**
* Perform checks whether the container should be attached during the current request
*
* @return bool True if the container is allowed to be attached
*/
public function is_valid_attach_for_request() {
return $this->static_conditions_pass();
}
/**
* Get environment array for object id
*
* @return array
*/
protected function get_environment_for_object( $object_id ) {
return array();
}
/**
* Check container attachment rules against object id
*
* @param int $object_id
* @return bool
*/
public function is_valid_attach_for_object( $object_id = null ) {
return $this->all_conditions_pass( intval( $object_id ) );
}
/**
* Add theme options container pages.
* Hook the container saving action.
*/
public function attach() {
// use the "read" capability because conditions will handle actual access and save capability checking
// before the attach() method is called
// Add menu page
if ( ! $this->settings['parent'] ) {
add_menu_page(
$this->title,
$this->settings['menu_title'] ? $this->settings['menu_title'] : $this->title,
'read',
$this->get_page_file(),
array( $this, 'render' ),
$this->settings['icon'],
$this->settings['menu_position']
);
}
add_submenu_page(
$this->settings['parent'],
$this->title,
$this->settings['menu_title'] ? $this->settings['menu_title'] : $this->title,
'read',
$this->get_page_file(),
array( $this, 'render' )
);
$page_hook = get_plugin_page_hookname( $this->get_page_file(), '' );
add_action( 'load-' . $page_hook, array( $this, '_save' ) );
}
/**
* Whether this container is currently viewed.
*
* @return boolean
*/
public function should_activate() {
$input = stripslashes_deep( $_GET );
$request_page = isset( $input['page'] ) ? $input['page'] : '';
if ( ! empty( $request_page ) && $request_page === $this->get_page_file() ) {
return true;
}
return false;
}
/**
* Output the container markup
*/
public function render() {
$input = stripslashes_deep( $_GET );
$request_settings_updated = isset( $input['settings-updated'] ) ? $input['settings-updated'] : '';
if ( $request_settings_updated === 'true' ) {
$this->notifications[] = __( 'Settings saved.', 'carbon-fields' );
}
include \Carbon_Fields\DIR . '/templates/Container/' . $this->type . '.php';
}
/**
* Register the page while making sure it is unique.
*
* @return boolean
*/
protected function register_page() {
$file = $this->get_page_file();
$parent = $this->settings['parent'];
if ( ! $parent ) {
// Register top level page
if ( isset( static::$registered_pages[ $file ] ) ) {
Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" already registered' );
return false;
}
static::$registered_pages[ $file ] = array();
return true;
}
// Register sub-page
if ( ! isset( static::$registered_pages[ $parent ] ) ) {
static::$registered_pages[ $parent ] = array();
}
if ( in_array( $file, static::$registered_pages[ $parent ] ) ) {
Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" with parent "' . $parent . '" is already registered. Please set a name for the container.' );
return false;
}
static::$registered_pages[ $parent ][] = $file;
return true;
}
/**
* Change the parent theme options page of this container
*
* @param string|Theme_Options_Container $parent
* @return Container $this
*/
public function set_page_parent( $parent ) {
if ( is_a( $parent, static::class ) ) {
$this->settings['parent'] = $parent->get_page_file();
return $this;
}
$this->settings['parent'] = $parent;
return $this;
}
/**
* Get the theme options file name of this container.
*
* @return string
*/
public function get_page_file() {
if ( ! empty( $this->settings['file'] ) ) {
return $this->settings['file'];
}
return $this->title_to_filename( 'crb_' . $this->get_id(), '.php' );
}
/**
* Set the theme options file name of this container.
*
* @param string $file
* @return Container $this
*/
public function set_page_file( $file ) {
$this->settings['file'] = $file;
return $this;
}
/**
* Set the title of this container in the administration menu.
*
* @param string $title
* @return Container $this
*/
public function set_page_menu_title( $title ) {
$this->settings['menu_title'] = $title;
return $this;
}
/**
* Alias of the set_page_menu_position() method for backwards compatibility
*
* @param integer $position
* @return Container $this
*/
public function set_page_position( $position ) {
return $this->set_page_menu_position( $position );
}
/**
* Set the page position of this container in the administration menu.
*
* @param integer $position
* @return Container $this
*/
public function set_page_menu_position( $position ) {
$this->settings['menu_position'] = $position;
return $this;
}
/**
* Set the icon of this theme options page.
* Applicable only for parent theme option pages.
*
* @param string $icon
* @return Container $this
*/
public function set_icon( $icon ) {
$this->settings['icon'] = $icon;
return $this;
}
}

Some files were not shown because too many files have changed in this diff Show more