diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..6ef2d1eaa --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,17 @@ +Hi there! Thanks for helping out in improving Eightshift Libs. + +## Reporting an issue + +If you are not sure how something works be sure to read our [readme](https://github.com/infinum/eightshift-libs/blob/master/README.md) and [wiki](https://github.com/infinum/eightshift-libs/wiki). If you found a bug in the code, please [open an issue](https://github.com/infinum/eightshift-libs/issues/new) and follow the instructions in the issue template. + +## Contributing patches and new features + +If you found a bug and want to fix it, or you want to add some new and cool feature, [fork](https://github.com/infinum/wp-boilerplate#fork-destination-box) our repository, then create a `feature` branch from the `master` branch. For instance `feature/some-bug-fix` or `feature/some-cool-new-feature`. + +Once you've coded things up, be sure you check that your code is following our [coding standards](https://github.com/infinum/coding-standards-wp). Also test that your code isn't breaking anything :) + +Then submit a pull request to `develop` branch. Once we check everything we'll merge the changes into `master` with correct version correction (noted by the milestone flag and `future release` tag). + +## Integration testing + +If you want to create integration tests for your code that would be great. We will add some in due time, and they are not necessary for a PR. diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 000000000..82e342b11 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,35 @@ + + + + + + +## Current Behavior + + + +## Expected Behavior + + + +## Possible Solution + + + +## Steps to Reproduce (for bugs) + + +1. +2. +3. +4. + +## Your Environment + +* PHP version: +* Development environment: +* Server type: +* Operating System and version: diff --git a/.gitignore b/.gitignore index 22d0d82f8..91be243cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor +node_modules diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..08bdd0506 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at team@eightshift.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/README.md b/README.md index ae733528e..86cbc3aff 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,29 @@ # Eightshift Libs -TBD +This library is aimed at bringing the modern development tools to the [Eightshift WordPress Boilerplate](https://github.com/infinum/wp-boilerplate), but you can use it on any WordPress project. + +It uses central service instantiator that instatiates all classes that obey single responsibility principle (SRP). Every class is responsible for registering its own hooks. This provides a more testable environment for your project. + +We provide some helpers, abstract classes, interfaces and abstractions on original WordPress functionlality to help you write more modern code. + +Provided functionality: +* Main theme/plugin entrypoint. +* Post Type Registration. +* Taxonomy Registration. +* Gutenberg Blocks Registration. +* Assets Manifest data. + +## :mailbox: Who do I talk to? + +For questions talk to: + +* [ivan.ruzevic@infinum.hr](ivan.ruzevic@infinum.hr) +* [denis.zoljom@infinum.hr](denis.zoljom@infinum.hr) +* [ivan.grginov@infinum.hr](ivan.grginov@infinum.hr) +* [team@eightshift.com](team@eightshift.com) + +Eightshift WordPress Boilerplate is maintained and sponsored by Eightshift and Infinum. + +## :scroll: License + +Eightshift WordPress Boilerplate is Copyright ©2019 Eightshift. It is free software, and may be redistributed under the terms specified in the LICENSE file. diff --git a/bin/lintPhp.sh b/bin/lintPhp.sh new file mode 100644 index 000000000..2009ce28a --- /dev/null +++ b/bin/lintPhp.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# pre-commit.sh +# +# This hook is ran every time a commit is attempted. For commit to pass, the minimum requirement is that +# WPCS checks pass. + +PROJECT=`php -r "echo dirname(dirname(realpath('$0')));"` +STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php` + +#Determine if a file list is passed +if [ "$#" -eq 1 ] +then + oIFS=$IFS + IFS=' + ' + SFILES="$1" + IFS=$oIFS +fi +SFILES=${SFILES:-$STAGED_FILES_CMD} + +echo "-----------------" +echo "Checking PHP Lint" +echo "-----------------" +for FILE in $SFILES +do + php -l -d display_errors=0 $PROJECT/$FILE + if [ $? != 0 ] + then + echo "Fix the error before commit." + exit 1 + fi + FILES="$FILES $PROJECT/$FILE" +done + +if [ "$FILES" != "" ] +then + echo "--------------------" + echo "Running Code Sniffer" + echo "--------------------" + composer check-cs -- -p --parallel=4 --colors $FILES + if [ $? != 0 ] + then + echo "Possible warnings and errors found." + exit 1 + fi +fi + +exit $? diff --git a/composer.lock b/composer.lock index 50de2d975..231b36033 100644 --- a/composer.lock +++ b/composer.lock @@ -284,16 +284,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.4.1", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "5b4333b4010625d29580eb4a41f1e53251be6baa" + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5b4333b4010625d29580eb4a41f1e53251be6baa", - "reference": "5b4333b4010625d29580eb4a41f1e53251be6baa", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", "shasum": "" }, "require": { @@ -331,7 +331,7 @@ "phpcs", "standards" ], - "time": "2019-03-19T03:22:27+00:00" + "time": "2019-04-10T23:49:02+00:00" }, { "name": "wp-coding-standards/wpcs", diff --git a/examples/admin/class-register-post-type.php b/examples/admin/class-example-faq-post-type.php similarity index 92% rename from examples/admin/class-register-post-type.php rename to examples/admin/class-example-faq-post-type.php index 3affd0477..9c83557af 100644 --- a/examples/admin/class-register-post-type.php +++ b/examples/admin/class-example-faq-post-type.php @@ -3,10 +3,12 @@ * File that holds faq custom post type registration details * * @since 1.0.0 - * @package Custom_Namespace\Admin + * @package Custom_Namespace\Examples + * + * TODO: Refactor and test */ -namespace Custom_Namespace\Admin; +namespace Custom_Namespace\Examples; use Eightshift_Libs\Custom_Post_Type\Base_Post_Type; use Eightshift_Libs\Custom_Post_Type\Label_Generator; @@ -16,7 +18,7 @@ * * @since 1.0.0 */ -final class Faq extends Base_Post_Type { +final class Example_Faq_Post_Type extends Base_Post_Type { /** * The custom post type type slug diff --git a/examples/admin/class-register-taxonomy.php b/examples/admin/class-example-faq-taxonomy.php similarity index 89% rename from examples/admin/class-register-taxonomy.php rename to examples/admin/class-example-faq-taxonomy.php index 1c8c94924..894872871 100644 --- a/examples/admin/class-register-taxonomy.php +++ b/examples/admin/class-example-faq-taxonomy.php @@ -3,22 +3,24 @@ * File that holds taxonomy class for fax taxonomy registration * * @since 1.0.0 - * @package Custom_Namespace\Admin + * @package Custom_Namespace\Examples + * + * TODO: Refactor and test */ -namespace Custom_Namespace\Admin; +namespace Custom_Namespace\Examples; use Eightshift_Libs\Custom_Taxonomy\Base_Taxonomy; use Eightshift_Libs\Custom_Post_Type\Label_Generator; -use Custom_Namespace\Admin\Faq; +use Custom_Namespace\Examples\Example_Faq_Post_Type; /** - * Class Faq_Taxonomy. + * Class Example_Faq_Taxonomy. * * @since 1.0.0 */ -class Faq_Taxonomy extends Base_Taxonomy { +class Example_Faq_Taxonomy extends Base_Taxonomy { /** * The systems custom taxonomy type slug * diff --git a/examples/blocks/heading/class-heading.php b/examples/blocks/heading/class-example-heading.php similarity index 92% rename from examples/blocks/heading/class-heading.php rename to examples/blocks/heading/class-example-heading.php index c259d09e8..f3beb0964 100644 --- a/examples/blocks/heading/class-heading.php +++ b/examples/blocks/heading/class-example-heading.php @@ -4,6 +4,8 @@ * * @since 1.0.0 * @package Custom_Namespace\Blocks\Heading + * + * TODO: Refactor and test */ namespace Custom_Namespace\Blocks\Heading; @@ -13,7 +15,7 @@ /** * Class Heading */ -class Heading extends Base_Block { +class Example_Heading extends Base_Block { /** * Block's name. diff --git a/examples/includes/class-main.php b/examples/class-example-main.php similarity index 77% rename from examples/includes/class-main.php rename to examples/class-example-main.php index 771cf621b..45495f40a 100644 --- a/examples/includes/class-main.php +++ b/examples/class-example-main.php @@ -2,14 +2,16 @@ /** * The file that defines the main start class * - * A class definition that includes attributes and functions used across both the + * A class definition that Core attributes and functions used across both the * theme-facing side of the site and the admin area. * * @since 1.0.0 - * @package Custom_Namespace\Includes + * @package Custom_Namespace\Core + * + * TODO: Refactor and test */ -namespace Custom_Namespace\Includes; +namespace Custom_Namespace\Core; use Eightshift_Libs\Core\Main as LibMain; @@ -24,7 +26,7 @@ * Also maintains the unique identifier of this theme as well as the current * version of the theme. */ -class Main extends LibMain { +class Example_Main extends LibMain { /** * Get the list of services to register. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..b62460ef3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,496 @@ +{ + "name": "eightshift_libs", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.0.tgz", + "integrity": "sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.0", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "husky": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-1.3.1.tgz", + "integrity": "sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.7", + "execa": "^1.0.0", + "find-up": "^3.0.0", + "get-stdin": "^6.0.0", + "is-ci": "^2.0.0", + "pkg-dir": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "read-pkg": "^4.0.1", + "run-node": "^1.0.0", + "slash": "^2.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "please-upgrade-node": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", + "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", + "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..41edef2ea --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "eightshift_libs", + "version": "1.0.0", + "author": "Team Eightshift", + "main": "", + "scripts": { + "lint": "bash bin/lintPhp.sh" + }, + "devDependencies": { + "husky": "^1.3.1" + }, + "dependencies": {}, + "husky": { + "hooks": { + "pre-commit": "npm run lint" + } + } +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 4441c7318..a9ec02154 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -4,6 +4,10 @@ + */tests/* + */vendor/* + */node_modules/* + 0 diff --git a/src/assets/class-manifest.php b/src/assets/class-manifest.php new file mode 100644 index 000000000..67706e15f --- /dev/null +++ b/src/assets/class-manifest.php @@ -0,0 +1,48 @@ +get_manifest_url(); + if ( ! file_exists( $manifest ) ) { + $error_message = esc_html__( 'manifest.json is missing. Bundle the theme before using it.', 'developer-portal' ); + throw Exception\Missing_Manifest::message( $error_message ); + } + + return implode( ' ', file( $manifest ) ); + } +} diff --git a/src/blocks/class-base-block.php b/src/blocks/class-base-block.php index 15bf47338..1cf014c5f 100644 --- a/src/blocks/class-base-block.php +++ b/src/blocks/class-base-block.php @@ -9,22 +9,14 @@ namespace Eightshift_Libs\Blocks; use Eightshift_Libs\Blocks\Block; +use Eightshift_Libs\Blocks\Renderable_Block; use Eightshift_Libs\Core\Service; use Eightshift_Libs\Exception\Missing_Block_Name; /** * Class Block */ -abstract class Base_Block extends Attribute_Type_Enums implements Block { - - /** - * Block Name. - * - * @var string - * - * @since 1.0.0 - */ - const NAME = 'abstract-block'; +abstract class Base_Block extends Attribute_Type_Enums implements Block, Service, Renderable_Block { /** * Namespace in which all our blocks exist. @@ -45,7 +37,7 @@ public function register() : void { 'init', function() { register_block_type( - static::BLOCK_NAMESPACE . '/' . static::NAME, + $this->get_block_namespace() . '/' . $this->get_block_name(), array( 'render_callback' => [ $this, 'render' ], 'attributes' => $this->get_attributes(), @@ -55,10 +47,52 @@ function() { ); } + /** + * Get the block name to use to register block. + * + * @return string Custom blog name. + * + * @since 1.0.0 + */ + abstract protected function get_block_name() : string; + + /** + * Get the block name to use to register block. + * + * @return string Custom blog name. + * + * @since 1.0.0 + */ + protected function get_block_namespace() : string { + return static::BLOCK_NAMESPACE; + } + + /** + * Get block attributes assigned inside block class. + * + * @return array + * + * @since 1.0.0 + */ + abstract public function get_block_attributes() : array; + + /** + * Get block view path. + * + * @return string + * + * @since 1.0.0 + */ + public function get_block_view_path() { + $block_name = $this->get_block_name(); + + return 'src/blocks/' . $block_name . '/view/' . $block_name . '.php'; + } + /** * Adds default attributes that are dynamically built for all blocks. * These are: - * - blockName: Block's full name including namespace (example: infinum/heading) + * - blockName: Block's full name including namespace (example: eightshift/heading) * - rootClass: Block's root (base) BEM CSS class, built in "block/$name" format (example: block-heading) * - jsClass: Block's js selector class, built in "js-block-$name" format (example: js-block-heading) * @@ -69,40 +103,25 @@ function() { * @since 1.0.0 */ public function get_default_attributes() : array { - - // Make sure the class (block) extending this class (abstract Base_Block) - // has defined its own name. - if ( static::NAME === self::NAME ) { - throw Missing_Block::name_exception(); - } + $block_namespace = $this->get_block_namespace(); + $block_name = $this->get_block_name(); return [ 'blockName' => array( 'type' => parent::TYPE_STRING, - 'default' => self::BLOCK_NAMESPACE . '/' . static::NAME, + 'default' => "{$block_namespace}/{$block_name}", ), 'rootClass' => array( 'type' => parent::TYPE_STRING, - 'default' => 'block-' . static::NAME, + 'default' => "block-{$block_name}", ), 'jsClass' => array( 'type' => parent::TYPE_STRING, - 'default' => 'js-block-' . static::NAME, + 'default' => "js-block-{$block_name}", ), ]; } - /** - * Get block attributes assigned inside block class. - * - * @return array - * - * @since 1.0.0 - */ - public function get_block_attributes() : array { - return []; - } - /** * Get all block attributes. Default and block attributes. * @@ -124,25 +143,17 @@ public function get_attributes() : array { * @param array $attributes Array of attributes as defined in block's index.js. * @param string $content Block's content. * - * @throws \Exception On missing attributes OR missing template. - * @echo string + * @throws Missing_Block::view_exception On missing attributes OR missing template. + * @return string html template for block. * * @since 1.0.0 */ public function render( array $attributes, string $content ) : string { + $template_path = $this->get_block_view_path(); - // Block must have a defined name to find its template. - // Make sure the class (block) extending this class (abstract Base_Block) - // has defined its own name. - if ( static::NAME === self::NAME ) { - throw Missing_Block::name_exception(); - } - - $template_path = 'src/blocks/' . static::NAME . '/view/' . static::NAME . '.php'; - $template = locate_template( $template_path ); - + $template = locate_template( $template_path ); if ( empty( $template ) ) { - throw Missing_Block::view_exception( static::NAME, $template_path ); + throw Missing_Block::view_exception( $this->get_block_name(), $template_path ); } // If everything is ok, return the contents of the template (return, NOT echo). diff --git a/src/blocks/interface-block.php b/src/blocks/interface-block.php index 8fbc6ad91..391eaea23 100644 --- a/src/blocks/interface-block.php +++ b/src/blocks/interface-block.php @@ -13,42 +13,6 @@ */ interface Block { - /** - * Register the current registrable. - * - * A register method holds the plugin action and filter hooks. - * Following the single responsibility principle, every class - * holds a functionality for a certain part of the plugin. - * This is why every class should hold its own hooks. - * - * @return void - * - * @since 1.0.0 - */ - public function register() : void; - - /** - * Adds default attributes that are dynamically built for all blocks. - * These are: - * - blockName: Block's full name including namespace (example: Infinum/heading) - * - rootClass: Block's root (base) BEM CSS class, built in "block/$name" format (example: block-heading) - * - jsClass: Block's js selector class, built in "js-block-$name" format (example: js-block-heading) - * - * @return array - * - * @since 1.0.0 - */ - public function get_default_attributes() : array; - - /** - * Get block attributes assigned inside block class. - * - * @return array - * - * @since 1.0.0 - */ - public function get_block_attributes() : array; - /** * Get all block attributes. Default and block attributes. * @@ -57,20 +21,4 @@ public function get_block_attributes() : array; * @since 1.0.0 */ public function get_attributes() : array; - - /** - * Renders the block using a template in Infinum\Blocks\Templates namespace/folder. - * Template file must have the same name as the class-blockname file, for example: - * - * Block: class-heading.php - * Template: heading.php - * - * @param array $attributes Array of attributes as defined in block's index.js. - * @param string $content Block's content. - * - * @echo string - * - * @since 1.0.0 - */ - public function render( array $attributes, string $content ) : string; } diff --git a/src/blocks/interface-renderable-block.php b/src/blocks/interface-renderable-block.php new file mode 100644 index 000000000..5e98f5cd5 --- /dev/null +++ b/src/blocks/interface-renderable-block.php @@ -0,0 +1,34 @@ +get_register_action_hook(), [ $this, 'register_services' ] ); + } - add_action( 'after_setup_theme', [ $this, 'register_services' ] ); - - $this->register_assets_manifest_data(); + /** + * Returns Theme/Plugin main action hook that start the whole lib. + * + * @return string + * + * @since 1.0.0 + */ + public function get_register_action_hook() : string { + return self::DEFAULT_REGISTER_ACTION_HOOK; } /** - * Register the individual services of this plugin. + * Register the individual services of this theme/plugin. * * @throws Exception\Invalid_Service If a service is not valid. * @@ -78,37 +91,6 @@ function( Service $service ) { ); } - /** - * Provide menifest json url location. - * - * @return string - * - * @since 1.0.0 - */ - protected function get_manifest_url() : string { - return get_template_directory() . '/skin/public/manifest.json'; - } - - /** - * Register bundled asset manifest - * - * @throws Exception\Missing_Manifest Throws error if manifest is missing. - * - * @return void - * - * @since 1.0.0 - */ - public function register_assets_manifest_data() : void { - - $manifest = $this->get_manifest_url(); - if ( ! file_exists( $manifest ) ) { - $error_message = esc_html__( 'manifest.json is missing. Bundle the theme before using it.', 'developer-portal' ); - throw Exception\Missing_Manifest::message( $error_message ); - } - - define( 'INF_ASSETS_MANIFEST', implode( ' ', file( $manifest ) ) ); - } - /** * Instantiate a single service. * @@ -142,7 +124,5 @@ private function instantiate_service( $class ) { * * @since 1.0.0 */ - protected function get_service_classes() : array { - return []; - } + abstract protected function get_service_classes() : array; } diff --git a/src/custom-post-type/class-base-post-type.php b/src/custom-post-type/class-base-post-type.php index e22dbfdf8..8c6897ff7 100644 --- a/src/custom-post-type/class-base-post-type.php +++ b/src/custom-post-type/class-base-post-type.php @@ -1,6 +1,6 @@