├── .gitignore ├── .gitlab-ci.yml ├── LICENSE ├── README.md ├── ci ├── patterns.txt ├── phpcs.phar ├── phpgrep-lint.sh └── ruleset.xml ├── elementBoilerplate ├── component.js ├── cssMixins │ └── boilerplateColorMixin.pcss ├── editor.css ├── index.js ├── public │ ├── preview-element-boilerplate.jpg │ └── thumbnail-element-boilerplate.png └── settings.json ├── manifest.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/dist/ 3 | !public/dist/.gitkeep 4 | .idea 5 | package-lock.json 6 | yarn.lock 7 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: node:10.13.0 2 | cache: 3 | key: ${CI_COMMIT_REF_SLUG} 4 | paths: 5 | - node_modules/ 6 | services: 7 | - mysql:5.7.28 8 | variables: 9 | # Configure mysql environment variables (https://hub.docker.com/_/mysql/) 10 | MYSQL_DATABASE: test 11 | MYSQL_ALLOW_EMPTY_PASSWORD: '1' 12 | stages: 13 | - codestyle 14 | - test 15 | - deploy 16 | before_script: 17 | ## https://docs.gitlab.com/ee/ci/ssh_keys/ 18 | ## Install ssh-agent if not already installed, it is required by Docker. 19 | ## (change apt-get to yum if you use an RPM-based image) 20 | ## 21 | - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' 22 | ## 23 | ## Run ssh-agent (inside the build environment) 24 | ## 25 | - eval $(ssh-agent -s) 26 | ## 27 | ## Create the SSH directory and give it the right permissions 28 | ## 29 | - mkdir -p ~/.ssh 30 | - chmod 700 ~/.ssh 31 | ## 32 | ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store 33 | ## We're using tr to fix line endings which makes ed25519 keys work 34 | ## without extra base64 encoding. 35 | ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556 36 | ## 37 | - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null 38 | - ssh-keyscan -H 'github.com' >> $HOME/.ssh/known_hosts 39 | - ssh-keyscan -H 'gitlab.com' >> $HOME/.ssh/known_hosts 40 | ## 41 | ## Optionally, if you will be using any Git commands, set the user name and 42 | ## and email. 43 | ## 44 | #- git config --global user.email "user@example.com" 45 | #- git config --global user.name "User name" 46 | # disable host key checking (NOTE: makes you susceptible to man-in-the-middle attacks) 47 | # WARNING: use only in docker container, if you use it with shell you will overwrite your user's ssh config 48 | - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config 49 | codestyle:js: 50 | image: node:10.13.0 51 | stage: codestyle 52 | script: 53 | - yarn install 54 | - yarn standard 55 | - yarn build 56 | - cat public/dist/element.bundle.js | grep "Cannot find module" && exit 1 57 | - if [ $? -eq 0 ]; then echo "good"; exit 0; else echo "fail"; exit 1; fi 58 | tags: 59 | - docker 60 | codestyle:php: 61 | image: wpbakery/phpcs 62 | stage: codestyle 63 | script: 64 | - php ci/phpcs.phar --standard=ci/ruleset.xml "$(basename $CI_PROJECT_DIR)/" 65 | tags: 66 | - docker 67 | test:end-2-end: 68 | image: visualcomposer/ci-wordpress:gitlab 69 | stage: test 70 | script: 71 | - if [ ! -f ./tests/cypress.json ]; then echo "no tests"; exit 0; fi; 72 | - sed -i 's/..\/..\/..\/..\/../\/\/var\/www\/html\/wp-content\/plugins\/visualcomposer/g' ./tests/cypress/plugins/index.js 73 | - sed -i 's/..\/..\/..\/..\/../\/\/var\/www\/html\/wp-content\/plugins\/visualcomposer/g' ./tests/cypress/support/index.js 74 | # Setup mysql and apache 75 | - mysql -h mysql --user="root" --execute="CREATE USER 'wpuser'@'%'; GRANT ALL PRIVILEGES ON test.* TO 'wpuser'@'%';" 76 | - apachectl restart 77 | # Install WordPress instance 78 | - wp core config --path=/var/www/html --dbhost=mysql --dbname=test --dbuser=wpuser --allow-root 79 | # Uncomment if you want to get more info about php errors in logs 80 | # - sed -i "s/\$table_prefix = 'wp_';/\$table_prefix = 'wp_';\nini_set('display_errors', 1);\nini_set('display_startup_errors', 1);\nerror_reporting(E_ALL);\ndefine('WP_DEBUG', true);\ndefine('VCV_DEBUG', true);\ndefine('WP_DEBUG_LOG', '\/builds\/visualcomposer-hub\/$CI_PROJECT_NAME\/logs.log');/" /var/www/html/wp-config.php 81 | - wp core install --url=http://localhost --title=Test --admin_user=admin --admin_password=12345 --admin_email=test@test.com --path=/var/www/html --allow-root --debug 82 | - chmod -R 777 /var/www/html/wp-content/uploads 83 | # Add Visual Composer plugin to WordPress instance 84 | - cd /var/www/html/wp-content/plugins 85 | - vc_latest_release_version=$(curl --silent "https://api.github.com/repos/VisualComposer/builder/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') 86 | - echo $vc_latest_release_version 87 | - curl -OL "https://github.com/VisualComposer/builder/releases/download/$vc_latest_release_version/visualcomposer.zip" 88 | - unzip ./visualcomposer.zip 89 | - cd visualcomposer 90 | - mkdir devElements devAddons 91 | - echo " env-dev.php 92 | # Add element to project 93 | - ln -s $CI_PROJECT_DIR /var/www/html/wp-content/plugins/visualcomposer/devElements/ 94 | - cd ./devElements/$(basename $CI_PROJECT_DIR)/ 95 | - yarn install 96 | - yarn build 97 | # Setup plugins and themes 98 | - wp plugin uninstall akismet --path=/var/www/html --allow-root 99 | - wp plugin activate --all --path=/var/www/html --allow-root 100 | - wp theme install visual-composer-starter --path=/var/www/html --activate --allow-root 101 | - yarn run cypress run --browser=chrome --project ./tests 102 | artifacts: 103 | when: on_failure 104 | expire_in: 1 day 105 | paths: 106 | - tests/cypress/screenshots 107 | - tests/cypress/videos 108 | # Uncomment for php logs 109 | # - logs 110 | deploying: 111 | image: node:10.13.0 112 | stage: deploy 113 | script: 114 | - "ELEMENT_TITLE=`node -e \"var manifest = require('./manifest.json');console.log(encodeURIComponent(manifest.elements[Object.keys(manifest.elements)[0]].settings.name));\"`" 115 | - "ELEMENT_TAG=`node -e \"var manifest = require('./manifest.json');console.log(Object.keys(manifest.elements)[0]);\"`" 116 | - "echo \"$CI_HUB_GROUP_TEST_DOMAIN/api/inner/bundle/create?key=$CI_HUB_GROUP_ELEMENTS_BUILD_KEY&bundle=element/$ELEMENT_TAG&version=latest&name=$ELEMENT_TITLE&branch=$CI_COMMIT_REF_NAME\"" 117 | - "curl -X GET -H 'Content-type: application/json' \"$CI_HUB_GROUP_TEST_DOMAIN/api/inner/bundle/create?key=$CI_HUB_GROUP_ELEMENTS_BUILD_KEY&bundle=element/$ELEMENT_TAG&version=latest&name=$ELEMENT_TITLE&branch=$CI_COMMIT_REF_NAME\"" 118 | tags: 119 | - docker -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VCWB Elements API 2 | 3 | ## What is an element 4 | The element is the independent part of the system which represents HTML based block with the ability to output media and dynamic content. 5 | 6 | ## How does it work? 7 | The editor works with elements as React components. These components must be built with webpack and enqueued by API. 8 | Every element has preview, thumbnail, category and React-based component. 9 | 10 | ### Element structure 11 | 12 | Elements contains 13 | - manifest.json - describes element data, preview, thumbnail, category and php files. 14 | - package.json - npm install/update files for required node modules 15 | 16 | Directory {tag} (must be renamed to src): 17 | - index.js - the main file, build with Webpack 18 | - component.js - ReactJs component contains VCWB editor component. This component is used only in the editor. 19 | - settings.json - Describes element attributes 20 | - *.php files - Required PHP files(must be described in ../manifest.json) 21 | - editor.css - CSS files which will be used only in the editor 22 | - style.css - CSS files which will be used on the frontend to display content. 23 | - cssMixins - directory that holds POSTCSS (*.pcss) files with mixin for custom generated styles 24 | 25 | ### Requirements 26 | - node > 10.0, recommended latest 27 | - PHP > 7.0, recommended latest 28 | 29 | ## Installation 30 | - To work with the element, each element is independent 31 | - Run `yarn install` in the element directory 32 | - Build via `yarn build` 33 | - Once the element is built it will appear in the editor 34 | 35 | ### Commands 36 | ``` 37 | yarn install // Install all the element dependencies (must be same as visualcomposer) 38 | yarn build // Build development build 39 | yarn watch // Watches & Build development version on file modification 40 | yarn build-production // Builds the minified build 41 | ``` 42 | -------------------------------------------------------------------------------- /ci/patterns.txt: -------------------------------------------------------------------------------- 1 | # Self-assignments are a bad smell in 99% of cases. 2 | '$x = $x' 3 | 4 | # Suspicious empty body of the if statement. 5 | 'if ($_);' 6 | 7 | # Using "==" instead of "=" inside init context. 8 | 'for ($_ == $_; $_; $_) $_' 9 | 10 | # Using assignment as expression inside boolean context. 11 | 'for ($_; $_ = []; $_) $_' 12 | 'for ($_; $_ = ${"const"}; $_) $_' 13 | 'for ($_; $_ = ${"num"}; $_) $_' 14 | 'for ($_; $_ = ${"str"}; $_) $_' 15 | 'while ($_ = []) $_' 16 | 'while ($_ = ${"const"}) $_' 17 | 'while ($_ = ${"num"}) $_' 18 | 'while ($_ = ${"str"}) $_' 19 | 'if ($_ = []) $_' 20 | 'if ($_ = ${"const"}) $_' 21 | 'if ($_ = ${"str"}) $_' 22 | 'if ($_ = ${"num"}) $_' 23 | '$_ = [] ? $_ : $_' 24 | '$_ = ${"const"} ? $_ : $_' 25 | '$_ = ${"str"} ? $_ : $_' 26 | '$_ = ${"num"} ? $_ : $_' 27 | '($_ = []) && $_' 28 | '($_ = ${"const"}) && $_' 29 | '($_ = ${"str"}) && $_' 30 | '($_ = ${"num"}) && $_' 31 | '$_ && $_ = []' 32 | '$_ && $_ = ${"const"}' 33 | '$_ && $_ = ${"str"}' 34 | '$_ && $_ = ${"num"}' 35 | '($_ = []) || $_' 36 | '($_ = ${"const"}) || $_' 37 | '($_ = ${"str"}) || $_' 38 | '($_ = ${"num"}) || $_' 39 | '$_ || $_ = []' 40 | '$_ || $_ = ${"const"}' 41 | '$_ || $_ = ${"str"}' 42 | '$_ || $_ = ${"num"}' 43 | 44 | # Suspicious (and sometimes always true/false) boolean expressions. 45 | '$x == $x' 46 | '$x === $x' 47 | '$x && !$x' 48 | '$x || !$x' 49 | '$x || $a && !$x' 50 | '$x != $a || $x != $b' 51 | '$x !== $a || $x != $b' 52 | '$x != $a || $x !== $b' 53 | '$x !== $a || $x !== $b' 54 | '$x == $a || $x != $b' 55 | '$x == $a || $x !== $b' 56 | '$x === $a || $x != $b' 57 | '$x === $a || $x !== $b' 58 | '$x == $a && $x != $b' 59 | '$x == $a && $x !== $b' 60 | '$x === $a && $x != $b' 61 | '$x === $a && $x !== $b' 62 | 63 | # Potential issues due to the operators precedence. 64 | '$x & $mask == $y' 65 | '$x & $mask === $y' 66 | '$x & $mask !== $y' 67 | '$x & $mask != $y' 68 | '$x | $mask == $y' 69 | '$x | $mask === $y' 70 | '$x | $mask !== $y' 71 | '$x | $mask != $y' 72 | 73 | # Potentially incorrect usage of ternary operator (due to the precedence). 74 | '$_ == $_ ? $_ : $_ ? $_ : $_' 75 | '$_ === $_ ? $_ : $_ ? $_ : $_' 76 | '$_ != $_ ? $_ : $_ ? $_ : $_' 77 | '$_ !== $_ ? $_ : $_ ? $_ : $_' 78 | 79 | # Duplicated true-false branches. 80 | '$_ ? $x : $x' 81 | 'if ($cond) $x; else $x' 82 | 83 | # Incorrect/suspicious order of arguments. 84 | 'stripos(${"str"}, ${"*"})' 85 | 'strpos(${"str"}, ${"*"})' 86 | 'explode($_, ${"str"}, ${"*"})' 87 | 'array_diff($x, $x)' 88 | 'array_intersect($x, $x)' 89 | 'array_filter(${"func"}, $_)' 90 | 'array_reduce(${"func"}, $_)' 91 | 'array_map($_, ${"func"})' 92 | 93 | # Calls that always lead to unwanted results. 94 | 'explode("", ${"*"})' 95 | 96 | # Duplicated sub-expressions inside boolean expressions. 97 | '$x && $x' 98 | '$x && $_ && $x' 99 | '$x && $_ && $_ && $x' 100 | '$x && $_ && $_ && $_ && $x' 101 | '$x || $x' 102 | '$x || $_ || $x' 103 | '$x || $_ || $_ || $x' 104 | '$x || $_ || $_ || $_ || $x' 105 | 106 | # Duplicated array keys. 107 | '[${"*"}, $k => $_, ${"*"}, $k => $_, ${"*"}]' 108 | 109 | # Using "==" for string comparison (should use "===" instead). 110 | '${"s:str"} == $x' 's~^.\d' 111 | '$x == ${"s:str"}' 's~^.\d' 112 | 113 | # Using "==" when comparing against falsy constant. 114 | 'false == $x' 115 | '$x == false' 116 | 'null == $x' 117 | '$x == null' 118 | 'false != $x' 119 | '$x != false' 120 | 'null != $x' 121 | '$x != null' 122 | 123 | # Find unescaped "." (dots) inside regexps that match URLs. 124 | 'preg_match(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 125 | 'preg_match_all(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 126 | 'preg_replace(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 127 | 'preg_replace_callback(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 128 | 'preg_replace_callback_array(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 129 | 'preg_filter(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 130 | 'preg_grep(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 131 | 'preg_split(${"pat:str"}, ${"*"})' 'pat~[^\\]\.(com|ru|net|org|edu|gov|uk|de|lv)\b' 132 | 133 | # Find new calls without parentheses. 134 | 'new $t' 135 | 136 | # Find all if statements with a body without {}. 137 | 'if ($cond) $x' 'x!~^\{' 138 | # or without expression 139 | 'if ($code) ${"expr"}' 140 | 141 | # All silenced 142 | '@$_' 143 | 144 | # 145 | '$${"var"}' 146 | '${${"var"}}' 147 | -------------------------------------------------------------------------------- /ci/phpcs.phar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VisualComposer/elementBoilerplate/954a9970e2a1b744006cb1ec41747ccfb21803e6/ci/phpcs.phar -------------------------------------------------------------------------------- /ci/phpgrep-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -eq 0 ]; then 4 | echo 'Usage: phpgrep-lint.sh target patterns_file' 5 | echo 'Where:' 6 | echo ' target is a file or directory name where search is performed.' 7 | echo ' patterns_file is a file with newline-separated phpgrep pattern args.' 8 | echo ' File can contain #-comments and empty lines.' 9 | echo '' 10 | echo 'Examples:' 11 | echo ' ./phpgrep-lint.sh file.php patterns.txt' 12 | echo ' ./phpgrep-lint.sh /path/to/code /path/to/patterns.txt' 13 | echo '' 14 | echo 'Exit status:' 15 | echo ' 0 if no issues are found' 16 | echo ' 1 if any of provided patterns matched anything' 17 | exit 1 18 | fi 19 | 20 | flag_target=$1 21 | flag_patterns_file=$2 22 | 23 | if [ -z "$flag_target" ]; then 24 | echo "target argument (1st positional) can't be empty" 25 | exit 1 26 | fi 27 | if [ -z "$flag_patterns_file" ]; then 28 | echo "patterns filename argument (2nd positional) can't be empty" 29 | exit 1 30 | fi 31 | 32 | mapfile -t patterns < "$flag_patterns_file" 33 | 34 | found_issues=0 35 | 36 | for pattern in "${patterns[@]}"; do 37 | # Treat lines starting with "#" as comments. 38 | if [ "${pattern:0:1}" = '#' ]; then 39 | continue 40 | fi 41 | # Skip empty lines. 42 | if [ -z "$pattern" ]; then 43 | continue 44 | fi 45 | 46 | # $pattern is unquoted on purpose, to allow passing filter args as well. 47 | # phpgrep "$flag_target" ${pattern[@]} 48 | eval phpgrep "$flag_target" $pattern 49 | 50 | # phpgrep exits with zero status if it finds anything. 51 | # We use "bad code" patterns, so if we matched something, 52 | # we've found some suspicious code bits. 53 | if [ $? -eq 0 ]; then 54 | found_issues=1 55 | fi 56 | done 57 | 58 | exit $found_issues 59 | -------------------------------------------------------------------------------- /ci/ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | A custom coding standard 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ./visualcomposer/resources/* 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ./visualcomposer/Requirements.php 66 | ./visualcomposer/Env.php 67 | 68 | 69 | ./visualcomposer/Requirements.php 70 | ./visualcomposer/Env.php 71 | 72 | 73 | ./plugin-wordpress.php 74 | 75 | 76 | ./visualcomposer 77 | ./bootstrap 78 | ./plugin-wordpress.php 79 | 80 | 81 | tests/* 82 | vendor/* 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /elementBoilerplate/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { getService } from 'vc-cake' 3 | 4 | const vcvAPI = getService('api') 5 | 6 | export default class ElementBoilerplate extends vcvAPI.elementComponent { 7 | render () { 8 | const { id, atts, editor } = this.props 9 | const { output, customClass, metaCustomId } = atts // destructuring assignment for attributes from settings.json with access public 10 | let elementBoilerplateClasses = 'vce-element-boilerplate' 11 | const wrapperClasses = 'vce-element-boilerplate-wrapper vce' 12 | const customProps = {} 13 | if (typeof customClass === 'string' && customClass) { 14 | elementBoilerplateClasses = elementBoilerplateClasses.concat(' ' + customClass) 15 | } 16 | 17 | const mixinData = this.getMixinData('boilerplateColorMixin') 18 | if (mixinData) { 19 | elementBoilerplateClasses = elementBoilerplateClasses.concat(` vce-element-boilerplate--color-${mixinData.selector}`) 20 | } 21 | 22 | if (metaCustomId) { 23 | customProps.id = metaCustomId 24 | } 25 | 26 | const doAll = this.applyDO('all') 27 | 28 | return ( 29 |
30 |
31 | {output} 32 |
33 |
34 | ) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /elementBoilerplate/cssMixins/boilerplateColorMixin.pcss: -------------------------------------------------------------------------------- 1 | .vce-element-boilerplate--color-$selector { 2 | color: $color; 3 |   &:hover { 4 |   color: color($color shade(10%)); 5 | } 6 | } -------------------------------------------------------------------------------- /elementBoilerplate/editor.css: -------------------------------------------------------------------------------- 1 | .vce-element-boilerplate { 2 | min-height: 1em; 3 | } 4 | -------------------------------------------------------------------------------- /elementBoilerplate/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-webpack-loader-syntax */ 2 | import { getService } from 'vc-cake' 3 | import ElementBoilerplate from './component' 4 | 5 | const vcvAddElement = getService('cook').add 6 | 7 | vcvAddElement( 8 | require('./settings.json'), 9 | // Component callback 10 | function (component) { 11 | component.add(ElementBoilerplate) 12 | }, 13 | // css settings // css for element 14 | { 15 | css: false, 16 | editorCss: require('raw-loader!./editor.css'), 17 | mixins: { 18 | boilerplateColorMixin: { 19 | mixin: require('raw-loader!./cssMixins/boilerplateColorMixin.pcss') 20 | } 21 | } 22 | } 23 | ) 24 | -------------------------------------------------------------------------------- /elementBoilerplate/public/preview-element-boilerplate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VisualComposer/elementBoilerplate/954a9970e2a1b744006cb1ec41747ccfb21803e6/elementBoilerplate/public/preview-element-boilerplate.jpg -------------------------------------------------------------------------------- /elementBoilerplate/public/thumbnail-element-boilerplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VisualComposer/elementBoilerplate/954a9970e2a1b744006cb1ec41747ccfb21803e6/elementBoilerplate/public/thumbnail-element-boilerplate.png -------------------------------------------------------------------------------- /elementBoilerplate/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "type": "htmleditor", 4 | "access": "public", 5 | "value": "

ElementBoilerplate API. HTML editor is also the part of the editor

", 6 | "options": { 7 | "label": "Content", 8 | "description": "Content for text block", 9 | "inline": true, 10 | "skinToggle": "lightTextSkin" 11 | } 12 | }, 13 | "color": { 14 | "type": "color", 15 | "access": "public", 16 | "value": "#000", 17 | "options": { 18 | "label": "Title color", 19 | "cssMixin": { 20 | "mixin": "boilerplateColorMixin", 21 | "property": "color", 22 | "namePattern": "[\\da-f]+" 23 | } 24 | } 25 | }, 26 | "darkTextSkin": { 27 | "type": "toggleSmall", 28 | "access": "public", 29 | "value": false 30 | }, 31 | "designOptions": { 32 | "type": "designOptions", 33 | "access": "public", 34 | "value": {}, 35 | "options": { 36 | "label": "Design Options" 37 | } 38 | }, 39 | "editFormTab1": { 40 | "type": "group", 41 | "access": "protected", 42 | "value": [ 43 | "output", 44 | "color", 45 | "metaCustomId", 46 | "customClass" 47 | ], 48 | "options": { 49 | "label": "General" 50 | } 51 | }, 52 | "metaEditFormTabs": { 53 | "type": "group", 54 | "access": "protected", 55 | "value": [ 56 | "editFormTab1", 57 | "designOptions" 58 | ] 59 | }, 60 | "relatedTo": { 61 | "type": "group", 62 | "access": "protected", 63 | "value": [ 64 | "General" 65 | ] 66 | }, 67 | "customClass": { 68 | "type": "string", 69 | "access": "public", 70 | "value": "", 71 | "options": { 72 | "label": "Extra class name", 73 | "description": "Add an extra class name to the element and refer to it from Custom CSS option." 74 | } 75 | }, 76 | "metaCustomId": { 77 | "type": "customId", 78 | "access": "public", 79 | "value": "", 80 | "options": { 81 | "label": "Element ID", 82 | "description": "Apply unique ID to element to link directly to it by using #your_id (for element ID use lowercase input only)." 83 | } 84 | }, 85 | "tag": { 86 | "access": "protected", 87 | "type": "string", 88 | "value": "elementBoilerplate" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "elements": { 3 | "elementBoilerplate": { 4 | "settings": { 5 | "name": "Element Boilerplate", 6 | "metaThumbnailUrl": "[publicPath]/thumbnail-element-boilerplate.png", 7 | "metaPreviewUrl": "[publicPath]/preview-element-boilerplate.jpg", 8 | "metaDescription": "Simple element boilerplate for working with static text, including paragraphs, titles, bullets and even media. Simple text block is a copy of default WordPress editor." 9 | } 10 | } 11 | }, 12 | "categories": { 13 | "Misc": { 14 | "elements": [ 15 | "elementBoilerplate" 16 | ] 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vcwb", 3 | "version": "dev", 4 | "license": "SEE LICENSE IN ", 5 | "description": "Visual Composer Website Builder", 6 | "main": "index.php", 7 | "repository": { 8 | "type": "git", 9 | "url": "git@github.com:Visualcomposer/builder.git" 10 | }, 11 | "scripts": { 12 | "standard": "standard --version && standard", 13 | "build": "webpack --version && webpack --config=./node_modules/vc-webpack-vendors/webpack.config.js", 14 | "build-production": "webpack --version && webpack --config=./node_modules/vc-webpack-vendors/webpack.config.production.js", 15 | "watch": "webpack --version && webpack --config=./node_modules/vc-webpack-vendors/webpack.config.js --watch" 16 | }, 17 | "devDependencies": { 18 | "vc-webpack-vendors": "3.3.3" 19 | }, 20 | "babel": { 21 | "presets": [ 22 | "@babel/preset-env", 23 | "@babel/preset-react" 24 | ], 25 | "plugins": [ 26 | "@babel/plugin-transform-runtime", 27 | "@babel/plugin-proposal-class-properties" 28 | ] 29 | }, 30 | "standard": { 31 | "parser": "babel-eslint", 32 | "ignore": [ 33 | "public/dist/", 34 | "tests/", 35 | "**/public/js" 36 | ], 37 | "rules": { 38 | "jsx-quotes": [ 39 | 2, 40 | "prefer-single" 41 | ], 42 | "import/no-webpack-loader-syntax": "off" 43 | } 44 | }, 45 | "resolutions": { 46 | "core-js": "3.25.5", 47 | "postcss": "8.4.18", 48 | "css-loader": "6.7.1", 49 | "color-name": "1.1.4", 50 | "eslint": "8.25.0", 51 | "less": "4.1.3", 52 | "raw-loader": "1.0.0", 53 | "@babel/runtime": "7.19.4" 54 | }, 55 | "browserslist": [ 56 | ">1%", 57 | "ios_saf 8", 58 | "ie 10", 59 | "ie 11" 60 | ] 61 | } 62 | --------------------------------------------------------------------------------