Repository: wp-papi/papi Branch: master Commit: c6621f5acbf2 Files: 354 Total size: 1.1 MB Directory structure: gitextract_jmguve0w/ ├── .babelrc ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ ├── issue_template.md │ ├── pull_request_template.md │ └── workflows/ │ └── php.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── composer.json ├── docker-compose.yml ├── languages/ │ ├── papi-fr_FR.mo │ ├── papi-fr_FR.po │ ├── papi-sv_SE.mo │ ├── papi-sv_SE.po │ └── papi.pot ├── package.json ├── papi-loader.php ├── phpcs.xml ├── phpunit.xml.dist ├── src/ │ ├── admin/ │ │ ├── class-papi-admin-ajax.php │ │ ├── class-papi-admin-assets.php │ │ ├── class-papi-admin-columns.php │ │ ├── class-papi-admin-entry-post.php │ │ ├── class-papi-admin-entry-taxonomy.php │ │ ├── class-papi-admin-entry.php │ │ ├── class-papi-admin-menu.php │ │ ├── class-papi-admin-meta-box-tabs.php │ │ ├── class-papi-admin-meta-box.php │ │ ├── class-papi-admin-meta-handler.php │ │ ├── class-papi-admin-option-handler.php │ │ ├── class-papi-admin-page-type-switcher.php │ │ ├── class-papi-admin-view.php │ │ ├── class-papi-admin.php │ │ └── views/ │ │ ├── add-new-page.php │ │ └── partials/ │ │ └── add-new-item.php │ ├── assets/ │ │ ├── js/ │ │ │ ├── components/ │ │ │ │ ├── pikaday.js │ │ │ │ └── select2.js │ │ │ ├── core.js │ │ │ ├── modals/ │ │ │ │ └── iframe.js │ │ │ ├── properties/ │ │ │ │ ├── color.js │ │ │ │ ├── datetime.js │ │ │ │ ├── dropdown.js │ │ │ │ ├── editor.js │ │ │ │ ├── file.js │ │ │ │ ├── flexible.js │ │ │ │ ├── link.js │ │ │ │ ├── module.js │ │ │ │ ├── post.js │ │ │ │ ├── reference.js │ │ │ │ ├── relationship.js │ │ │ │ ├── repeater.js │ │ │ │ ├── term.js │ │ │ │ └── url.js │ │ │ ├── required.js │ │ │ ├── rules.js │ │ │ ├── tabs.js │ │ │ ├── taxonomy.js │ │ │ └── utils.js │ │ └── scss/ │ │ ├── components/ │ │ │ ├── pikaday.scss │ │ │ └── select2.scss │ │ ├── modules/ │ │ │ ├── _admin.scss │ │ │ ├── _attachment.scss │ │ │ ├── _base.scss │ │ │ ├── _box.scss │ │ │ ├── _iframe.scss │ │ │ ├── _options.scss │ │ │ ├── _table.scss │ │ │ ├── _tabs.scss │ │ │ └── _utils.scss │ │ ├── properties/ │ │ │ ├── _checkbox.scss │ │ │ ├── _color.scss │ │ │ ├── _divider.scss │ │ │ ├── _dropdown.scss │ │ │ ├── _file.scss │ │ │ ├── _flexible.scss │ │ │ ├── _group.scss │ │ │ ├── _link.scss │ │ │ ├── _post.scss │ │ │ ├── _radio.scss │ │ │ ├── _reference.scss │ │ │ ├── _relationship.scss │ │ │ ├── _repeater.scss │ │ │ ├── _shared.scss │ │ │ ├── _table.scss │ │ │ ├── _term.scss │ │ │ ├── _text.scss │ │ │ └── _url.scss │ │ └── style.scss │ ├── cli/ │ │ ├── class-papi-cli-command.php │ │ ├── class-papi-cli-post-command.php │ │ ├── class-papi-cli-term-command.php │ │ ├── class-papi-cli-type-command.php │ │ └── class-papi-cli.php │ ├── core/ │ │ ├── class-papi-core-autoload.php │ │ ├── class-papi-core-box.php │ │ ├── class-papi-core-conditional-rule.php │ │ ├── class-papi-core-conditional-rules.php │ │ ├── class-papi-core-conditional.php │ │ ├── class-papi-core-container.php │ │ ├── class-papi-core-data-handler.php │ │ ├── class-papi-core-data.php │ │ ├── class-papi-core-meta-store.php │ │ ├── class-papi-core-property.php │ │ ├── class-papi-core-tab.php │ │ └── class-papi-core-type.php │ ├── lib/ │ │ ├── core/ │ │ │ ├── cache.php │ │ │ ├── conditional.php │ │ │ ├── data.php │ │ │ ├── deprecated.php │ │ │ ├── io.php │ │ │ ├── meta.php │ │ │ ├── post.php │ │ │ ├── property.php │ │ │ ├── slug.php │ │ │ ├── tabs.php │ │ │ ├── taxonomy.php │ │ │ ├── template.php │ │ │ ├── url.php │ │ │ └── utilities.php │ │ ├── fields/ │ │ │ ├── option.php │ │ │ ├── page.php │ │ │ └── taxonomy.php │ │ ├── hooks/ │ │ │ ├── actions.php │ │ │ ├── filters-page-type.php │ │ │ ├── filters-taxonomy-type.php │ │ │ └── filters.php │ │ └── types/ │ │ ├── entry.php │ │ ├── page.php │ │ └── taxonomy.php │ ├── papi-loader.php │ ├── properties/ │ │ ├── class-papi-property-bool.php │ │ ├── class-papi-property-checkbox.php │ │ ├── class-papi-property-color.php │ │ ├── class-papi-property-datetime.php │ │ ├── class-papi-property-divider.php │ │ ├── class-papi-property-dropdown.php │ │ ├── class-papi-property-editor.php │ │ ├── class-papi-property-email.php │ │ ├── class-papi-property-file.php │ │ ├── class-papi-property-flexible.php │ │ ├── class-papi-property-gallery.php │ │ ├── class-papi-property-group.php │ │ ├── class-papi-property-hidden.php │ │ ├── class-papi-property-html.php │ │ ├── class-papi-property-image.php │ │ ├── class-papi-property-link.php │ │ ├── class-papi-property-module.php │ │ ├── class-papi-property-number.php │ │ ├── class-papi-property-post.php │ │ ├── class-papi-property-radio.php │ │ ├── class-papi-property-reference.php │ │ ├── class-papi-property-relationship.php │ │ ├── class-papi-property-repeater.php │ │ ├── class-papi-property-sidebar.php │ │ ├── class-papi-property-string.php │ │ ├── class-papi-property-table.php │ │ ├── class-papi-property-term.php │ │ ├── class-papi-property-text.php │ │ ├── class-papi-property-url.php │ │ ├── class-papi-property-user.php │ │ └── class-papi-property.php │ ├── query/ │ │ └── class-papi-query.php │ ├── rest-api/ │ │ ├── class-papi-rest-api-post.php │ │ ├── class-papi-rest-api-settings.php │ │ └── class-papi-rest-api.php │ ├── stores/ │ │ ├── class-papi-option-store.php │ │ ├── class-papi-post-store.php │ │ └── class-papi-term-store.php │ └── types/ │ ├── class-papi-attachment-type.php │ ├── class-papi-entry-type.php │ ├── class-papi-front-page-type.php │ ├── class-papi-module-type.php │ ├── class-papi-option-type.php │ ├── class-papi-page-type.php │ └── class-papi-taxonomy-type.php ├── tests/ │ ├── Dockerfile │ ├── README.md │ ├── bin/ │ │ └── install-cp-tests.sh │ ├── bootstrap.php │ ├── cases/ │ │ ├── admin/ │ │ │ ├── class-papi-admin-ajax-test.php │ │ │ ├── class-papi-admin-assets-test.php │ │ │ ├── class-papi-admin-columns-test.php │ │ │ ├── class-papi-admin-entry-post-test.php │ │ │ ├── class-papi-admin-entry-taxonomy-test.php │ │ │ ├── class-papi-admin-menu-test.php │ │ │ ├── class-papi-admin-meta-box-tabs-test.php │ │ │ ├── class-papi-admin-meta-box-test.php │ │ │ ├── class-papi-admin-meta-handler-test.php │ │ │ ├── class-papi-admin-option-handler-test.php │ │ │ ├── class-papi-admin-page-type-switcher.php │ │ │ ├── class-papi-admin-test.php │ │ │ └── class-papi-admin-view-test.php │ │ ├── core/ │ │ │ ├── class-papi-conditional-rules-test.php │ │ │ ├── class-papi-core-box-test.php │ │ │ ├── class-papi-core-conditional-rule-test.php │ │ │ ├── class-papi-core-conditional-test.php │ │ │ ├── class-papi-core-container-test.php │ │ │ ├── class-papi-core-data-test.php │ │ │ ├── class-papi-core-property-test.php │ │ │ ├── class-papi-core-tab-test.php │ │ │ └── class-papi-core-type-test.php │ │ ├── lib/ │ │ │ ├── core/ │ │ │ │ ├── cache-test.php │ │ │ │ ├── conditional-test.php │ │ │ │ ├── data-test.php │ │ │ │ ├── deprecated-test.php │ │ │ │ ├── io-test.php │ │ │ │ ├── meta-test.php │ │ │ │ ├── post-test.php │ │ │ │ ├── property-test.php │ │ │ │ ├── slug-test.php │ │ │ │ ├── tabs-test.php │ │ │ │ ├── taxonomy-test.php │ │ │ │ ├── template-test.php │ │ │ │ ├── url-test.php │ │ │ │ └── utilities-test.php │ │ │ ├── fields/ │ │ │ │ ├── option-test.php │ │ │ │ ├── page-test.php │ │ │ │ └── taxonomy-test.php │ │ │ ├── hooks/ │ │ │ │ ├── actions-test.php │ │ │ │ ├── filters-page-type-test.php │ │ │ │ ├── filters-taxonomy-type-test.php │ │ │ │ └── filters-test.php │ │ │ └── types/ │ │ │ ├── entry-test.php │ │ │ ├── page-test.php │ │ │ └── taxonomy-test.php │ │ ├── papi-loader-test.php │ │ ├── properties/ │ │ │ ├── class-papi-property-bool-test.php │ │ │ ├── class-papi-property-checkbox-test.php │ │ │ ├── class-papi-property-color-test.php │ │ │ ├── class-papi-property-datetime-test.php │ │ │ ├── class-papi-property-divider-test.php │ │ │ ├── class-papi-property-dropdown-test.php │ │ │ ├── class-papi-property-editor-test.php │ │ │ ├── class-papi-property-email-test.php │ │ │ ├── class-papi-property-file-test.php │ │ │ ├── class-papi-property-flexible-test.php │ │ │ ├── class-papi-property-gallery-test.php │ │ │ ├── class-papi-property-group-test.php │ │ │ ├── class-papi-property-hidden-test.php │ │ │ ├── class-papi-property-html-test.php │ │ │ ├── class-papi-property-image-test.php │ │ │ ├── class-papi-property-link-test.php │ │ │ ├── class-papi-property-module-test.php │ │ │ ├── class-papi-property-number-test.php │ │ │ ├── class-papi-property-post-test.php │ │ │ ├── class-papi-property-radio-test.php │ │ │ ├── class-papi-property-reference-test.php │ │ │ ├── class-papi-property-relationship-test.php │ │ │ ├── class-papi-property-repeater-test.php │ │ │ ├── class-papi-property-sidebar-test.php │ │ │ ├── class-papi-property-string-test.php │ │ │ ├── class-papi-property-term-test.php │ │ │ ├── class-papi-property-test.php │ │ │ ├── class-papi-property-text-test.php │ │ │ ├── class-papi-property-url-test.php │ │ │ └── class-papi-property-user-test.php │ │ ├── query/ │ │ │ └── class-papi-query-test.php │ │ ├── rest-api/ │ │ │ ├── class-papi-rest-api-post-test.php │ │ │ ├── class-papi-rest-api-settings-test.php │ │ │ └── class-papi-rest-api-test.php │ │ ├── stores/ │ │ │ ├── class-papi-option-store-test.php │ │ │ ├── class-papi-post-store-test.php │ │ │ └── class-papi-term-store-test.php │ │ └── types/ │ │ ├── class-papi-attachment-type-test.php │ │ ├── class-papi-entry-type-test.php │ │ ├── class-papi-option-type-test.php │ │ ├── class-papi-page-type-test.php │ │ └── class-papi-taxonomy-type-test.php │ ├── data/ │ │ ├── classes/ │ │ │ └── class-say.php │ │ ├── container/ │ │ │ └── class-container-test-stub.php │ │ ├── core-types/ │ │ │ ├── abstract-core-type.php │ │ │ ├── base-core-type.php │ │ │ ├── broken-core-type.php │ │ │ ├── info-core-type.php │ │ │ └── info2-core-type.php │ │ ├── entry-types/ │ │ │ ├── abstract-entry-type.php │ │ │ ├── base-entry-type.php │ │ │ ├── broken-entry-type.php │ │ │ ├── info-entry-type.php │ │ │ └── term-entry-type.php │ │ ├── entry-types2/ │ │ │ └── term-entry-type.php │ │ ├── page-types/ │ │ │ ├── big-page-type.php │ │ │ ├── book-page-type.php │ │ │ ├── boxes/ │ │ │ │ ├── big.php │ │ │ │ ├── properties.php │ │ │ │ └── simple.php │ │ │ ├── broken-page-type.php │ │ │ ├── display-not-page-type.php │ │ │ ├── dot-page-type.php │ │ │ ├── dot2-page-type.php │ │ │ ├── duck-page-type.php │ │ │ ├── editor-page-type.php │ │ │ ├── empty-page-type.php │ │ │ ├── extra-page-type.php │ │ │ ├── faq-extra-page-type.php │ │ │ ├── faq-extra2-page-type.php │ │ │ ├── faq-page-type.php │ │ │ ├── fields-page-type.php │ │ │ ├── flex-page-type.php │ │ │ ├── flex2-page-type.php │ │ │ ├── front-page-type.php │ │ │ ├── group-page-type.php │ │ │ ├── hidden-page-type.php │ │ │ ├── hidden2-page-type.php │ │ │ ├── identifier-page-type.php │ │ │ ├── module-page-type.php │ │ │ ├── modules/ │ │ │ │ ├── image-module-type.php │ │ │ │ ├── string-module-type.php │ │ │ │ ├── top-module-type.php │ │ │ │ └── video-module-type.php │ │ │ ├── name-page-type.php │ │ │ ├── namespace-page-type.php │ │ │ ├── no-page-type.php │ │ │ ├── options/ │ │ │ │ ├── class-settings-option-type.php │ │ │ │ ├── header-option-type.php │ │ │ │ └── properties-option-type.php │ │ │ ├── others/ │ │ │ │ ├── attachment-type.php │ │ │ │ └── media-attachment-type.php │ │ │ ├── post-page-type.php │ │ │ ├── price-page-type.php │ │ │ ├── properties/ │ │ │ │ └── name.php │ │ │ ├── properties-page-type.php │ │ │ ├── rule-page-type.php │ │ │ ├── simple-page-type.php │ │ │ ├── tab-page-type.php │ │ │ ├── tab2-page-type.php │ │ │ ├── tabs/ │ │ │ │ ├── content.php │ │ │ │ └── video.php │ │ │ ├── test-page-type.php │ │ │ └── twenty-page-type.php │ │ ├── page-types2/ │ │ │ ├── any-page-type.php │ │ │ └── look-page-type.php │ │ ├── properties/ │ │ │ ├── array.php │ │ │ ├── class-papi-property-fake.php │ │ │ ├── class-papi-property-kvack.php │ │ │ └── simple.php │ │ └── taxonomy-types/ │ │ ├── broken-taxonomy-type.php │ │ ├── empty-taxonomy-type.php │ │ ├── faq-extra-taxonomy-type.php │ │ ├── faq-extra2-taxonomy-type.php │ │ ├── faq-taxonomy-type.php │ │ ├── properties-taxonomy-type.php │ │ └── simple-taxonomy-type.php │ └── framework/ │ ├── class-papi-property-test-case.php │ ├── functions.php │ └── helpers.php └── webpack.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": ["@jitesoft/main"] } ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 end_of_line = lf indent_style = space indent_size = 2 insert_final_newline = true trim_trailing_whitespace = true [*.php] indent_style = tab indent_size = 4 [*.md] trim_trailing_whitespace = false [Makefile] indent_style = tab indent_size = 8 [*.{js,jsx,ts,tsx,vue}] quote_type = single ================================================ FILE: .gitattributes ================================================ * text=auto /bin export-ignore /src/assets export-ignore /tests export-ignore .coveralls.yml export-ignore .gitattributes export-ignore .gitignore export-ignore .github export-ignore .scrutinizer.yml export-ignore .travis.yml export-ignore CONTRIBUTING.md export-ignore Makefile export-ignore package.json export-ignore phpcs.xml export-ignore phpunit.xml.dist export-ignore tmp export-ignore Vagrantfile export-ignore vendor export-ignore behat.yml export-ignore webpack.config.js export-ignore ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve --- ### What I expected A clear and concise description of what you expected to happen. ### What happened instead A clear and concise description of what the bug is. ### Screenshots If applicable, add screenshots to help explain your problem. ### Steps to reproduce 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error ### What versions of softwares are you using? - Browser: [e.g. chrome, safari] - Papi: [e.g. 3.2.0] - WordPress: [e.g. 4.9.8] ### Additional context Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/issue_template.md ================================================ ### What I expected ### What happened instead ### Steps to reproduce ### What versions of softwares are you using? - Browser: - Papi: - WordPress: ================================================ FILE: .github/pull_request_template.md ================================================ ### Description Please explain the changes you made here. ### Checklist - [ ] Bug fix? - [ ] New feature? - [ ] Deprecations? - [ ] Created tests, if possible ================================================ FILE: .github/workflows/php.yml ================================================ name: PHP Unit Tests on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: strategy: matrix: php-versions: ['7.4'] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} - name: Start MySQL run: sudo systemctl start mysql.service - name: Validate composer.json and composer.lock run: composer validate - name: Cache Composer packages id: composer-cache uses: actions/cache@v2 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-php- - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' run: composer install --prefer-dist --no-progress --no-suggest - name: Set up test environement run: vendor/frozzare/wp-test-suite/bin/install-wp-tests.sh wordpress_test root root localhost latest - name: Run tests run: vendor/bin/phpunit ================================================ FILE: .gitignore ================================================ .idea node_modules test.php tmp/ build/ coverage/ vendor composer.lock components.js style.css main.js ================================================ FILE: CHANGELOG.md ================================================ # Papi Changelog ## [3.3.0] ## Added * Added `papi/pre_template_include` filter to modify which template is loaded before Papi looks for a template. * Added `papi_get_fields` and `papi_get_term_fields` to receive all slugs and values from a Page/Taxonomy type. ## [3.2.0](https://github.com/wp-papi/papi/releases/tag/v3.2.0) - 2017-09-07 The stable release of Papi 3.2.0, a lot has been added, changed, fixed and some functions has been removed (mostly core stuff). Papi 3.2.0 introduce a new core data api that is used everywhere in the plugin and by advanced properties. Upgrading from Papi 3.1.x will work and the new core data api will not create any problems. Unfortunately this will likely be the last release I plan to work on as the core maintainer of Papi since my focus has shifted from WordPress to doing more JavaScript and Go projects. I hope you understand my decision to step back from the project, if you have any questions or would be interested in take over some of the maintenance of the project please let me know. I will still be around answering questions and helping any new maintainers. Some bug fixes and/or pull request may be added (but now new versions) since me and my colleagues use Papi internally and will be continuing doing it. ## Added * Added: `body_classes` will be added to the frontend aswell and not just the admin. * Added: `register_meta` support for REST API. * Added: Edit post reference in a iframe instead of leaving the current page. * Added: `edit_url` setting to post property to display iframe mode. * Added: Page type switcher. * Added: `papi/get_boxes` filter so you can add boxes to a entry type that don't exists in the class. * Added: New ajax action for shortcodes `/papi-ajax/?action=get_shortcode&shortcode=[test]` * Added: New method on `Papi_Entry_Type` to fetch all properties `get_properties`, it's useful if you would like to build something custom. * Added: `Papi_Query` * Added: Multiple select support for dropdown property. * Added: `site_id` option added to both box and property. * Added: `papi/get_property` filter added so you can modify properties when they are fetched inside Papi. * Added: Labels to flexible property so you can see which row is using which layout. * Added: `fields => ids` setting on file, image, gallery, post, term and relationship property. * Added: `meta_key => custom_meta_key` setting on file, image, gallery, post, term and relationship property, so you can match meta value instead of post id. * Added: Support for `any` post type value for a page type. * Added: CLI to rename meta keys for posts and terms, see [#208](https://github.com/wp-papi/papi/issues/208). * Added: `lang` option now supports arrays and not just strings. * Added: Filter to override conditional rule allowed value `papi/conditional/rule_allowed` * Added: Filter to modify lang query string value `papi/lang` * Added: Filter to modify template extension `papi/template_extension` ## Changed * Changed: PHP 5.6 will be required instead of 5.5.9. * Changed: WordPress 4.4 will be required instead of 4.0. * Changed: String numeric and bool values are strings and numeric and bool values are not string values in dropdown anymore. * Changed: You can now use `papi_is_page_type` to check if current post is a page type with (was only used internal before). * Changed: `papi()->make( 'Sample_Page_Type' )` is replaced by id `papi()->make( 'simple-page-type' )` to make it more consistent. ## Deprecated * Deprecated: `papi_get_page`, is deprecated and you should use `papi_get_meta_store( $id )` instead since it support both post, term and option stores and `papi_get_page` returns the value of `papi_get_meta_store` so no need for two functions that does the same thing. ## Fixed * Fixed: `papi_get_entry_type_css_class` will work with taxonomies. * Fixed: Better peformance when core loads entry types. * Fixed: Group properties works with conditional rules now. * Fixed: Dropdown property can now handle numeric values, see [#225](https://github.com/wp-papi/papi/issues/225). * Fixed: Respect show standard type filter in list columns, see [#235](https://github.com/wp-papi/papi/issues/235). * Fixed: Complex properties should now be rendered in REST API, see [#232](https://github.com/wp-papi/papi/issues/232). * Fixed: Post ID will be respected all the way and it will not guess, see [#227](https://github.com/wp-papi/papi/pull/227). ## Removed * Removed: HHVM testing is removed, PHP7 is more awesome. * Removed: `papi_delete_property_meta_value` is replaced with `papi_data_delete`, mostly use by core and advanced properties. * Removed: `papi_get_property_meta_value` is replaced with `papi_data_get`, mostly use by core and advanced properties. * Removed: `papi_update_property_meta_value` is replaced with `papi_data_update`, mostly use by core and advanced properties. ## [3.1.19](https://github.com/wp-papi/papi/releases/tag/v3.1.19) - 2017-02-14 * Fixed: Sanitize box id key [#215](https://github.com/wp-papi/papi/issues/215). * Fixed: Undefined property on file object used in file property [#217](https://github.com/wp-papi/papi/issues/217). * Fixed: AJAX endpoint for plain permalink structure [#218](https://github.com/wp-papi/papi/issues/218). * Fixed: `FORCE_SSL_ADMIN` and AJAX endpoint [#213](https://github.com/wp-papi/papi/issues/213). * Fixed: oEmbed cache is broken if content is empty [#210](https://github.com/wp-papi/papi/issues/210). * Fixed: Respect user admin language in WordPress 4.7 [#209](https://github.com/wp-papi/papi/issues/209). * Fixed: Sort order on properties. * Fixed: Autosave didn't work as it should. * Fixed: Repeater rows was affected when removing flexible rows when repeater was a child property to the flexible. ## [3.1.18](https://github.com/wp-papi/papi/releases/tag/v3.1.18) - 2016-12-16 * Fixed: Link property target didn't work correct in new WordPress [#207](https://github.com/wp-papi/papi/issues/207). ## [3.1.17](https://github.com/wp-papi/papi/releases/tag/v3.1.17) - 2016-11-01 * Fixed: Link property didn't save values correct. * Fixed: Relationship custom data can now use string id and not just int ids. ## [3.1.16](https://github.com/wp-papi/papi/releases/tag/v3.1.16) - 2016-10-26 * Fixed: Auto draft didn't save fields. * Fixed: Issues with color picker property that didn't work [#179](https://github.com/wp-papi/papi/issues/179). * Fixed: Editor tabs didn't work when flexible and repeater use `vertical` layout [#201](https://github.com/wp-papi/papi/issues/201). * Fixed: Remove duplicated database queries. * Fixed: `z-index` issue with flexible `add` button when placed under a editor [#198](https://github.com/wp-papi/papi/pull/198). Props [nlemoine](https://github.com/nlemoine). * Fixed: `nl2br` issue with text property [#199](https://github.com/wp-papi/papi/issues/199). ## [3.1.15](https://github.com/wp-papi/papi/releases/tag/v3.1.15) - 2016-10-06 * Fixed: Expression issues with TinyMCE in flexibles and repeaters [#196](https://github.com/wp-papi/papi/issues/196). * Fixed: Dot files should not be loaded if exists in types directories [#193](https://github.com/wp-papi/papi/issues/193). * Fixed: Cache issue when a repeater is a child property to a flexible. ## [3.1.14](https://github.com/wp-papi/papi/releases/tag/v3.1.14) - 2016-09-23 * Fixed: Browser issue with `selected` attribute. * Fixed: Drag and drop issue with repeater. ## [3.1.13](https://github.com/wp-papi/papi/releases/tag/v3.1.13) - 2016-09-12 * Fixed: Drag and drop issue with link property in flexible/repeater. * Fixed: Bug with post add new link when user is on another post type [#190](https://github.com/wp-papi/papi/pull/190). * Fixed: Optimize `papi_is_empty` check for arrays [#191](https://github.com/wp-papi/papi/pull/191). ## [3.1.12](https://github.com/wp-papi/papi/releases/tag/v3.1.12) - 2016-09-05 * Fixed: Cache issue with improved cache for flexible. ## [3.1.11](https://github.com/wp-papi/papi/releases/tag/v3.1.11) - 2016-09-05 * Fixed: Cache only raw database value instead of formatted value, this solves problems with shortcodes in the editor that shouldn't be cached. * Fixed: Improve css for flexible and repeater. ## [3.1.10](https://github.com/wp-papi/papi/releases/tag/v3.1.10) - 2016-08-30 * Fixed: Multiple render issue when using `papi_get_field` instead a property array. * Fixed: Add new page did remove custom query strings that shouldn't be removed. ## [3.1.9](https://github.com/wp-papi/papi/releases/tag/v3.1.9) - 2016-08-16 * Fixed: Small css fixes for repeater in flexible [#187](https://github.com/wp-papi/papi/pull/187). * Fixed: Remove repeater rows in flexible. * Fixed: Object cache not updated when adding row in repeater in flexible [#185](https://github.com/wp-papi/papi/pull/185). * Fixed: CSS bug: Remove is hidden for repeater in flexible [#184](https://github.com/wp-papi/papi/pull/184). ## [3.1.8](https://github.com/wp-papi/papi/releases/tag/v3.1.8) - 2016-08-10 * Fixed: Some properties did try to save the property key. ## [3.1.7](https://github.com/wp-papi/papi/releases/tag/v3.1.7) - 2016-08-10 * Fixed: Save issue with key/value arrays. * FIxed: Relationship setting `only_once` didn't remove items on page load [#183](https://github.com/wp-papi/papi/pull/183). ## [3.1.6](https://github.com/wp-papi/papi/releases/tag/v3.1.6) - 2016-08-08 * Fixed: Issue with `papi_html_tag` that caused html output issue with some properties. ## [3.1.5](https://github.com/wp-papi/papi/releases/tag/v3.1.5) - 2016-08-08 * Fixed: Slug with `_property` suffix didn't work. * Fixed: Remove empty values on post save for properties. ## [3.1.4](https://github.com/wp-papi/papi/releases/tag/v3.1.4) - 2016-08-01 * Fixed: PHP type error in group property. * Fixed: Wrong meta type was send to ajax when option page was in a post type menu. ## [3.1.3](https://github.com/wp-papi/papi/releases/tag/v3.1.3) - 2016-07-27 * Fixed: Cache issue with key that has `papi_` prefix. ## [3.1.2](https://github.com/wp-papi/papi/releases/tag/v3.1.2) - 2016-07-27 * Added: `papi_filter_settings_only_taxonomy_type` that acts the same way as `papi_filter_settings_only_page_type` * Fixed: UTF-8 Encoding issue with JSON encoded strings [#177](https://github.com/wp-papi/papi/pull/177). * Fixed: Equal hight class names on add new page view. ## [3.1.1](https://github.com/wp-papi/papi/releases/tag/v3.1.1) - 2016-07-04 * Fixed: Path to files was rewritten with to lowercase [#176](https://github.com/wp-papi/papi/issues/176) ## [3.1.0](https://github.com/wp-papi/papi/releases/tag/v3.1.0) - 2016-06-27 ### Added * Added: `show_screen_options` to all types meta method that can turn off screen options tab. * Added: `show_help_tabs` to all types meta method that can turn off help tab. * Added: `help` method to all types which can be used to add help tabs. * Added: `help_sidebar` method to all types which can be used to add help tabs sidebar content. * Added: Support for taxonomy types with support for term meta. * Added: `wp papi term` command like post command. * Added: `mce_buttons` settings to editor property. * Added: `media_buttons`, `teeny` and `drag_drop_upload` settings to editor property. * Added: Vertical boxes support [#148](https://github.com/wp-papi/papi/issues/159). * Added: Support for saving properties on revision posts and restoring revision data. * Added: `display` option to box options in order to control if the box should be displayed or not. * Added: Support for repeaters inside repeaters. * Added: Support for repeaters inside flexibles. * Added: Support for render html in `Publish box` with `publish_box` method. * Added: `papi_get_entry_type_css_class` to get the css class that is added to body for a entry type. * Added: Support for autosaving fields. * Added: Support for group inside flexibles. * Added: Support for group inside repeaters. * Added: `body_classes` method to all types which can be used to add custom body classes. * Added: `show_permalink` to page type so permalink div can be hidden on a page type. * Added: `show_page_template` to hide page template dropdown by default on a page type. * Added: `show_page_attributes` to show page attributes box by default on a page type. * Added: `false` value to `slug` key to generate a unique slug that don't should be saved in the database but displayed in the admin. ### Changed * Updated: Cross icon for file property with new color [#158](https://github.com/wp-papi/papi/pull/158). * Updated: `$id` param for `papi_get_slugs` is optional. * Updated: Group property is stored as a repeater but only with one row and not a standalone properties. ### Removed * Removed: Papi tool page. * Removed: `papi_translate_keys` ## [3.0.9](https://github.com/wp-papi/papi/releases/tag/v3.0.9) - 2016-05-25 * Fixed: Checkbox property did not save unchecked values. ## [3.0.8](https://github.com/wp-papi/papi/releases/tag/v3.0.8) - 2016-05-17 * Fixed: Cache issue where admin and theme did get the same cached data, will now be saved as two caches. ## [3.0.7](https://github.com/wp-papi/papi/releases/tag/v3.0.7) - 2016-05-09 * Fixed: Locale should be restored after `papi_slugify` is used [#169](https://github.com/wp-papi/papi/issues/169). * Fixed: Show standard page type filter is used when only one page type exists. ## [3.0.6](https://github.com/wp-papi/papi/releases/tag/v3.0.6) - 2016-04-14 * Fixed: Attachment types used on a page type didn't load right, so the site performance was bad. * Fixed: Object cache issue with properties that overwrites a existing post field. Cached data was loaded in WordPress admin. ## [3.0.5](https://github.com/wp-papi/papi/releases/tag/v3.0.5) - 2016-04-01 * Fixed: Datetime did not work in repeater [#166](https://github.com/wp-papi/papi/issues/166). ## [3.0.4](https://github.com/wp-papi/papi/releases/tag/v3.0.4) - 2016-03-23 * Fixed: Require for link property [#165](https://github.com/wp-papi/papi/issues/165). * Fixed: Check so file exists before calling `file_get_contents` when reading page type files. ## [3.0.3](https://github.com/wp-papi/papi/releases/tag/v3.0.3) - 2016-03-19 * Fixed: Box options didn't work when no properties exists in the box. * Fixed: Some properties that was stored in options table did return null from `papi_get_option`, mostly flexible and repeater. * Fixed: Object cache issue with options fields that did get post id instead of zero that options should have. * Fixed: Check for registered directories before they are used. ## [3.0.2](https://github.com/wp-papi/papi/releases/tag/v3.0.2) - 2016-03-08 ### Fixed * Fixed: PHP Notice/Object issue for relationship when using custom relationship data. * Fixed: Double fields issue for any field when using `papi_get_field` in hooks that fires earlier then `admin_init` [#153](https://github.com/wp-papi/papi/issues/153). ## [3.0.1](https://github.com/wp-papi/papi/releases/tag/v3.0.1) - 2016-02-15 ### Fixed * Fixed: Render issue with tabs that existed in template files [#148](https://github.com/wp-papi/papi/issues/148). * Fixed: Edit link property did appear in the default editor. * Fixed: Required did not output the red wildcard [#149](https://github.com/wp-papi/papi/issues/149). * Fixed: Required did not output the red wildcard [#149](https://github.com/wp-papi/papi/issues/149). ## [3.0.0](https://github.com/wp-papi/papi/releases/tag/v3.0.0) - 2016-02-02 Papi 3.0.0 is a big release since a big piece of the core code has been refactored to improve how page type works. With 3.0.0 release we introduce `Entry Type` which is a base class that both page type and option type use. Both `box` and `tab` logic has been rewritten with new core classes and the admin classes has been divided into several smaller classes. Some internal functions has been removed or rewritten with backward compatibility. We moved some logic from page type class to entry type class to be able the separate page type and option type class. This will make it easier to add new types to core or create plugin that has custom types. ### Added * Added: Extended support for `meta`, `box` and `remove` methods [#114](https://github.com/wp-papi/papi/issues/114). * Added: WP CLI Support [#111](https://github.com/wp-papi/papi/issues/111). * Added: Group property [#112](https://github.com/wp-papi/papi/issues/112). * Added: `papi/before_init` action that is fired before Papi loads textdomain, classes, functions and setups the container. * Added: `papi/init` action that is fired after Papi loads textdomain, classes, functions and setups the container. * Added: `papi/loaded` action that will be the new `papi/include`. The old action is deprecated but will still work, it's fired before `papi/loaded` and will be removed in a feature version of Papi. * Added: `placeholder` setting to string property. * Added: Description to option type meta data. * Added: `papi/settings/column_hide_{$post_type}` for hiding type column. * Added: `papi/template_include` to provide support for third party templating engines. * Added: Layout mode to post property. It can devide into multiple select or a single select with labels (as before). * Added: Layout mode to term property. It can devide into multiple select or a single select with labels (as before). * Added: Second bool param to `papi_get_slugs` that will return only slugs if true. * Added: A way to handle classes with the same name in multiple directories [#107](https://github.com/wp-papi/papi/issues/107) * Added: When WordPress refresh nonces, Papi nonces should be refreshed too. ### Changed * Flexible property will only save one layout per row. The layout key is changed from `_layout` to `_flexible_layout` since `_layout` can be a real slug. It has backward compatibility for the old layout key. This may cause problem with existing slugs that are named `layout`. To fix default value issue you need to manually add the layout value for the effected row. The slug will be something like this: `sections_0_flexible_layout`, where `sections` is your flexible slug, `0` is the row and `_flexible_layout` is the new layout key. The value should be a slug of the layout title, the same value as the old `_layout` rows that exists on each property. ### Fixed * Fixed: Save post issue when using property template file and overwrited the slug [#129](https://github.com/wp-papi/papi/issues/129). * Fixed: Select2 clear issue [#132](https://github.com/wp-papi/papi/issues/132). * Fixed: Property type values like `test-form-1` should match `Papi_Property_Test_Form_1` * Fixed: When using `overwrite` it should read data from the post instead of post meta [#145](https://github.com/wp-papi/papi/issues/145) * Fixed: Same prefix on folders should not replace all, only the current one. ### Removed * Removed: `remove` method is removed. * Removed: No more array properties, all properties must use `papi_property` or `$this->property` to work. This because the converting of array properties is bad and some keys can't be used for other things. * Removed deprecated function `current_page`, was deprecated in 2.0.0. * Removed deprecated function `papi_field`, was deprecated in 2.0.0. * Removed deprecated function `papi_fields`, was deprecated in 2.0.0. * Removed deprecated function `papi_get_page_type_meta_value`, was deprecated in 2.0.0. * Removed deprecated meta methods, `page_type` and `option_type`, `meta` method should be used instead. ### Upgraded * Upgraded: Moment.js from 2.10.6 to 2.11.0 ### Thanks Thanks to all contributors and all who have tested Papi during the development. You can find the old changelog for `2.x` [here](https://github.com/wp-papi/papi/blob/2.x/CHANGELOG.md). ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # 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, gender identity and expression, level of experience, 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 [INSERT EMAIL ADDRESS]. 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 [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: CONTRIBUTING.md ================================================ ## Contributing to Papi Everyone is welcome to contribute with patches, bug-fixes and new features. ## Ideas If you have a idea the easiest way is to create a [issue](https://github.com/wp-papi/papi/issues). ## Bugs Before you submit a bug issue you should be able to run the tests that the project has. Then you know if the tests works or not. When you submit a bug issue you should write which browser you are using since Papi contains front-end code and not only back-end code. If a test fails you should tell which one so it's easier to know what the bug is about. Try to be as detailed as possible in your bug issue so we can help you better with the issue. **Please** write how to reproduce the bug. ## Which branch? The `master` branch is unsafe but it should be used when you adding new features. When it's a bug fix that effects the current version you should do your pull request against the last stable branch. The stable branch will have the format `MAJOR.X`. ## Pull requests Good pull requests with patches, improvements or new features is always welcome. They should remain focused in scope and avoid containing unrelated commits. **Please ask first** embarking on any significant pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the project developers might not want to merge into the project. **Please follow** the projects code style. The projects PHP code should be following the code style that is based on [WordPress code standard](https://make.wordpress.org/core/handbook/coding-standards/php/) and always use brackets. * Fork [wp-papi/papi](https://github.com/wp-papi/papi) on Github and add the upstream remote. ``` git clone https://github.com//papi.git cd papi git remote add upstream https://github.com/wp-papi/papi.git ``` This is useful if you cloned your repo a while ago and now wants to update it. ``` git checkout master git pull upstream master ``` * Create a new branch: ``` git checkout -b ``` * Make sure to update, or add to the tests when appropriate. * Commit your changes to your fork. * Locally merge (or rebase) the upstream development branch into your topic branch: ``` git pull [--rebase] upstream master ``` * Push to your branch: ``` git push origin ``` * [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description against the `master` branch or against the stable branch if it's a bug fix that effects the current version. **Note:** If you are making several changes at once please divide them into multiple pull requests. ## License By contributing your code, you agree to license your contribution under the [MIT license](https://github.com/wp-papi/papi/blob/master/LICENSE). ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2013-2019 Fredrik Forsmo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ all: css js css: npm run css deps: composer install npm install -g yarn wp-pot-cli yarn js: npm run js lint: make lint:js make lint:php lint\:js: npm run lint lint\:php: vendor/bin/phpcs -s --extensions=php --standard=phpcs.xml src/ pot: wp-pot --src 'src/**/*.php' --dest-file languages/papi.pot --package papi watch: npm run watch watch\:css: npm run css watch\:js: npm run js ================================================ FILE: README.md ================================================ # Papi ![Papi](https://cloud.githubusercontent.com/assets/14610/9073902/16a6d906-3b05-11e5-9287-5644a96e9a82.png) [![Latest Version](https://img.shields.io/github/release/wp-papi/papi.svg?style=flat)](https://github.com/wp-papi/papi/releases) [![License](https://img.shields.io/packagist/l/wp-papi/papi.svg)](https://packagist.org/packages/wp-papi/papi) [![Gitter](https://badges.gitter.im/wp-papi/papi.svg)](https://gitter.im/wp-papi/papi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) > `master` is unsafe. `3.x` is the stable branch. Papi has a different approach on how to work with fields and page types in WordPress. The idea is coming from how Page Type Builder in EPiServer works and has been loved by the developers. So we though why don’t use the same approach in WordPress? Papi is today running in production and has been easy to work with when it came to add new fields. Papi don’t have any admin user interface where you should add all fields, we use classes in PHP, where one class represents one page type and in your class you add all fields you need. It’s that easy! [Visit Papi’s project page](https://wp-papi.github.io/) ## A message from the author v3.2.0 will likely be the last release I plan to work on as the core maintainer of Papi since my focus has shifted from WordPress to doing more JavaScript and Go projects. I hope you understand my decision to step back from the project, if you have any questions or would be interested in take over some of the maintenance of the project please let me know. I will still be around answering questions and helping any new maintainers. Some bug fixes and/or pull request may be added (but no new versions) since me and my colleagues use Papi internally and will be continuing doing it. ## Installation If you're using Composer to manage WordPress, add Papi to your project's dependencies. Run: ```sh composer require wp-papi/papi ``` Or manually add it to your `composer.json`: ```json "require": { "php": "^^7.4", "wordpress": "^4.6", "wp-papi/papi": "^3.2" } ``` ## Build CSS and JavaScript Install dependencies: ``` make deps ``` Build CSS: ``` make css ``` Build JavaScript: ``` make js ``` ## Testing Visit the [readme](tests/README.md) file for testing. ## Coding style You can check if your contribution passes the styleguide by installing [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) and running the following in your Papi directory: ``` make lint:php ``` ## Contributing Visit the [contributing](CONTRIBUTING.md) file. ## Security If you discover a security vulnerability within this package, please send an e-mail to Fredrik Forsmo at security@frozzare.com. All security vulnerabilities will be promptly addressed. ## License MIT © [Fredrik Forsmo](https://github.com/frozzare) ================================================ FILE: composer.json ================================================ { "name": "wp-papi/papi", "type": "wordpress-plugin", "license": "MIT", "description": "WordPress Page Type API with custom fields", "homepage": "https://wp-papi.github.io", "authors": [{ "name": "Fredrik Forsmo", "email": "fredrik.forsmo@gmail.com", "homepage": "https://github.com/frozzare" }], "keywords": [ "wordpress", "custom fields", "page type", "page", "taxonomy", "options" ], "require": { "php": "^7.4" }, "require-dev": { "frozzare/wp-test-suite": "^1.0", "wp-coding-standards/wpcs": "^0.13" }, "scripts": { "post-install-cmd": "if [ -f vendor/bin/phpcs ]; then \"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs; fi", "post-update-cmd": "if [ -f vendor/bin/phpcs ]; then \"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs; fi" }, "minimum-stability": "dev", "prefer-stable": true, "extra": { "branch-alias": { "dev-master": "3.3.x-dev" } } } ================================================ FILE: docker-compose.yml ================================================ version: '3' services: mysql: image: mariadb environment: - MYSQL_ROOT_PASSWORD=root phpunit: build: context: ./tests volumes: - .:/var/www/html depends_on: - mysql entrypoint: bash -c "composer install && vendor/frozzare/wp-test-suite/bin/install-wp-tests.sh wordpress_test root root mysql latest && vendor/bin/phpunit" ================================================ FILE: languages/papi-fr_FR.po ================================================ msgid "" msgstr "" "Project-Id-Version: Papi\n" "POT-Creation-Date: 2015-10-13 22:23+0100\n" "PO-Revision-Date: 2015-10-13 22:23+0100\n" "Last-Translator: Fredrik Forsmo \n" "Language-Team: \n" "Language: fr_FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.7.3\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n" "X-Poedit-SearchPath-0: ../src\n" #: ../src/admin/class-papi-admin-menu.php:109 #: ../src/admin/class-papi-admin-menu.php:158 #: ../src/admin/class-papi-admin-menu.php:159 #: ../src/types/class-papi-page-type-meta.php:153 msgid "Add New" msgstr "Ajouter nouveau" #: ../src/admin/class-papi-admin.php:45 ../src/admin/class-papi-admin.php:54 #: ../src/papi-loader.php:55 ../src/papi-loader.php:64 msgid "Cheatin’ huh?" msgstr "Alors, on triche ?" #: ../src/admin/class-papi-admin.php:114 #: ../src/properties/class-papi-property-flexible.php:721 #: ../src/properties/class-papi-property-flexible.php:744 #: ../src/properties/class-papi-property-repeater.php:703 #: ../src/properties/class-papi-property-repeater.php:725 msgid "Remove" msgstr "Supprimer" #: ../src/admin/class-papi-admin.php:115 msgid "This fields are required:" msgstr "Ces champs sont obligatoires :" #: ../src/admin/class-papi-admin.php:305 msgid "All types" msgstr "" #: ../src/admin/views/add-new-page.php:8 #, php-format msgid "Add New %s" msgstr "" #: ../src/admin/views/management-page-type.php:18 msgid "Tab Title" msgstr "Title de l’onglet" #: ../src/admin/views/management-page-type.php:19 #: ../src/admin/views/management-page-type.php:25 msgid "Sort Order" msgstr "Ordre de tri" #: ../src/admin/views/management-page-type.php:20 #: ../src/admin/views/management-page-type.php:44 #: ../src/admin/views/management-page-type.php:104 msgid "Properties" msgstr "Propriétés" #: ../src/admin/views/management-page-type.php:22 #: ../src/properties/class-papi-property-link.php:139 #: ../src/properties/class-papi-property-link.php:208 msgid "Title" msgstr "Titre" #: ../src/admin/views/management-page-type.php:23 ../src/lib/filters.php:136 msgid "Type" msgstr "Type" #: ../src/admin/views/management-page-type.php:24 msgid "Slug" msgstr "Alias" #: ../src/admin/views/management-page-type.php:80 msgid "Cannot find the page type" msgstr "Le type de page n’a pas été trouvé" #: ../src/admin/views/management-page-type.php:87 msgid "Overview of page type" msgstr "Vue d’ensemble du type de page" #: ../src/admin/views/management-page-type.php:98 msgid "No meta boxes exists." msgstr "Aucune metaboxes existante." #: ../src/admin/views/management-page-type.php:107 msgid "Tabs" msgstr "Onglets" #: ../src/admin/views/management-start.php:7 msgid "Page Types" msgstr "Types de page" #: ../src/admin/views/management-start.php:12 msgid "Name" msgstr "Nom" #: ../src/admin/views/management-start.php:15 msgid "Page Type ID" msgstr "Type de page ID" #: ../src/admin/views/management-start.php:18 msgid "Post types" msgstr "" #: ../src/admin/views/management-start.php:21 msgid "Template" msgstr "Gabarit" #: ../src/admin/views/management-start.php:24 msgid "Page Count" msgstr "Nombre de pages" #: ../src/admin/views/management-start.php:55 msgid "Page Type has no template file" msgstr "Le type de page n’a pas de fichier de gabarit" #: ../src/admin/views/management-start.php:69 msgid "Template file does not exist" msgstr "Le fichier de gabarit n’existe pas" #: ../src/admin/views/partials/add-new-item.php:14 #: ../src/properties/class-papi-property-relationship.php:123 msgid "Select" msgstr "Sélectionner" #: ../src/lib/filters.php:181 #, php-format msgid "%s with WordPress standard fields" msgstr "%s avec les champs standard WordPress" #: ../src/lib/filters.php:197 #, php-format msgid "Standard %s" msgstr "Standard %s" #: ../src/lib/property.php:353 msgid "(required field)" msgstr "(champ obligatoire)" #: ../src/papi-loader.php:185 msgid "" "WordPress 4.0 and higher required to run Papi! The plugin has now disabled " "itself." msgstr "" "WordPress 4.0 et supérieur est requis pour exécuter Papi ! Le plugin s’est " "maintenant désactivé." #: ../src/properties/class-papi-property-datetime.php:32 msgid "Previous Month" msgstr "" #: ../src/properties/class-papi-property-datetime.php:33 msgid "Next Month" msgstr "" #: ../src/properties/class-papi-property-datetime.php:34 msgid "Midnight" msgstr "" #: ../src/properties/class-papi-property-datetime.php:36 msgid "January" msgstr "" #: ../src/properties/class-papi-property-datetime.php:37 msgid "February" msgstr "" #: ../src/properties/class-papi-property-datetime.php:38 msgid "March" msgstr "" #: ../src/properties/class-papi-property-datetime.php:39 msgid "April" msgstr "" #: ../src/properties/class-papi-property-datetime.php:40 msgid "May" msgstr "" #: ../src/properties/class-papi-property-datetime.php:41 msgid "June" msgstr "" #: ../src/properties/class-papi-property-datetime.php:42 msgid "July" msgstr "" #: ../src/properties/class-papi-property-datetime.php:43 msgid "August" msgstr "" #: ../src/properties/class-papi-property-datetime.php:44 msgid "September" msgstr "" #: ../src/properties/class-papi-property-datetime.php:45 msgid "October" msgstr "" #: ../src/properties/class-papi-property-datetime.php:46 msgid "November" msgstr "" #: ../src/properties/class-papi-property-datetime.php:47 msgid "December" msgstr "" #: ../src/properties/class-papi-property-datetime.php:49 msgid "Noon" msgstr "" #: ../src/properties/class-papi-property-datetime.php:51 msgid "Sunday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:52 msgid "Monday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:53 msgid "Tuesday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:54 msgid "Wednesday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:55 msgid "Thursday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:56 msgid "Friday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:57 msgid "Saturday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:60 msgid "Sun" msgstr "" #: ../src/properties/class-papi-property-datetime.php:61 msgid "Mon" msgstr "" #: ../src/properties/class-papi-property-datetime.php:62 msgid "Tue" msgstr "" #: ../src/properties/class-papi-property-datetime.php:63 msgid "Wed" msgstr "" #: ../src/properties/class-papi-property-datetime.php:64 msgid "Thu" msgstr "" #: ../src/properties/class-papi-property-datetime.php:65 msgid "Fri" msgstr "" #: ../src/properties/class-papi-property-datetime.php:66 msgid "Sat" msgstr "" #: ../src/properties/class-papi-property-file.php:104 msgid "Add file" msgstr "" #: ../src/properties/class-papi-property-file.php:105 msgid "No file selected" msgstr "" #: ../src/properties/class-papi-property-flexible.php:655 #: ../src/properties/class-papi-property-repeater.php:636 msgid "Add new row" msgstr "Ajouter une nouvelle ligne" #: ../src/properties/class-papi-property-image.php:22 msgid "Add image" msgstr "Ajouter image" #: ../src/properties/class-papi-property-image.php:23 msgid "No image selected" msgstr "Aucune image sélectionnée" #: ../src/properties/class-papi-property-link.php:129 #: ../src/properties/class-papi-property-link.php:198 msgid "URL" msgstr "" #: ../src/properties/class-papi-property-link.php:148 #: ../src/properties/class-papi-property-link.php:217 msgid "Target" msgstr "" #: ../src/properties/class-papi-property-link.php:151 msgid "New window" msgstr "" #: ../src/properties/class-papi-property-link.php:151 msgid "Same window" msgstr "" #: ../src/properties/class-papi-property-link.php:161 msgid "No link selected" msgstr "" #: ../src/properties/class-papi-property-link.php:162 msgid "Add link" msgstr "" #: ../src/properties/class-papi-property-link.php:165 msgid "Edit link" msgstr "" #: ../src/properties/class-papi-property-link.php:166 msgid "Remove link" msgstr "" #: ../src/properties/class-papi-property-reference.php:91 msgid "No references exists" msgstr "Aucune référence existe" #: ../src/properties/class-papi-property-relationship.php:93 msgid "Post" msgstr "" #: ../src/properties/class-papi-property-relationship.php:125 msgid "Name (alphabetically)" msgstr "Nom (alphabétiquement)" #: ../src/properties/class-papi-property-relationship.php:133 msgid "Post created date (ascending)" msgstr "Article par date de création (croissant)" #: ../src/properties/class-papi-property-relationship.php:137 msgid "Post created date (descending)" msgstr "Article par date de création (décroissant)" #: ../src/properties/class-papi-property-relationship.php:141 msgid "Post id (ascending)" msgstr "ID article (croissant)" #: ../src/properties/class-papi-property-relationship.php:146 msgid "Post id (descending)" msgstr "ID article (décroissant)" #: ../src/properties/class-papi-property-relationship.php:151 msgid "Post order value (ascending)" msgstr "Article par champ ordre (croissant)" #: ../src/properties/class-papi-property-relationship.php:155 msgid "Post order value (descending)" msgstr "Article par champ ordre (décroissant)" #: ../src/properties/class-papi-property-relationship.php:159 msgid "Post modified date (ascending)" msgstr "Article par date de modification (croissant)" #: ../src/properties/class-papi-property-relationship.php:164 msgid "Post modified date (descending)" msgstr "Article par date de modification (décroissant)" #: ../src/properties/class-papi-property-relationship.php:254 msgid "Search" msgstr "Recherche" #: ../src/properties/class-papi-property-relationship.php:259 msgid "Sort by" msgstr "Trier par" #: ../src/properties/class-papi-property-term.php:65 msgid "No taxonomy defined for term property" msgstr "" #: ../src/properties/class-papi-property-url.php:42 msgid "Select file" msgstr "Sélectionnez un fichier" #: ../src/types/class-papi-page-type-meta.php:158 msgid "Edit" msgstr "Modifier" #: ../src/types/class-papi-page-type-meta.php:163 msgid "View" msgstr "Voir" #~ msgid "Show all page types" #~ msgstr "Voir tous les types de pages" #~ msgid "Add new page type" #~ msgstr "Ajouter une nouvelle page" #~ msgid "Search page types" #~ msgstr "Recherche dans les types de page" #~ msgid "Back to list" #~ msgstr "Retour à la liste" #~ msgid "Page Type" #~ msgstr "Type de page" ================================================ FILE: languages/papi-sv_SE.po ================================================ msgid "" msgstr "" "Project-Id-Version: Papi\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" "PO-Revision-Date: 2017-03-20 11:51+0100\n" "Last-Translator: Rasmus Bengtsson \n" "Language-Team: \n" "Language: sv_SE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.12\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;" "_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n" "X-Poedit-SearchPath-0: ../src\n" #: ../src/papi-loader.php:75, ../src/papi-loader.php:84, #: ../src/admin/class-papi-admin.php:38, ../src/admin/class-papi-admin.php:47 msgid "Cheatin’ huh?" msgstr "Fuskar du?" #: ../src/papi-loader.php:244 msgid "" "WordPress 4.4 and higher required to run Papi! The plugin has now disabled " "itself." msgstr "" "WordPress 4.4 eller högre krävs för att köra Papi! Tillägget har nu " "inaktiverat sig." #: ../src/admin/class-papi-admin-assets.php:51 msgid "Close" msgstr "Stäng" #: ../src/admin/class-papi-admin-assets.php:52, #: ../src/admin/class-papi-admin-page-type-switcher.php:39, #: ../src/types/class-papi-page-type.php:204, #: ../src/types/class-papi-taxonomy-type.php:67 msgid "Edit" msgstr "Redigera" #: ../src/admin/class-papi-admin-assets.php:53, #: ../src/properties/class-papi-property-flexible.php:824, #: ../src/properties/class-papi-property-flexible.php:847, #: ../src/properties/class-papi-property-repeater.php:790, #: ../src/properties/class-papi-property-repeater.php:812 msgid "Remove" msgstr "Ta bort" #: ../src/admin/class-papi-admin-assets.php:54 msgid "This fields are required:" msgstr "Dessa fält är obligatoriska:" #: ../src/admin/class-papi-admin-columns.php:68 msgid "Type" msgstr "Typ" #: ../src/admin/class-papi-admin-columns.php:175 msgid "All types" msgstr "Alla typer" #: ../src/admin/class-papi-admin-entry-taxonomy.php:50 msgid "%s type" msgstr "%styp" #: ../src/admin/class-papi-admin-menu.php:125, #: ../src/admin/class-papi-admin-menu.php:172, #: ../src/admin/class-papi-admin-menu.php:173, #: ../src/types/class-papi-page-type.php:203, #: ../src/types/class-papi-taxonomy-type.php:66 msgid "Add New" msgstr "Skapa ny" #: ../src/admin/class-papi-admin-page-type-switcher.php:35 msgid "Page Type:" msgstr "Sidtyp:" #: ../src/admin/class-papi-admin-page-type-switcher.php:57 msgid "OK" msgstr "OK" #: ../src/admin/class-papi-admin-page-type-switcher.php:58 msgid "Cancel" msgstr "Avbryt" #: ../src/admin/class-papi-admin.php:185 msgid "View Papi Documentation" msgstr "Läs Papi dokumentationen" #: ../src/admin/class-papi-admin.php:185 msgid "Docs" msgstr "Dokumentation" #: ../src/properties/class-papi-property-datetime.php:32 msgid "Previous Month" msgstr "Föregående månad" #: ../src/properties/class-papi-property-datetime.php:33 msgid "Next Month" msgstr "Nästa månad" #: ../src/properties/class-papi-property-datetime.php:34 msgid "Midnight" msgstr "Midnatt" #: ../src/properties/class-papi-property-datetime.php:36 msgid "January" msgstr "Januari" #: ../src/properties/class-papi-property-datetime.php:37 msgid "February" msgstr "Februari" #: ../src/properties/class-papi-property-datetime.php:38 msgid "March" msgstr "Mars" #: ../src/properties/class-papi-property-datetime.php:39 msgid "April" msgstr "April" #: ../src/properties/class-papi-property-datetime.php:40 msgid "May" msgstr "Maj" #: ../src/properties/class-papi-property-datetime.php:41 msgid "June" msgstr "Juni" #: ../src/properties/class-papi-property-datetime.php:42 msgid "July" msgstr "Juli" #: ../src/properties/class-papi-property-datetime.php:43 msgid "August" msgstr "Augusti" #: ../src/properties/class-papi-property-datetime.php:44 msgid "September" msgstr "September" #: ../src/properties/class-papi-property-datetime.php:45 msgid "October" msgstr "Oktober" #: ../src/properties/class-papi-property-datetime.php:46 msgid "November" msgstr "November" #: ../src/properties/class-papi-property-datetime.php:47 msgid "December" msgstr "December" #: ../src/properties/class-papi-property-datetime.php:49 msgid "Noon" msgstr "Eftermiddag" #: ../src/properties/class-papi-property-datetime.php:51 msgid "Sunday" msgstr "Söndag" #: ../src/properties/class-papi-property-datetime.php:52 msgid "Monday" msgstr "Måndag" #: ../src/properties/class-papi-property-datetime.php:53 msgid "Tuesday" msgstr "Tisdag" #: ../src/properties/class-papi-property-datetime.php:54 msgid "Wednesday" msgstr "Onsdag" #: ../src/properties/class-papi-property-datetime.php:55 msgid "Thursday" msgstr "Torsdag" #: ../src/properties/class-papi-property-datetime.php:56 msgid "Friday" msgstr "Fredag" #: ../src/properties/class-papi-property-datetime.php:57 msgid "Saturday" msgstr "Lördag" #: ../src/properties/class-papi-property-datetime.php:60 msgid "Sun" msgstr "Sön" #: ../src/properties/class-papi-property-datetime.php:61 msgid "Mon" msgstr "Mån" #: ../src/properties/class-papi-property-datetime.php:62 msgid "Tue" msgstr "Tis" #: ../src/properties/class-papi-property-datetime.php:63 msgid "Wed" msgstr "Ons" #: ../src/properties/class-papi-property-datetime.php:64 msgid "Thu" msgstr "Tor" #: ../src/properties/class-papi-property-datetime.php:65 msgid "Fri" msgstr "Fre" #: ../src/properties/class-papi-property-datetime.php:66 msgid "Sat" msgstr "Lör" #: ../src/properties/class-papi-property-file.php:117 msgid "Add file" msgstr "Lägg till fil" #: ../src/properties/class-papi-property-file.php:118 msgid "No file selected" msgstr "Ingen fil vald" #: ../src/properties/class-papi-property-image.php:22 msgid "Add image" msgstr "Lägg till bild" #: ../src/properties/class-papi-property-image.php:23 msgid "No image selected" msgstr "Ingen bild vald" #: ../src/properties/class-papi-property-link.php:127, #: ../src/properties/class-papi-property-link.php:240 msgid "URL" msgstr "URL" #: ../src/properties/class-papi-property-link.php:135, #: ../src/properties/class-papi-property-link.php:250 msgid "Title" msgstr "Rubrik" #: ../src/properties/class-papi-property-link.php:142, #: ../src/properties/class-papi-property-link.php:259 msgid "Target" msgstr "Mål" #: ../src/properties/class-papi-property-link.php:144, #: ../src/properties/class-papi-property-link.php:263 msgid "New window" msgstr "Nytt fönster" #: ../src/properties/class-papi-property-link.php:144, #: ../src/properties/class-papi-property-link.php:263 msgid "Same window" msgstr "Samma fönster" #: ../src/properties/class-papi-property-link.php:154 msgid "No link selected" msgstr "Ingen länk vald" #: ../src/properties/class-papi-property-link.php:155 msgid "Add link" msgstr "Lägg till länk" #: ../src/properties/class-papi-property-link.php:158 msgid "Edit link" msgstr "Ändra länk" #: ../src/properties/class-papi-property-link.php:159 msgid "Remove link" msgstr "Ta bort länk" #: ../src/properties/class-papi-property-post.php:70 msgid "Select Post Type" msgstr "Välj post typ" #: ../src/properties/class-papi-property-post.php:71 msgid "Select %s" msgstr "Välj %s" #: ../src/properties/class-papi-property-reference.php:91 msgid "No references exists" msgstr "Inga referenser finns" #: ../src/properties/class-papi-property-relationship.php:145 msgid "Post" msgstr "Inlägg" #: ../src/properties/class-papi-property-relationship.php:334 msgid "Search" msgstr "Sök" #: ../src/properties/class-papi-property-relationship.php:339 msgid "Sort by" msgstr "Sortera efter" #: ../src/properties/class-papi-property-repeater.php:157 msgid "Add new row" msgstr "Lägg till ny rad" #: ../src/properties/class-papi-property-term.php:69 msgid "Select Taxonomy" msgstr "Välj taxonomi" #: ../src/properties/class-papi-property-term.php:70 msgid "Select %s term" msgstr "Välj %s term" #: ../src/properties/class-papi-property-url.php:42 msgid "Select file" msgstr "Välj fil" #: ../src/types/class-papi-page-type.php:205, #: ../src/types/class-papi-taxonomy-type.php:68 msgid "View" msgstr "Vy" #: ../src/admin/views/add-new-page.php:8 msgid "Add New %s" msgstr "Lägg till ny %s" #: ../src/lib/core/property.php:327 msgid "(required field)" msgstr "(obligatoriskt fält)" #: ../src/lib/hooks/filters-page-type.php:58 msgid "%s with WordPress standard fields" msgstr "%s med Wordpress standardfält" #: ../src/lib/hooks/filters-page-type.php:80, #: ../src/lib/hooks/filters-taxonomy-type.php:31 msgid "Standard %s" msgstr "Standard %s" #: ../src/admin/views/partials/add-new-item.php:9 msgid "Thumbnail missing" msgstr "Bild saknas" #: ../src/admin/views/partials/add-new-item.php:22 msgid "Select" msgstr "Välj" #~ msgid "" #~ "WordPress 4.0 and higher required to run Papi! The plugin has now " #~ "disabled itself." #~ msgstr "" #~ "Wordpress 4.0 och högre krävs för att köra Papi! Tillägget har nu " #~ "inaktiverat sig själv." #~ msgid "Name (alphabetically)" #~ msgstr "Enligt namn (alfabetiskt)" #~ msgid "Post created date (ascending)" #~ msgstr "Enligt publiceringsdatum (stigande)" #~ msgid "Post created date (descending)" #~ msgstr "Enligt publiceringsdatum (fallande)" #~ msgid "Post id (ascending)" #~ msgstr "Enligt sidans id (stigande)" #~ msgid "Post id (descending)" #~ msgstr "Enligt sidans id (fallande)" #~ msgid "Post order value (ascending)" #~ msgstr "Post ordervärde (stigande)" #~ msgid "Post order value (descending)" #~ msgstr "Post ordervärde (fallande)" #~ msgid "Post modified date (ascending)" #~ msgstr "Enligt ändringsdatum (stigande)" #~ msgid "Post modified date (descending)" #~ msgstr "Enligt ändringsdatum (fallande)" #~ msgid "Tab Title" #~ msgstr "Flikens rubrik" #~ msgid "Sort Order" #~ msgstr "Sorteringsordning" #~ msgid "Properties" #~ msgstr "Egenskaper" #~ msgid "Slug" #~ msgstr "Adress" #~ msgid "Cannot find the page type" #~ msgstr "Kan inte hitta sidtypen" #~ msgid "Overview of page type" #~ msgstr "Översikt över sidtyper" #~ msgid "No meta boxes exists." #~ msgstr "Inga meta boxar existerar." #~ msgid "Tabs" #~ msgstr "Tabbar" #~ msgid "Page Types" #~ msgstr "Sidtyper" #~ msgid "Name" #~ msgstr "Namn" #~ msgid "Page Type ID" #~ msgstr "Sidtyp ID" #~ msgid "Post types" #~ msgstr "Post typer" #~ msgid "Template" #~ msgstr "Mall" #~ msgid "Page Count" #~ msgstr "Antal sidor" #~ msgid "Page Type has no template file" #~ msgstr "Sidtypen har ingen mallfil" #~ msgid "Template file does not exist" #~ msgstr "Mallfilen finns inte" ================================================ FILE: languages/papi.pot ================================================ # Copyright (C) 2017 papi # This file is distributed under the same license as the papi package. msgid "" msgstr "" "Project-Id-Version: papi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: *.js\n" "X-Poedit-SourceCharset: UTF-8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../src/papi-loader.php:75, ../src/papi-loader.php:84, ../src/admin/class-papi-admin.php:38, ../src/admin/class-papi-admin.php:47 msgid "Cheatin’ huh?" msgstr "" #: ../src/papi-loader.php:244 msgid "WordPress 4.4 and higher required to run Papi! The plugin has now disabled itself." msgstr "" #: ../src/admin/class-papi-admin-assets.php:51 msgid "Close" msgstr "" #: ../src/admin/class-papi-admin-assets.php:52, ../src/admin/class-papi-admin-page-type-switcher.php:39, ../src/types/class-papi-page-type.php:204, ../src/types/class-papi-taxonomy-type.php:67 msgid "Edit" msgstr "" #: ../src/admin/class-papi-admin-assets.php:53, ../src/properties/class-papi-property-flexible.php:824, ../src/properties/class-papi-property-flexible.php:847, ../src/properties/class-papi-property-repeater.php:790, ../src/properties/class-papi-property-repeater.php:812 msgid "Remove" msgstr "" #: ../src/admin/class-papi-admin-assets.php:54 msgid "This fields are required:" msgstr "" #: ../src/admin/class-papi-admin-columns.php:68 msgid "Type" msgstr "" #: ../src/admin/class-papi-admin-columns.php:175 msgid "All types" msgstr "" #: ../src/admin/class-papi-admin-entry-taxonomy.php:50 msgid "%s type" msgstr "" #: ../src/admin/class-papi-admin-menu.php:125, ../src/admin/class-papi-admin-menu.php:172, ../src/admin/class-papi-admin-menu.php:173, ../src/types/class-papi-page-type.php:203, ../src/types/class-papi-taxonomy-type.php:66 msgid "Add New" msgstr "" #: ../src/admin/class-papi-admin-page-type-switcher.php:35 msgid "Page Type:" msgstr "" #: ../src/admin/class-papi-admin-page-type-switcher.php:57 msgid "OK" msgstr "" #: ../src/admin/class-papi-admin-page-type-switcher.php:58 msgid "Cancel" msgstr "" #: ../src/admin/class-papi-admin.php:185 msgid "View Papi Documentation" msgstr "" #: ../src/admin/class-papi-admin.php:185 msgid "Docs" msgstr "" #: ../src/properties/class-papi-property-datetime.php:32 msgid "Previous Month" msgstr "" #: ../src/properties/class-papi-property-datetime.php:33 msgid "Next Month" msgstr "" #: ../src/properties/class-papi-property-datetime.php:34 msgid "Midnight" msgstr "" #: ../src/properties/class-papi-property-datetime.php:36 msgid "January" msgstr "" #: ../src/properties/class-papi-property-datetime.php:37 msgid "February" msgstr "" #: ../src/properties/class-papi-property-datetime.php:38 msgid "March" msgstr "" #: ../src/properties/class-papi-property-datetime.php:39 msgid "April" msgstr "" #: ../src/properties/class-papi-property-datetime.php:40 msgid "May" msgstr "" #: ../src/properties/class-papi-property-datetime.php:41 msgid "June" msgstr "" #: ../src/properties/class-papi-property-datetime.php:42 msgid "July" msgstr "" #: ../src/properties/class-papi-property-datetime.php:43 msgid "August" msgstr "" #: ../src/properties/class-papi-property-datetime.php:44 msgid "September" msgstr "" #: ../src/properties/class-papi-property-datetime.php:45 msgid "October" msgstr "" #: ../src/properties/class-papi-property-datetime.php:46 msgid "November" msgstr "" #: ../src/properties/class-papi-property-datetime.php:47 msgid "December" msgstr "" #: ../src/properties/class-papi-property-datetime.php:49 msgid "Noon" msgstr "" #: ../src/properties/class-papi-property-datetime.php:51 msgid "Sunday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:52 msgid "Monday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:53 msgid "Tuesday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:54 msgid "Wednesday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:55 msgid "Thursday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:56 msgid "Friday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:57 msgid "Saturday" msgstr "" #: ../src/properties/class-papi-property-datetime.php:60 msgid "Sun" msgstr "" #: ../src/properties/class-papi-property-datetime.php:61 msgid "Mon" msgstr "" #: ../src/properties/class-papi-property-datetime.php:62 msgid "Tue" msgstr "" #: ../src/properties/class-papi-property-datetime.php:63 msgid "Wed" msgstr "" #: ../src/properties/class-papi-property-datetime.php:64 msgid "Thu" msgstr "" #: ../src/properties/class-papi-property-datetime.php:65 msgid "Fri" msgstr "" #: ../src/properties/class-papi-property-datetime.php:66 msgid "Sat" msgstr "" #: ../src/properties/class-papi-property-file.php:117 msgid "Add file" msgstr "" #: ../src/properties/class-papi-property-file.php:118 msgid "No file selected" msgstr "" #: ../src/properties/class-papi-property-image.php:22 msgid "Add image" msgstr "" #: ../src/properties/class-papi-property-image.php:23 msgid "No image selected" msgstr "" #: ../src/properties/class-papi-property-link.php:127, ../src/properties/class-papi-property-link.php:240 msgid "URL" msgstr "" #: ../src/properties/class-papi-property-link.php:135, ../src/properties/class-papi-property-link.php:250 msgid "Title" msgstr "" #: ../src/properties/class-papi-property-link.php:142, ../src/properties/class-papi-property-link.php:259 msgid "Target" msgstr "" #: ../src/properties/class-papi-property-link.php:144, ../src/properties/class-papi-property-link.php:263 msgid "New window" msgstr "" #: ../src/properties/class-papi-property-link.php:144, ../src/properties/class-papi-property-link.php:263 msgid "Same window" msgstr "" #: ../src/properties/class-papi-property-link.php:154 msgid "No link selected" msgstr "" #: ../src/properties/class-papi-property-link.php:155 msgid "Add link" msgstr "" #: ../src/properties/class-papi-property-link.php:158 msgid "Edit link" msgstr "" #: ../src/properties/class-papi-property-link.php:159 msgid "Remove link" msgstr "" #: ../src/properties/class-papi-property-post.php:70 msgid "Select Post Type" msgstr "" #: ../src/properties/class-papi-property-post.php:71 msgid "Select %s" msgstr "" #: ../src/properties/class-papi-property-reference.php:91 msgid "No references exists" msgstr "" #: ../src/properties/class-papi-property-relationship.php:145 msgid "Post" msgstr "" #: ../src/properties/class-papi-property-relationship.php:334 msgid "Search" msgstr "" #: ../src/properties/class-papi-property-relationship.php:339 msgid "Sort by" msgstr "" #: ../src/properties/class-papi-property-repeater.php:157 msgid "Add new row" msgstr "" #: ../src/properties/class-papi-property-term.php:69 msgid "Select Taxonomy" msgstr "" #: ../src/properties/class-papi-property-term.php:70 msgid "Select %s term" msgstr "" #: ../src/properties/class-papi-property-url.php:42 msgid "Select file" msgstr "" #: ../src/types/class-papi-page-type.php:205, ../src/types/class-papi-taxonomy-type.php:68 msgid "View" msgstr "" #: ../src/admin/views/add-new-page.php:8 msgid "Add New %s" msgstr "" #: ../src/lib/core/property.php:327 msgid "(required field)" msgstr "" #: ../src/lib/hooks/filters-page-type.php:58 msgid "%s with WordPress standard fields" msgstr "" #: ../src/lib/hooks/filters-page-type.php:80, ../src/lib/hooks/filters-taxonomy-type.php:31 msgid "Standard %s" msgstr "" #: ../src/admin/views/partials/add-new-item.php:9 msgid "Thumbnail missing" msgstr "" #: ../src/admin/views/partials/add-new-item.php:22 msgid "Select" msgstr "" ================================================ FILE: package.json ================================================ { "name": "papi", "version": "3.2.0", "repository": "wp-papi/papi", "description": "WordPress Page Type API with custom fields", "author": "Fredrik Forsmo ", "license": "MIT", "dependencies": { "moment": "^2.29", "select2": "^4.0.5" }, "devDependencies": { "@babel/core": "^7.8.7", "@jitesoft/babel-preset-main": "^2.1.5", "autoprefixer-cli": "^1.0", "babel": "^6.5", "babel-core": "^6.17", "babel-eslint": "^10.1.0", "babel-loader": "^8.0.6", "babel-preset-es2015": "^6.18", "concurrently": "^5.1.0", "core-js": "^3.6.4", "csso-cli": "^3.0.0", "sass": "^1.17.2", "semistandard": "^14.2.0", "watch": "^1.0", "webpack": "^4.42.0", "webpack-cli": "^3.3.12" }, "scripts": { "build": "NODE_ENV=production npm run js", "css": "sass src/assets/scss/style.scss dist/css/style.css && autoprefixer-cli -b \"last 2 version\" dist/css/style.css dist/css/style.css && csso dist/css/style.css dist/css/style.min.css && echo \"\n/*# sourceMappingURL=style.min.css.map */\" >> dist/css/style.min.css && mv dist/css/style.css.map dist/css/style.min.css.map && rm dist/css/style.css", "js": "webpack", "lint": "semistandard --global papi --fix src/assets/js/*.js src/assets/js/properties/*.js", "watch": "concurrently \"watch:css\" \"watch:js\"", "watch:css": "watch \"npm run css\"", "watch:js": "watch \"npm run js\"" }, "semistandard": { "parser": "babel-eslint" } } ================================================ FILE: papi-loader.php ================================================ Papi rules for PHP_CodeSniffer node_modules/* vendor/* ================================================ FILE: phpunit.xml.dist ================================================ ./tests/cases ./src ================================================ FILE: src/admin/class-papi-admin-ajax.php ================================================ setup_actions(); $this->structure = get_option( 'permalink_structure' ); } /** * Add ajax endpoint. */ public function add_endpoint() { if ( empty( $this->structure ) ) { return; } add_rewrite_tag( '%action%', '([^/]*)' ); add_rewrite_rule( 'papi-ajax/([^/]*)/?', 'index.php?action=$matches[1]', 'top' ); } /** * Add ajax url to Papi JavaScript object. */ public function ajax_url() { if ( empty( $this->structure ) ) { $url = esc_url( home_url( 'index.php', is_ssl() ? 'https' : 'http' ) ); } else { $url = esc_url( home_url( '/papi-ajax/', is_ssl() ? 'https' : 'http' ) ); } ?> action_prefix . $ajax_action ) !== false ) { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } status_header( 200 ); do_action( $this->action_prefix . $ajax_action ); wp_die(); } } /** * Get entry type via GET. * * GET /papi-ajax/?action=get_entry_type */ public function get_entry_type() { $entry_type_id = papi_get_qs( 'entry_type' ); $entry_type = papi_get_entry_type_by_id( $entry_type_id ); if ( empty( $entry_type ) ) { $this->render_error( 'No entry type found' ); return; } wp_send_json( $entry_type ); } /** * Get posts via GET. * * Posts with empty title will be ignored. * * GET /papi-ajax/?action=get_posts */ public function get_posts() { $args = papi_get_qs( 'query' ) ?: []; $args = is_array( $args ) ? $args : []; $fields = papi_get_qs( 'fields' ) ?: []; $fields = is_array( $fields ) ? $fields : []; $posts = ( new WP_Query( array_merge( [ 'posts_per_page' => -1, 'post_status' => 'any', 'post_type' => ['post'], 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false ], $args ) ) )->posts; $posts = array_filter( $posts, function ( $post ) { return ! empty( $post->post_title ); } ); usort( $posts, function ( $a, $b ) { return strcmp( strtolower( $a->post_title ), strtolower( $b->post_title ) ); } ); if ( ! empty( $fields ) ) { foreach ( $posts as $index => $post ) { $item = []; foreach ( $fields as $field ) { $item[$field] = $post->$field; } $posts[$index] = $item; } } wp_send_json( $posts ); } /** * Get property html via GET. * * GET /papi-ajax/?action=get_property */ public function get_property() { $default_options = Papi_Core_Property::factory()->get_options(); $keys = array_keys( get_object_vars( $default_options ) ); $options = papi_get_qs( $keys, true ); if ( $property = papi_property( $options ) ) { ob_start(); $property->render_ajax_request(); $html = ob_get_clean(); wp_send_json( [ 'html' => utf8_encode( $html ) ] ); return; } $this->render_error( 'No property found' ); } /** * Get properties via POST. * * POST /papi-ajax/?action=get_properties */ public function get_properties() { if ( ! papi_get_sanitized_post( 'properties' ) ) { $this->render_error( 'No properties found' ); return; } $items = json_decode( stripslashes( $_POST['properties'] ), true ); if ( empty( $items ) || ! is_array( $items ) ) { $this->render_error( 'No properties found' ); return; } foreach ( $items as $key => $item ) { $property = papi_property( (array) $item ); if ( ! papi_is_property( $property ) ) { unset( $items[$key] ); continue; } ob_start(); $property->render_ajax_request(); $items[$key] = trim( ob_get_clean() ); } $items = array_filter( $items ); if ( empty( $items ) ) { $this->render_error( 'No properties found' ); return; } wp_send_json( [ 'html' => $items ] ); } /** * Get rules result via GET. * * GET /papi-ajax/?action=get_rules_result */ public function get_rules_result() { if ( ! papi_get_sanitized_post( 'data' ) ) { $this->render_error( 'No rule found' ); return; } $data = json_decode( stripslashes( papi_get_sanitized_post( 'data' ) ), true ); if ( empty( $data ) || ! is_array( $data ) || ! isset( $data['slug'] ) ) { $this->render_error( 'No rule found' ); return; } $entry_type = papi_get_entry_type_by_meta_id(); if ( empty( $entry_type ) ) { $entry_type_id = papi_get_qs( 'entry_type' ); $entry_type = papi_get_entry_type_by_id( $entry_type_id ); } if ( $entry_type instanceof Papi_Entry_Type === false ) { $this->render_error( 'No rule found' ); return; } if ( preg_match( '/\[\]$/', $data['slug'] ) ) { $data['slug'] = preg_replace( '/\[\]$/', '', $data['slug'] ); } if ( $property = $entry_type->get_property( $data['slug'] ) ) { wp_send_json( [ 'render' => $property->render_is_allowed_by_rules( $data['rules'] ) ] ); return; } $this->render_error( 'No rule found' ); } /** * Get shortcode via GET. * * GET /papi-ajax/?action=get_shortcode */ public function get_shortcode() { $shortcode = papi_get_qs( 'shortcode' ) ?: ''; $shortcode = html_entity_decode( $shortcode ); $shortcode = wp_unslash( $shortcode ); wp_send_json( [ 'html' => do_shortcode( $shortcode ) ] ); } /** * Get terms via GET. * * GET /papi-ajax/?action=get_terms */ public function get_terms() { $query = papi_get_qs( 'query' ) ?: []; $query = is_array( $query ) ? $query : []; $taxonomy = papi_get_qs( 'taxonomy' ) ?: ''; $args = array_merge( [ 'fields' => 'id=>name' ], $query ); $terms = []; if ( taxonomy_exists( $taxonomy ) ) { $terms = get_terms( $taxonomy, $args ); } wp_send_json( $terms ); } /** * Render error message. * * @param string $message */ public function render_error( $message ) { wp_send_json( [ 'error' => $message ] ); } /** * Setup action hooks. */ protected function setup_actions() { add_action( 'init', [$this, 'add_endpoint'] ); add_action( 'parse_request', [$this, 'handle_papi_ajax'] ); add_action( 'admin_enqueue_scripts', [$this, 'ajax_url'], 10 ); // Ajax actions. add_action( $this->action_prefix . 'get_entry_type', [$this, 'get_entry_type'] ); add_action( $this->action_prefix . 'get_property', [$this, 'get_property'] ); add_action( $this->action_prefix . 'get_properties', [$this, 'get_properties'] ); add_action( $this->action_prefix . 'get_rules_result', [$this, 'get_rules_result'] ); add_action( $this->action_prefix . 'get_posts', [$this, 'get_posts'] ); add_action( $this->action_prefix . 'get_terms', [$this, 'get_terms'] ); add_action( $this->action_prefix . 'get_shortcode', [$this, 'get_shortcode'] ); } } new Papi_Admin_Ajax; ================================================ FILE: src/admin/class-papi-admin-assets.php ================================================ __( 'Close', 'default' ), 'edit' => __( 'Edit', 'default' ), 'new' => __( 'New', 'default' ), 'remove' => __( 'Remove', 'default' ), 'requiredError' => __( 'This fields are required:', 'papi' ), ] ); } } if ( papi_is_admin() ) { new Papi_Admin_Assets; } ================================================ FILE: src/admin/class-papi-admin-columns.php ================================================ setup_globals(); $this->setup_actions(); $this->setup_filters(); } /** * Get meta type value. * * @return string */ protected function get_meta_type_value() { return empty( $this->taxonomy ) ? $this->post_type : $this->taxonomy; } /** * Add custom table header to page or taxonomy type. * * @param array $defaults * * @return array */ public function manage_page_type_posts_columns( array $defaults = [] ) { if ( ! in_array( $this->post_type, papi_get_post_types(), true ) && ! in_array( $this->taxonomy, papi_get_taxonomies(), true ) ) { return $defaults; } /** * Hide column for post or taxonomy type. Default is false. * * @param string $post_type */ if ( apply_filters( 'papi/settings/column_hide_' . $this->get_meta_type_value(), false ) ) { return $defaults; } /** * Change column title for entry type column. * * @param string $post_type */ $defaults['entry_type'] = apply_filters( 'papi/settings/column_title_' . $this->get_meta_type_value(), esc_html__( 'Type', 'papi' ) ); return $defaults; } /** * Add custom table column to page or taxonomy type. * * @param string $column_name * @param int $post_id * @param int $term_id */ public function manage_page_type_posts_custom_column( $column_name, $post_id, $term_id = null ) { if ( ! in_array( $this->post_type, papi_get_post_types(), true ) && ! in_array( $this->taxonomy, papi_get_taxonomies(), true ) ) { return; } /** * Hide column for post type. Default is false. * * @param string $post_type */ if ( apply_filters( 'papi/settings/column_hide_' . $this->get_meta_type_value(), false ) ) { return; } // Column name most be `entry_type`. On taxomy the column name is `post_id` variable. if ( $column_name !== 'entry_type' && $post_id !== 'entry_type' ) { return; } // Get the entry type for the post or term. $entry_type = papi_get_entry_type_by_meta_id( is_numeric( $post_id ) ? $post_id : $term_id, papi_get_meta_type() ); $post = ! empty( $this->post_type ) && empty( $this->taxonomy ); $type = $post ? 'page' : 'taxonomy'; $arg = $post ? papi_get_post_type() : papi_get_taxonomy(); $show = call_user_func_array( "papi_filter_settings_show_standard_{$type}_type", [$arg] ); if ( ! is_null( $entry_type ) && ( $show === false || get_metadata( papi_get_meta_type( $type ), ( is_numeric( $post_id ) ? $post_id : $term_id ), papi_get_page_type_key(), true ) === $entry_type->get_id() ) ) { echo esc_html( $entry_type->name ); } else { echo esc_html( call_user_func_array( "papi_filter_settings_standard_{$type}_type_name", [$arg] ) ); } } /** * Add entry type as a sortable column. * * @param array $columns * * @return array */ public function manage_page_type_sortable_columns( $columns ) { if ( in_array( $this->post_type, papi_get_post_types(), true ) || in_array( $this->taxonomy, papi_get_taxonomies(), true ) ) { $columns['entry_type'] = 'entry_type'; } return $columns; } /** * Filter posts on load if `page_type` query string is set. * * @param WP_Query $query * * @return WP_Query */ public function pre_get_posts( WP_Query $query ) { global $pagenow; if ( $pagenow === 'edit.php' && ! is_null( papi_get_qs( 'page_type' ) ) ) { if ( papi_get_qs( 'page_type' ) === 'papi-standard-page' ) { $query->set( 'meta_query', [ [ 'key' => papi_get_page_type_key(), 'compare' => 'NOT EXISTS' ] ] ); } else { $query->set( 'meta_key', papi_get_page_type_key() ); $query->set( 'meta_value', papi_get_qs( 'page_type' ) ); } } // Order query result by entry type. if ( $query->get( 'orderby' ) === 'entry_type' ) { $query->set( 'meta_key', papi_get_page_type_key() ); $query->set( 'orderby', 'meta_value' ); } return $query; } /** * Filter page types in post type list. */ public function restrict_page_types() { $post_types = papi_get_post_types(); if ( in_array( $this->post_type, $post_types, true ) ) { $page_types = papi_get_all_page_types( $this->post_type ); $page_types = array_map( function ( $page_type ) { return [ 'name' => $page_type->name, 'value' => $page_type->get_id() ]; }, $page_types ); // Add the standard page that isn't a real page type. if ( papi_filter_settings_show_standard_page_type_in_filter( $this->post_type ) ) { $page_types[] = [ 'name' => papi_filter_settings_standard_page_type_name( $this->post_type ), 'value' => 'papi-standard-page' ]; } usort( $page_types, function ( $a, $b ) { return strcmp( strtolower( $a['name'] ), strtolower( $b['name'] ) ); } ); ?> post_type ) && empty( $this->taxonomy ) ) { add_filter( 'pre_get_posts', [$this, 'pre_get_posts'] ); add_action( 'restrict_manage_posts', [$this, 'restrict_page_types'] ); add_action( sprintf( 'manage_%s_posts_custom_column', $this->post_type ), [$this, 'manage_page_type_posts_custom_column'], 10, 2 ); } // Setup taxonomy actions. if ( ! empty( $this->taxonomy ) ) { add_action( sprintf( 'manage_%s_custom_column', $this->taxonomy ), [$this, 'manage_page_type_posts_custom_column'], 10, 3 ); } } /** * Setup filters. */ protected function setup_filters() { // Setup post type actions. if ( ! empty( $this->post_type ) && empty( $this->taxonomy ) ) { add_filter( sprintf( 'manage_%s_posts_columns', $this->post_type ), [$this, 'manage_page_type_posts_columns'] ); add_filter( sprintf( 'manage_edit-%s_sortable_columns', $this->post_type ), [$this, 'manage_page_type_sortable_columns'] ); } // Setup taxonomy actions. if ( ! empty( $this->taxonomy ) ) { add_filter( sprintf( 'manage_edit-%s_columns', $this->taxonomy ), [$this, 'manage_page_type_posts_columns'] ); add_filter( sprintf( 'manage_edit-%s_sortable_columns', $this->taxonomy ), [$this, 'manage_page_type_sortable_columns'] ); } } /** * Setup globals. */ protected function setup_globals() { $this->post_type = papi_get_post_type(); $this->taxonomy = papi_get_taxonomy(); } } if ( papi_is_admin() ) { new Papi_Admin_Columns; } ================================================ FILE: src/admin/class-papi-admin-entry-post.php ================================================ post_type = papi_get_post_type(); $this->setup_actions(); $this->setup_filters(); } /** * Filters the fields displayed in the post revision diff UI. * * @param array $return * @param WP_Post $compare_from * @param WP_Post $compare_to * * @return array */ public function get_revision_ui_diff( $return, $compare_from, $compare_to ) { $meta = get_post_meta( $compare_from->ID ); $meta = is_array( $meta ) ? $meta : []; foreach ( $meta as $key => $value ) { if ( $key[0] === '_' && $key !== papi_get_page_type_key() ) { continue; } $content_from = papi_data_get( $compare_from->ID, $key ); $content_to = papi_data_get( $compare_to->ID, $key ); $diff = wp_text_diff( $content_from, $content_to, [ 'show_split_view' => true ] ); if ( $diff ) { $return[] = [ 'id' => $key, 'name' => $key, 'diff' => $diff, ]; } } return $return; } /** * Output hidden meta boxes. */ public function hidden_meta_boxes() { global $_wp_post_type_features; if ( isset( $_wp_post_type_features[$this->post_type]['editor'] ) ) { return; } add_meta_box( 'papi-hidden-editor', 'Papi hidden editor', [$this, 'hidden_meta_box_editor'], $this->post_type ); } /** * Output hidden WordPress editor. */ public function hidden_meta_box_editor() { wp_editor( '', 'papiHiddenEditor' ); } /** * Load post new action * Redirect to right url if no page type is set. */ public function load_post_new() { $request_uri = $_SERVER['REQUEST_URI']; $post_types = papi_get_post_types(); if ( in_array( $this->post_type, $post_types, true ) && strpos( $request_uri, 'page_type=' ) === false ) { $parsed_url = parse_url( $request_uri ); $only_page_type = papi_filter_settings_only_page_type( $this->post_type ); $page_types = papi_get_all_page_types( $this->post_type ); $show_standard = false; if ( count( $page_types ) === 1 && empty( $only_page_type ) ) { $show_standard = $page_types[0]->standard_type; $show_standard = $show_standard ? papi_filter_settings_show_standard_page_type( $this->post_type ) : $show_standard; $only_page_type = $show_standard ? '' : $page_types[0]->get_id(); } // Check if we should show one post type or not and // create the right url for that. if ( ! empty( $only_page_type ) && ! $show_standard ) { $url = papi_get_page_new_url( $only_page_type, false ); } else { $page = 'page=papi-add-new-page,' . $this->post_type; if ( $this->post_type !== 'post' ) { $page = '&' . $page; } $url = 'edit.php?' . $parsed_url['query'] . $page; } wp_safe_redirect( $url ); papi_is_admin() && exit; } } /** * Redirect post location when post is in iframe mode. * * @param string $location * * @return string */ public function redirect_post_location( $location ) { if ( ! isset( $_SERVER['HTTP_REFERER'] ) ) { return $location; } $referer = $_SERVER['HTTP_REFERER']; $referer = strtolower( $referer ); if ( strpos( $referer, 'papi-iframe-mode' ) === false ) { return $location; } return sprintf( '%s&papi_css[]=papi-iframe-mode', $location ); } /** * Setup admin entry. */ public function setup() { // Preload all page types. foreach ( papi_get_post_types() as $post_type ) { papi_get_all_entry_types( [ 'args' => $post_type ] ); } return ! in_array( $this->post_type, ['revision', 'nav_menu_item'], true ); } /** * Setup actions. */ protected function setup_actions() { add_action( 'load-post-new.php', [$this, 'load_post_new'] ); add_action( 'add_meta_boxes', [$this, 'hidden_meta_boxes'], 10 ); add_action( 'redirect_post_location', [$this, 'redirect_post_location'] ); } /** * Setup filters. */ protected function setup_filters() { add_filter( 'wp_get_revision_ui_diff', [$this, 'get_revision_ui_diff'], 10, 3 ); } } if ( papi_is_admin() ) { Papi_Admin_Entry_Post::instance(); } ================================================ FILE: src/admin/class-papi-admin-entry-taxonomy.php ================================================ setup_actions(); } /** * Add form fields to edit tags page. */ public function add_form_fields() { $html_name = esc_attr( papi_get_page_type_key() ); $taxonomy = papi_get_qs( 'taxonomy' ); $taxonomy_object = get_taxonomy( $taxonomy ); // Get only the taxonomy types that has the taxonomy. $taxonomy_types = array_filter( $this->taxonomy_types, function ( $taxonomy_type ) use ( $taxonomy ) { return in_array( $taxonomy, $taxonomy_type->taxonomy, true ) && $taxonomy_type->display( $taxonomy ); } ); $taxonomy_types = array_values( $taxonomy_types ); // Do not display empty select if no taxonomy types. if ( empty( $taxonomy_types ) ) { return; } // Prepare taxonomy types with standard taxonomy type. $taxonomy_types = $this->prepare_taxonomy_types( $taxonomy_types ); // Render a dropdown if more than one taxonomy types // exists on the taxonomy. if ( count( $taxonomy_types ) > 1 ): ?>
$taxonomy_types[0]->redirect_after_create, 'data-papi-page-type-key' => true, 'name' => esc_attr( $html_name ), 'type' => 'hidden', 'value' => esc_attr( $taxonomy_types[0]->get_id() ) ] ); endif; } /** * Prepare taxonomy types, add standard taxonomy if it should be added. * * @param array $taxonomy_types * * @return array */ protected function prepare_taxonomy_types( array $taxonomy_types ) { $taxonomy = papi_get_qs( 'taxonomy' ); if ( papi_filter_settings_show_standard_taxonomy_type( $taxonomy ) ) { $id = sprintf( 'papi-standard-%s-type', $taxonomy ); $taxonomy_type = new Papi_Taxonomy_Type( $id ); $taxonomy_type->id = $id; $taxonomy_type->name = papi_filter_settings_standard_taxonomy_type_name( $taxonomy ); $taxonomy_type->taxonomy = [$taxonomy]; $taxonomy_types[] = $taxonomy_type; } usort( $taxonomy_types, function ( $a, $b ) { return strcmp( $a->name, $b->name ); } ); return papi_sort_order( array_reverse( $taxonomy_types ) ); } /** * Setup actions. */ protected function setup_actions() { add_action( 'admin_init', [$this, 'setup_taxonomies_hooks'] ); } /** * Setup hooks for all taxonomies. */ public function setup_taxonomies_hooks() { $this->taxonomy_types = papi_get_all_entry_types( [ 'types' => 'taxonomy' ] ); $taxonomies = array_reduce( $this->taxonomy_types, function ( $taxonomies, $taxonomy_type ) { return array_merge( $taxonomies, $taxonomy_type->taxonomy ); }, [] ); $taxonomies = array_unique( $taxonomies ); foreach ( $taxonomies as $taxonomy ) { if ( is_string( $taxonomy ) && taxonomy_exists( $taxonomy ) ) { add_action( $taxonomy . '_add_form_fields', [$this, 'add_form_fields'] ); } } } } if ( papi_is_admin() ) { Papi_Admin_Entry_Taxonomy::instance(); } ================================================ FILE: src/admin/class-papi-admin-entry.php ================================================ setup_actions(); } /** * Fill labels on admin bar. */ public function admin_bar_menu() { if ( $entry_type = $this->get_entry_type() ) { $this->override_labels( $entry_type ); } } /** * Get current type class. * * @return Papi_Entry_Type */ protected function get_entry_type() { if ( $entry_type = papi_get_entry_type_by_id( papi_get_entry_type_id() ) ) { return $entry_type; } } /** * Override labels with labels from the entry type. * * @param Papi_Entry_Type $entry_type */ protected function override_labels( Papi_Entry_Type $entry_type ) { global $wp_post_types, $wp_taxonomies; if ( $entry_type->get_type() === 'taxonomy' ) { $meta_type_value = papi_get_taxonomy(); } else { $meta_type_value = papi_get_post_type(); } if ( empty( $meta_type_value ) || ( ! isset( $wp_post_types[$meta_type_value] ) && ! isset( $wp_taxonomies[$meta_type_value] ) ) ) { return; } foreach ( $entry_type->get_labels() as $key => $value ) { if ( empty( $value ) ) { continue; } if ( $entry_type->get_type() === 'taxonomy' && isset( $wp_taxonomies[$meta_type_value]->labels->$key ) ) { $wp_taxonomies[$meta_type_value]->labels->$key = $value; } else if ( isset( $wp_post_types[$meta_type_value]->labels->$key ) ) { $wp_post_types[$meta_type_value]->labels->$key = $value; } } } /** * Page items menu. * * This function will register all entry types * that has a fake post type. Like option types. */ public function page_items_menu() { $entry_types = papi_get_all_entry_types( [ 'mode' => 'exclude', 'types' => 'page' ] ); foreach ( $entry_types as $entry_type ) { if ( empty( $entry_type->get_menu() ) || empty( $entry_type->name ) ) { continue; } $slug = sprintf( 'papi/%s/%s', $entry_type->get_type(), $entry_type->get_id() ); add_submenu_page( $entry_type->get_menu(), $entry_type->name, $entry_type->name, $entry_type->capability, $slug, [$entry_type, 'render'] ); } } /** * Setup menu items for real post types. */ public function post_types_menu() { global $submenu; $post_types = papi_get_post_types(); foreach ( $post_types as $post_type ) { if ( ! post_type_exists( $post_type ) ) { continue; } if ( $post_type === 'post' ) { $edit_url = 'edit.php'; } else { $edit_url = 'edit.php?post_type=' . $post_type; } if ( ! isset( $submenu[$edit_url], $submenu[$edit_url][10], $submenu[$edit_url][10][2] ) ) { $post_type_object = get_post_type_object( $post_type ); if ( $post_type_object->show_in_menu !== true ) { $submenu[$edit_url] = [ 10 => [ __( 'Add New', 'papi' ), 'edit_posts', 'post-new.php' ] ]; } else { continue; } } $only_page_type = papi_filter_settings_only_page_type( $post_type ); $page_types = papi_get_all_page_types( $post_type ); $show_standard = false; // Don't change menu item when no page types is found. if ( empty( $page_types ) ) { continue; } if ( count( $page_types ) === 1 && empty( $only_page_type ) ) { $show_standard = papi_filter_settings_show_standard_page_type( $post_type ); $only_page_type = $show_standard ? '' : $page_types[0]->get_id(); } if ( ! empty( $only_page_type ) && ! $show_standard ) { $submenu[$edit_url][10][2] = papi_get_page_new_url( $only_page_type, false, $post_type, [ 'post_parent', 'lang' ] ); } else { $page = 'papi-add-new-page,' . $post_type; $start = strpos( $edit_url, 'post_type' ) === false ? '?' : '&'; $submenu[$edit_url][10][2] = sprintf( '%s%spage=%s', $edit_url, $start, $page ); // Add menu item. add_menu_page( __( 'Add New', 'papi' ), __( 'Add New', 'papi' ), 'read', $page, [$this, 'render_view'] ); // Remove the menu item so it's hidden. remove_menu_page( $page ); } } } /** * Menu callback that loads right view depending on what the `page` query string says. */ public function render_view() { if ( strpos( papi_get_qs( 'page' ), 'papi' ) !== false ) { $page = str_replace( 'papi-', '', papi_get_qs( 'page' ) ); $res = preg_replace( '/\,.*/', '', $page ); if ( is_string( $res ) ) { $page_view = $res; } } if ( ! isset( $page_view ) ) { $page_view = null; } if ( ! is_null( $page_view ) ) { $view = new Papi_Admin_View; $view->render( $page_view ); } else { echo '

Papi - 404

'; } } /** * Setup actions. */ protected function setup_actions() { if ( papi_is_admin() ) { add_action( 'admin_init', [$this, 'admin_bar_menu'] ); add_action( 'admin_menu', [$this, 'page_items_menu'] ); add_action( 'admin_menu', [$this, 'post_types_menu'] ); } else { add_action( 'admin_bar_menu', [$this, 'admin_bar_menu'] ); } } } new Papi_Admin_Menu; ================================================ FILE: src/admin/class-papi-admin-meta-box-tabs.php ================================================ tabs = papi_tabs_setup( $tabs ); if ( $render ) { $this->html(); } } /** * Get the tabs that are registered. * * @return array */ public function get_tabs() { return $this->tabs; } /** * Generate html for tabs and properties. */ protected function html() { ?>
    tabs as $tab ): $css_classes = $this->tabs[0] === $tab ? 'active ' : ''; if ( empty( $tab->background ) ) { // Find out if the first property has a sidebar or not. If the first property // don't have a sidebar the tab background should be white since it looks better. $no_sidebar = empty( $tab->properties ) ? false : $tab->properties[0]->sidebar; $css_classes .= ! empty( $tab->properties ) && $no_sidebar ? '' : 'white-tab'; } else { $css_classes .= $tab->background === 'white' ? 'white-tab' : ''; } ?>
  • icon ) ): ?> <?php echo esc_attr( $tab->title ); ?> title ); ?>
tabs as $tab ): ?>
properties ); ?>
capabilities ) ) { return; } if ( $box->display ) { $this->box = $box; $this->setup_actions(); } } /** * Add custom css for hiding boxes with no frame in screen options. * * @return string */ public function admin_head() { if ( ! $this->box->frame ) { echo sprintf( '', esc_attr( $this->box->id ), esc_attr( $this->box->id ), esc_attr( $this->box->id ) ); } } /** * Add css classes to meta box. * * @param array $classes * * @return string[] */ public function meta_box_css_classes( array $classes ) { return array_merge( $classes, [ 'papi-box' ] ); } /** * Move meta boxes after title. */ public function move_meta_box_after_title() { global $post, $wp_meta_boxes; do_meta_boxes( get_current_screen(), $this->box->context, $post ); unset( $wp_meta_boxes[get_post_type( $post )][$this->box->context] ); } /** * Get meta post type. * * @return string */ protected function get_post_type() { if ( papi_get_meta_type() === 'post' ) { if ( $post_id = papi_get_post_id() ) { return get_post_type( $post_id ); } if ( $post_type = papi_get_post_type() ) { return $post_type; } } return $this->box->id; } /** * Get meta box title. * * @return string */ protected function get_title() { $title = $this->box->title; if ( $this->box->get_option( 'required' ) ) { $title .= papi_property_required_html( $this->box->properties[0], true ); } return $title; } /** * Render the meta box * * @param array $post * @param array $args */ public function render_meta_box( $post, array $args ) { if ( ! isset( $args['args'] ) ) { return; } // Do a last check before all properties is rendered. $args['args'] = array_filter( $args['args'], 'papi_is_property' ); // Inherit options from the box. foreach ( $args['args'] as $index => $property ) { if ( $property->layout === 'horizontal' ) { $args['args'][$index]->layout = $this->box->layout; } } // Render the properties. papi_render_properties( papi_sort_order( array_reverse( $args['args'] ) ) ); } /** * Setup action hooks. */ protected function setup_actions() { if ( post_type_exists( $this->get_post_type() ) && papi_get_meta_type() === 'post' ) { add_action( 'add_meta_boxes', [$this, 'setup_meta_box'] ); if ( $this->box->context === 'after_title' ) { add_action( 'edit_form_after_title', [$this, 'move_meta_box_after_title'] ); } } else { $this->setup_meta_box(); } // Will be called on when you call do_meta_boxes // even without a real post type. add_action( sprintf( 'postbox_classes_%s_%s', strtolower( $this->get_post_type() ), $this->box->id ), [$this, 'meta_box_css_classes'] ); add_action( 'admin_head', [$this, 'admin_head'] ); } /** * Setup meta box. */ public function setup_meta_box() { $properties = $this->box->properties; // Check all properties and remove them that can't be rendered. foreach ( $properties as $index => $property ) { if ( $property instanceof Papi_Property && ! $property->can_render() ) { unset( $properties[$index] ); } } // Bail if properties array is empty, // no need to render a empty meta box. if ( empty( $properties ) ) { return; } add_meta_box( $this->box->id, $this->get_title(), [$this, 'render_meta_box'], $this->get_post_type(), $this->box->context, $this->box->priority, $properties ); } } ================================================ FILE: src/admin/class-papi-admin-meta-handler.php ================================================ overwrite ) ) { return; } $wpdb->update( $wpdb->posts, $this->overwrite, [ 'ID' => $post_id ] ); // Delete cache since it can be cached even if not saved in the database. foreach ( array_keys( $this->overwrite ) as $key ) { papi_cache_delete( $key, $post_id ); } clean_post_cache( $post_id ); } /** * Pre save page template and page type. * * @param int $id */ protected function pre_save( $id ) { if ( empty( $id ) ) { return; } $data = $this->get_pre_data(); foreach ( $data as $key => $value ) { if ( empty( $value ) ) { continue; } if ( is_array( $value ) ) { list( $keys, $value ) = $this->get_pre_deep_keys_value( $value ); $key = sprintf( '%s_%s', $key, implode( '_', $keys ) ); } update_metadata( $this->get_meta_type(), $id, $key, $value ); } } /** * Save meta boxes. * * @param int $id * @param object  $post */ public function save_meta_boxes( $id, $post = null ) { // Check if there was a multisite switch before. if ( is_multisite() && ms_is_switched() ) { return; } // Can't proceed without a id. if ( empty( $id ) ) { return; } // Check if our nonce is vailed. if ( ! wp_verify_nonce( papi_get_sanitized_post( 'papi_meta_nonce' ), 'papi_save_data' ) ) { return; } $meta_type = $this->get_meta_type(); $post = is_array( $post ) ? (object) $post : $post; if ( $meta_type === 'post' && $post_type = get_post_type_object( $post->post_type ) ) { // Check so the id is a post id and not a autosave post. if ( ! $this->valid_post_id( $id ) ) { return; } // Check the `edit_posts` capability before we continue. if ( ! current_user_can( $post_type->cap->edit_posts ) ) { return; } // Delete all oEmbed caches. if ( class_exists( 'WP_Embed' ) ) { global $wp_embed; if ( $wp_embed instanceof WP_Embed ) { $wp_embed->delete_oembed_caches( $id ); } } } if ( $meta_type === 'term' && $taxonomy = get_taxonomy( papi_get_taxonomy() ) ) { // Check the `edit_terms` capability before we continue. if ( $taxonomy && ! current_user_can( $taxonomy->cap->edit_terms ) ) { return; } } $this->save_properties( $id ); } /** * Save custom fields for revision post. * * @param int $post_id */ public function save_revision( $revision_id ) { // Check if our nonce is vailed. if ( ! wp_verify_nonce( papi_get_sanitized_post( 'papi_meta_nonce' ), 'papi_save_data' ) ) { return; } // Fetch parent id from revision. if ( ! $parent_id = wp_is_post_revision( $revision_id ) ) { return; } // Bail if a entry type don't exists on parent post. if ( papi_is_empty( papi_get_entry_type_by_meta_id( $parent_id, 'post' ) ) ) { return; } $meta = get_post_meta( $parent_id ); foreach ( $meta as $key => $value ) { if ( $key[0] === '_' && $key !== papi_get_page_type_key() ) { continue; } papi_data_update( $revision_id, $key, array_shift( $value ) ); } } /** * Save properties. * * @param int $id */ public function save_properties( $id ) { // Pre save page template, page type and some others dynamic values. $this->pre_save( $id ); // Get properties data. $data = $this->get_post_data(); // Prepare properties data. $data = $this->prepare_properties_data( $data, $id ); // Get meta type. $meta_type = $this->get_meta_type(); // Overwrite post data if any. if ( $meta_type === 'post' ) { $this->overwrite_post_data( $id ); } // Save all properties value foreach ( $data as $key => $value ) { papi_data_update( $id, $key, $value, $this->get_meta_type() ); } /** * Fire `save_properties` action when all is done. * * @param int $id * @param string $meta_type */ do_action( 'papi/save_properties', $id, $meta_type ); } /** * Restore to post revision. * * @param int $post_id * @param int $revision_id */ public function restore_post_revision( $post_id, $revision_id ) { if ( papi_is_empty( papi_get_entry_type_by_meta_id( $post_id, 'post' ) ) ) { return; } $meta = get_post_meta( $revision_id ); foreach ( $meta as $key => $value ) { if ( $key[0] === '_' && $key !== papi_get_page_type_key() ) { continue; } papi_data_update( $post_id, $key, array_shift( $value ) ); } } /** * Setup actions. */ protected function setup_actions() { add_action( '_wp_put_post_revision', [$this, 'save_revision'] ); add_action( 'save_post', [$this, 'save_meta_boxes'], 1, 2 ); add_action( 'created_term', [$this, 'save_meta_boxes'], 1 ); add_action( 'edit_term', [$this, 'save_meta_boxes'], 1 ); add_action( 'wp_restore_post_revision', [$this, 'restore_post_revision'], 10, 2 ); } /** * Check if post id is valid or not. * * @param int $post_id * * @return bool */ protected function valid_post_id( $post_id ) { $key = papi_get_sanitized_post( 'action' ) === 'save-attachment-compat' ? 'id' : 'post_ID'; $val = papi_get_sanitized_post( $key ); // When autosave is in place the post id is located deeper in the post data array, the ids should not match. if ( isset( $_POST['data']['wp_autosave'], $_POST['data']['wp_autosave']['post_id'] ) ) { // But if it's a auto draft the ids should match. if ( isset( $_POST['data']['wp_autosave']['auto_draft'] ) && ! empty( $_POST['data']['wp_autosave']['auto_draft'] ) ) { return sanitize_text_field( $_POST['data']['wp_autosave']['post_id'] ) === strval( $post_id ); } return sanitize_text_field( $_POST['data']['wp_autosave']['post_id'] ) !== strval( $post_id ); } // Should not be the same id when `wp-preview` equals `dopreview`. if ( isset( $_POST['wp-preview'] ) && strtolower( $_POST['wp-preview'] ) === 'dopreview' ) { return $val !== strval( $post_id ); } return $val === strval( $post_id ); } } if ( papi_is_admin() ) { new Papi_Admin_Meta_Handler; } ================================================ FILE: src/admin/class-papi-admin-option-handler.php ================================================ get_post_data(); // Prepare properties data. $data = $this->prepare_properties_data( $data, 0 ); foreach ( $data as $key => $value ) { papi_data_update( 0, $key, $value, 'option' ); } /** * Fire `save_properties` action when all is done. * * @param int $id * @param string $meta_type */ do_action( 'papi/save_properties', 0, 'option' ); } /** * Setup actions. */ protected function setup_actions() { add_action( 'admin_init', [$this, 'save_properties'] ); } } if ( papi_is_admin() ) { new Papi_Admin_Option_Handler; } ================================================ FILE: src/admin/class-papi-admin-page-type-switcher.php ================================================ name, $b->name ); } ); $page_types = papi_sort_order( array_reverse( $page_types ) ); // Don't do anything without any page types. if ( empty( $page_type ) || empty( $page_types ) ) { return; } ?>
name ); ?> capabilities ) && $page_type->switcher ): ?>
post_type ) === $page_type_id ) { $page_type = papi_get_standard_page_type( $post->post_type ); } else { $page_type = papi_get_entry_type_by_id( $page_type_id ); } // Fetch right page type switch if standard page type id. if ( papi_get_standard_page_type_id( $post->post_type ) === $page_type_switch_id ) { $page_type_switch = papi_get_standard_page_type( $post->post_type ); $page_type_switch_id = ''; } else { $page_type_switch = papi_get_entry_type_by_id( $page_type_switch_id ); } $post_type_object = get_post_type_object( $post->post_type ); // Check if page type and post type is not empty. if ( empty( $page_type_switch ) || empty( $post_type_object ) ) { return false; } // Check if autosave. if ( wp_is_post_autosave( $post_id ) ) { return false; } // Check if revision. if ( wp_is_post_revision( $post_id ) ) { return false; } // Check if revision post type. if ( in_array( $post->post_type, ['revision', 'nav_menu_item'], true ) ) { return false; } // Check so page type has the post type. if ( ! $page_type->has_post_type( $post->post_type ) || ! $page_type_switch->has_post_type( $post->post_type ) ) { return false; } // Check page type capabilities. if ( ! papi_current_user_is_allowed( $page_type_switch->capabilities ) ) { return false; } // Check so user can edit posts and that the user can publish posts on the post type. if ( ! current_user_can( 'edit_post', $post_id ) || ! current_user_can( $post_type_object->cap->publish_posts ) ) { return false; } // Get properties. $properties = $page_type->get_properties(); $properties_switch = $page_type_switch->get_properties(); // Delete only properties that don't have the same type and slug. foreach ( $properties as $property ) { $delete = true; // Check if the properties are the same or not. foreach ( $properties_switch as $property_switch ) { if ( $property_switch->type === $property->type && $property_switch->match_slug( $property->get_slug() ) ) { $delete = false; break; } } if ( ! $delete ) { continue; } // Delete property values. $property->delete_value( $property->get_slug( true ), $post_id, papi_get_meta_type() ); } // Delete page type switch id. if ( empty( $page_type_switch_id ) ) { return delete_post_meta( $post_id, papi_get_page_type_key() ); } // Update page type id. return papi_set_page_type_id( $post_id, $page_type_switch_id ); } } if ( papi_is_admin() ) { new Papi_Admin_Page_Type_Switcher; } ================================================ FILE: src/admin/class-papi-admin-view.php ================================================ path = empty( $path ) ? PAPI_PLUGIN_DIR . '/admin/views/' : $path; } /** * Check if file exists. * * @param string $file * * @return bool */ public function exists( $file ) { return file_exists( $this->file( $file ) ); } /** * Render file. * * @param string $file * * @return string */ public function render( $file ) { if ( ! empty( $file ) && $this->exists( $file ) ) { require $this->file( $file ); } } /** * Get full path to file with php exstention. * * @param string $file * * @return string */ protected function file( $file ) { return $this->path . $file . '.php'; } } ================================================ FILE: src/admin/class-papi-admin.php ================================================ load_files(); $this->setup_actions(); $this->setup_filters(); } /** * Cloning is forbidden. * * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'papi' ), '3.0' ); } /** * Unserializing instances of this class is forbidden. * * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'papi' ), '3.0' ); } /** * Preboot all types and setup the current type if any. */ public function admin_init() { $meta_type = papi_get_meta_type(); $meta_type = ucfirst( $meta_type ); $class_name = 'Papi_Admin_Entry_' . $meta_type; // A custom class is not required, e.g // options don't have one. if ( class_exists( $class_name ) ) { $class = call_user_func( [$class_name, 'instance'] ); if ( ! $class->setup() ) { return; } } // Setup entry type. if ( $entry_type = $this->get_entry_type() ) { $entry_type->setup(); } } /** * Add custom body class when it's a page type. * * @param string $classes * * @return string */ public function admin_body_class( $classes ) { if ( $entry_type = $this->get_entry_type() ) { $classes .= sprintf( ' papi-body papi-meta-type-%s', papi_get_meta_type() ); // Add custom css classes from entry type. $arr = $entry_type->get_body_classes(); $arr = is_string( $arr ) ? [ $arr ] : $arr; $arr = is_array( $arr ) ? $arr : []; $classes .= ' ' . implode( ' ', $arr ); } // Add custom css classes from query string. if ( $css = papi_get_qs( 'papi_css' ) ) { $css = is_array( $css ) ? $css : []; $css = array_map( 'sanitize_text_field', $css ); $classes .= ' ' . implode( ' ', $css ); } return $classes; } /** * Output Papi page type hidden field. */ public function edit_form_after_title() { wp_nonce_field( 'papi_save_data', 'papi_meta_nonce' ); if ( $value = esc_attr( papi_get_entry_type_id() ) ) { papi_render_html_tag( 'input', [ 'data-papi-page-type-key' => true, 'name' => esc_attr( papi_get_page_type_key() ), 'type' => 'hidden', 'value' => $value ] ); } } /** * Get Entry Type instance. * * @return Papi_Entry_Type|false */ protected function get_entry_type() { if ( $this->entry_type instanceof Papi_Entry_Type ) { return $this->entry_type; } $entry_type_id = papi_get_entry_type_id(); // If the entry type id is empty try to load // the entry type id from `page` query string. // // Example: // /wp-admin/options-general.php?page=papi/option/site-option-type if ( empty( $entry_type_id ) ) { $entry_type_id = preg_replace( '/^papi\/\w+\//', '', papi_get_qs( 'page' ) ); } // Use the default entry type id if empty. if ( empty( $entry_type_id ) ) { $entry_type_id = papi_get_entry_type_id(); } // If no entry type id exists Papi can't setup a entry type. if ( empty( $entry_type_id ) ) { return false; } $entry_type = papi_get_entry_type_by_id( $entry_type_id ); if ( $entry_type instanceof Papi_Entry_Type === false ) { return false; } $this->entry_type = $entry_type; return $entry_type; } /** * Load admin files that are not loaded by the autoload. */ protected function load_files() { require_once __DIR__ . '/class-papi-admin-meta-handler.php'; require_once __DIR__ . '/class-papi-admin-option-handler.php'; require_once __DIR__ . '/class-papi-admin-entry-post.php'; require_once __DIR__ . '/class-papi-admin-entry-taxonomy.php'; require_once __DIR__ . '/class-papi-admin-columns.php'; require_once __DIR__ . '/class-papi-admin-page-type-switcher.php'; } /** * Add docs links to plugin row meta. * * @param array $links * @param string $file * * @return array */ public function plugin_row_meta( array $links, $file ) { if ( $file === PAPI_PLUGIN_BASENAME ) { return array_merge( $links, [ 'docs' => '' . __( 'Docs', 'papi' ) . '', ] ); } return $links; } /** * Setup actions. */ protected function setup_actions() { add_action( 'admin_init', [$this, 'admin_init'] ); add_action( 'edit_form_after_title', [$this, 'edit_form_after_title'] ); if ( $taxonomy = papi_get_taxonomy() ) { add_action( $taxonomy . '_add_form', [$this, 'edit_form_after_title'] ); add_action( $taxonomy . '_edit_form', [$this, 'edit_form_after_title'] ); } } /** * Setup filters. */ protected function setup_filters() { add_filter( 'admin_body_class', [$this, 'admin_body_class'] ); add_filter( 'plugin_row_meta', [$this, 'plugin_row_meta'], 10, 2 ); add_filter( 'wp_link_query', [$this, 'wp_link_query'] ); add_filter( 'wp_refresh_nonces', [$this, 'wp_refresh_nonces'], 11 ); add_filter( 'pre_update_option', [$this, 'update_front_page'], 10, 2 ); } /** * Update page type to front page type when updating * which page that should be used as front page. * * @param mixed $value * @param string $option * * @return mixed */ public function update_front_page( $value, $option ) { if ( $option !== 'page_on_front' ) { return $value; } $front_pages = papi_get_all_entry_types( [ 'types' => ['front-page'], ] ); if ( count( $front_pages ) === 0 ) { return $value; } $old_page_type_id = papi_get_page_type_id( $value ); $new_page_type_id = $front_pages[0]->get_id(); // Delete all old fields from old page type if any. if ( strtolower( $old_page_type_id ) !== strtolower( $new_page_type_id ) ) { if ( $page_type = papi_get_entry_type_by_id( $old_page_type_id ) ) { $slugs = array_map( function( $property ) { return $property->get_slug( true ); }, $page_type->get_properties() ); foreach ( $slugs as $slug ) { papi_delete_field( $value, $slug ); } } } papi_set_page_type_id( $value, $new_page_type_id ); return $value; } /** * Filter the link query results. * * @param array $results * * @return array */ public function wp_link_query( array $results ) { foreach ( $results as $index => $value ) { $post_type = papi_get_post_type( $value['ID'] ); $name = papi_get_page_type_name( $value['ID'] ); if ( empty( $name ) ) { $name = papi_filter_settings_standard_page_type_name( $post_type ); } $results[$index]['info'] = esc_html( $name ); } return $results; } /** * Check nonce expiration on the New/Edit Post screen and refresh if needed. * * @param array $response * * @return array */ public function wp_refresh_nonces( array $response ) { if ( ! array_key_exists( 'wp-refresh-post-nonces', $response ) ) { return $response; } $response['wp-refresh-post-nonces']['replace']['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); return $response; } } if ( papi_is_admin() ) { new Papi_Admin; } ================================================ FILE: src/admin/views/add-new-page.php ================================================

labels->singular_name ) ); ?>

get_child_types(); $page_types = empty( $child_types ) ? $page_types : $child_types; if ( ! $show_standard ) { $show_standard = $parent_page_type->standard_type; } } if ( $show_standard ) { $page_types[] = papi_get_standard_page_type( $post_type_name ); } usort( $page_types, function ( $a, $b ) { return strcmp( $a->name, $b->name ); } ); $page_types = papi_sort_order( array_reverse( $page_types ) ); $use_thumbnail = false; foreach ( $page_types as $key => $page_type ) { if ( ! empty( $page_type->get_thumbnail() ) ) { $use_thumbnail = true; } } foreach ( $page_types as $key => $page_type ) { if ( ! papi_display_page_type( $page_type ) ) { continue; } papi_include_template( 'admin/views/partials/add-new-item.php', [ 'title' => $page_type->name, 'description' => $page_type->description, 'thumbnail' => $page_type->get_thumbnail(), 'url' => papi_get_page_new_url( $page_type->get_id(), true, null ), 'use_thumbnail' => $use_thumbnail ] ); } ?>
================================================ FILE: src/admin/views/partials/add-new-item.php ================================================

================================================ FILE: src/assets/js/components/pikaday.js ================================================ import moment from 'moment'; /*! * Pikaday * * Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday */ /** * feature detection and helper functions */ var hasMoment = typeof moment === 'function', hasEventListeners = !!window.addEventListener, document = window.document, sto = window.setTimeout, addEvent = function(el, e, callback, capture) { if (hasEventListeners) { el.addEventListener(e, callback, !!capture); } else { el.attachEvent('on' + e, callback); } }, removeEvent = function(el, e, callback, capture) { if (hasEventListeners) { el.removeEventListener(e, callback, !!capture); } else { el.detachEvent('on' + e, callback); } }, fireEvent = function(el, eventName, data) { var ev; if (document.createEvent) { ev = document.createEvent('HTMLEvents'); ev.initEvent(eventName, true, false); ev = extend(ev, data); el.dispatchEvent(ev); } else if (document.createEventObject) { ev = document.createEventObject(); ev = extend(ev, data); el.fireEvent('on' + eventName, ev); } }, trim = function(str) { return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); }, hasClass = function(el, cn) { return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1; }, addClass = function(el, cn) { if (!hasClass(el, cn)) { el.className = el.className === '' ? cn : el.className + ' ' + cn; } }, removeClass = function(el, cn) { el.className = trim( (' ' + el.className + ' ').replace(' ' + cn + ' ', ' ') ); }, isArray = function(obj) { return /Array/.test(Object.prototype.toString.call(obj)); }, isDate = function(obj) { return ( /Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime()) ); }, isWeekend = function(date) { var day = date.getDay(); return day === 0 || day === 6; }, isLeapYear = function(year) { // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; }, getDaysInMonth = function(year, month) { return [ 31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ][month]; }, setToStartOfDay = function(date) { if (isDate(date)) date.setHours(0, 0, 0, 0); }, compareDates = function(a, b) { // Copy so we don't change the dates being passed in var _a = new Date(a.getTime()); var _b = new Date(b.getTime()); setToStartOfDay(_a); setToStartOfDay(_b); return _a.getTime() === _b.getTime(); }, extend = function(to, from, overwrite) { var prop, hasProp; for (prop in from) { hasProp = to[prop] !== undefined; if ( hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined ) { if (isDate(from[prop])) { if (overwrite) { to[prop] = new Date(from[prop].getTime()); } } else if (isArray(from[prop])) { if (overwrite) { to[prop] = from[prop].slice(0); } } else { to[prop] = extend({}, from[prop], overwrite); } } else if (overwrite || !hasProp) { to[prop] = from[prop]; } } return to; }, adjustCalendar = function(calendar) { if (calendar.month < 0) { calendar.year -= Math.ceil(Math.abs(calendar.month) / 12); calendar.month += 12; } if (calendar.month > 11) { calendar.year += Math.floor(Math.abs(calendar.month) / 12); calendar.month -= 12; } return calendar; }, /** * defaults and localisation */ defaults = { // bind the picker to a form field field: null, // automatically show/hide the picker on `field` focus (default `true` if `field` is set) bound: undefined, // position of the datepicker, relative to the field (default to bottom & left) // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position) position: 'bottom left', // automatically fit in the viewport even if it means repositioning from the position option reposition: true, // the default output format for `.toString()` and `field` value // set in `config` based on if showTime is set format: null, // an array giving the allowable input format(s). As with moment, // the input formats may be either a single string or an array of strings. // Usually set in `config` inputFormats: null, // the initial date to view when first opened defaultDate: null, // make the `defaultDate` the initial selected value setDefaultDate: false, // first day of week (0: Sunday, 1: Monday etc) firstDay: 0, // the minimum/earliest date that can be selected minDate: null, // the maximum/latest date that can be selected maxDate: null, // number of years either side, or array of upper/lower range yearRange: 10, // show week numbers at head of row showWeekNumber: false, // used internally (don't config outside) minYear: 0, maxYear: 9999, minMonth: undefined, maxMonth: undefined, isRTL: false, // Additional text to append to the year in the calendar title yearSuffix: '', // Render the month after year in the calendar title showMonthAfterYear: false, // how many months are visible numberOfMonths: 1, // time showTime: true, showTimeFirst: false, showSeconds: false, use24hour: false, // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`) // only used for the first display or when a selected date is not visible mainCalendar: 'left', // Specify a DOM element to render the calendar in container: undefined, // internationalization i18n: { previousMonth: 'Previous Month', nextMonth: 'Next Month', months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], weekdays: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], midnight: 'Midnight', noon: 'Noon' }, // Theme Classname theme: null, // callback function onSelect: null, onOpen: null, onClose: null, onDraw: null }, /** * templating functions to abstract HTML rendering */ renderDayName = function(opts, day, abbr) { day += opts.firstDay; while (day >= 7) { day -= 7; } return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day]; }, renderDay = function(d, m, y, isSelected, isToday, isDisabled, isEmpty) { if (isEmpty) { return ''; } var arr = []; if (isDisabled) { arr.push('is-disabled'); } if (isToday) { arr.push('is-today'); } if (isSelected) { arr.push('is-selected'); } return ( '' + '' + '' ); }, renderWeek = function(d, m, y) { // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified. var onejan = new Date(y, 0, 1), weekNum = Math.ceil( ((new Date(y, m, d) - onejan) / 86400000 + onejan.getDay() + 1) / 7 ); return '' + weekNum + ''; }, renderRow = function(days, isRTL) { return '' + (isRTL ? days.reverse() : days).join('') + ''; }, renderBody = function(rows) { return '' + rows.join('') + ''; }, renderHead = function(opts) { var i, arr = []; if (opts.showWeekNumber) { arr.push(''); } for (i = 0; i < 7; i++) { arr.push( '' + renderDayName(opts, i, true) + '' ); } return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ''; }, renderTitle = function(instance, c, year, month, refYear) { var i, j, arr, opts = instance._o, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear, html = '
', monthHtml, yearHtml, prev = true, next = true; for (arr = [], i = 0; i < 12; i++) { arr.push( '' ); } monthHtml = '
' + opts.i18n.months[month] + '
'; if (isArray(opts.yearRange)) { i = opts.yearRange[0]; j = opts.yearRange[1] + 1; } else { i = year - opts.yearRange; j = 1 + year + opts.yearRange; } for (arr = []; i < j && i <= opts.maxYear; i++) { if (i >= opts.minYear) { arr.push( '' ); } } yearHtml = '
' + year + opts.yearSuffix + '
'; if (opts.showMonthAfterYear) { html += yearHtml + monthHtml; } else { html += monthHtml + yearHtml; } if (isMinYear && (month === 0 || opts.minMonth >= month)) { prev = false; } if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { next = false; } if (c === 0) { html += ''; } if (c === instance._o.numberOfMonths - 1) { html += ''; } return (html += '
'); }, renderTable = function(opts, data) { return ( '' + renderHead(opts) + renderBody(data) + '
' ); }, renderTimePicker = function( num_options, selected_val, select_class, display_func ) { var to_return = ''; return to_return; }, renderTime = function(hh, mm, ss, opts) { var to_return = '' + renderTimePicker(24, hh, 'pika-select-hour', function(i) { if (opts.use24hour) { return i; } else { var to_return = (i % 12) + (i < 12 ? ' AM' : ' PM'); if (to_return == '0 AM') { return opts.i18n.midnight; } else if (to_return == '0 PM') { return opts.i18n.noon; } else { return to_return; } } }) + '' + renderTimePicker(60, mm, 'pika-select-minute', function(i) { if (i < 10) return '0' + i; return i; }); if (opts.showSeconds) { to_return += '' + renderTimePicker(60, ss, 'pika-select-second', function(i) { if (i < 10) return '0' + i; return i; }); } return to_return + '
::
'; }, /** * Pikaday constructor */ Pikaday = function(options) { var self = this, opts = self.config(options); self._onMouseDown = function(e) { if (!self._v) { return; } e = e || window.event; var target = e.target || e.srcElement; if (!target) { return; } // Do not preventDefaul when using time picker if ( !hasClass(target, 'pika-select-hour') && !hasClass(target, 'pika-select-minute') && !hasClass(target, 'pika-select-second') ) { e.preventDefault(); } if (!hasClass(target, 'is-disabled')) { if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) { var newDate = new Date( target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day') ); // Preserve time selection when date changed if (self._d && opts.showTime) { newDate.setHours(self._d.getHours()); newDate.setMinutes(self._d.getMinutes()); } self.setDate(newDate); if (opts.bound) { sto(function() { self.hide(); if (opts.field) { opts.field.blur(); } }, 100); } return; } else if (hasClass(target, 'pika-prev')) { self.prevMonth(); } else if (hasClass(target, 'pika-next')) { self.nextMonth(); } } if (!hasClass(target, 'pika-select')) { if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; return false; } } else { self._c = true; } }; self._onChange = function(e) { e = e || window.event; var target = e.target || e.srcElement; if (!target) { return; } if (hasClass(target, 'pika-select-month')) { self.gotoMonth(target.value); } else if (hasClass(target, 'pika-select-year')) { self.gotoYear(target.value); } else if (hasClass(target, 'pika-select-hour')) { self.setTime(target.value); } else if (hasClass(target, 'pika-select-minute')) { self.setTime(null, target.value); } else if (hasClass(target, 'pika-select-second')) { self.setTime(null, null, target.value); } }; self._onInputChange = function(e) { var date; if (e.firedBy === self) { return; } if (hasMoment) { date = moment(opts.field.value, opts.inputFormats); date = date && date.isValid() ? date.toDate() : null; } else { date = new Date(Date.parse(opts.field.value)); } self.setDate(isDate(date) ? date : null); if (!self._v) { self.show(); } }; self._onInputFocus = function() { self.show(); }; self._onInputClick = function() { self.show(); }; self._onInputBlur = function() { // IE allows pika div to gain focus; catch blur the input field var pEl = document.activeElement; do { if (hasClass(pEl, 'pika-single')) { return; } } while ((pEl = pEl.parentNode)); if (!self._c) { self._b = sto(function() { self.hide(); }, 50); } self._c = false; }; self._onClick = function(e) { e = e || window.event; var target = e.target || e.srcElement, pEl = target; if (!target) { return; } if (!hasEventListeners && hasClass(target, 'pika-select')) { if (!target.onchange) { target.setAttribute('onchange', 'return;'); addEvent(target, 'change', self._onChange); } } do { if ( hasClass(pEl, 'pika-single') || pEl === opts.trigger || (opts.showTime && hasClass(pEl, 'pika-time-container')) ) { return; } } while ((pEl = pEl.parentNode)); if (self._v && target !== opts.trigger && pEl !== opts.trigger) { self.hide(); } }; self.el = document.createElement('div'); self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : ''); addEvent( self.el, 'ontouchend' in document ? 'ontouchend' : 'mousedown', self._onMouseDown, true ); addEvent(self.el, 'change', self._onChange); if (opts.field) { if (opts.container) { opts.container.appendChild(self.el); } else if (opts.bound) { document.body.appendChild(self.el); } else { opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling); } addEvent(opts.field, 'change', self._onInputChange); if (!opts.defaultDate) { if (hasMoment && opts.field.value) { opts.defaultDate = moment( opts.field.value, opts.inputFormats ).toDate(); } else { opts.defaultDate = new Date(Date.parse(opts.field.value)); } opts.setDefaultDate = true; } } var defDate = opts.defaultDate; if (isDate(defDate)) { if (opts.setDefaultDate) { self.setDate(defDate, true); } else { self.gotoDate(defDate); } } else { self.gotoDate(new Date()); } if (opts.bound) { this.hide(); self.el.className += ' is-bound'; addEvent(opts.trigger, 'click', self._onInputClick); addEvent(opts.trigger, 'focus', self._onInputFocus); addEvent(opts.trigger, 'blur', self._onInputBlur); } else { this.show(); } }; /** * public Pikaday API */ Pikaday.prototype = { /** * configure functionality */ config: function(options) { if (!this._o) { this._o = extend({}, defaults, true); } var opts = extend(this._o, options, true); opts.isRTL = !!opts.isRTL; opts.field = opts.field && opts.field.nodeName ? opts.field : null; opts.theme = typeof opts.theme == 'string' && opts.theme ? opts.theme : null; opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field); opts.trigger = opts.trigger && opts.trigger.nodeName ? opts.trigger : opts.field; opts.disableWeekends = !!opts.disableWeekends; opts.disableDayFn = typeof opts.disableDayFn == 'function' ? opts.disableDayFn : null; var nom = parseInt(opts.numberOfMonths, 10) || 1; opts.numberOfMonths = nom > 4 ? 4 : nom; if (!isDate(opts.minDate)) { opts.minDate = false; } if (!isDate(opts.maxDate)) { opts.maxDate = false; } if (opts.minDate && opts.maxDate && opts.maxDate < opts.minDate) { opts.maxDate = opts.minDate = false; } if (opts.minDate) { this.setMinDate(opts.minDate); } if (opts.maxDate) { if (!opts.showTime) setToStartOfDay(opts.maxDate); opts.maxYear = opts.maxDate.getFullYear(); opts.maxMonth = opts.maxDate.getMonth(); } if (isArray(opts.yearRange)) { var fallback = new Date().getFullYear() - 10; opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback; opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback; } else { opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange; if (opts.yearRange > 100) { opts.yearRange = 100; } } // If no format is given, set based on showTime if (opts.format === null) { opts.format = 'YYYY-MM-DD'; if (opts.showTime) { opts.format += ' HH:mm:ss'; } } if (!opts.inputFormats) { opts.inputFormats = opts.format; } return opts; }, /** * return a formatted string of the current selection (using Moment.js if available) */ toString: function(format) { return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._o.showTime ? this._d.toString() : this._d.toDateString(); }, /** * return a Moment.js object of the current selection (if available) */ getMoment: function() { return hasMoment ? moment(this._d) : null; }, /** * set the current selection from a Moment.js object (if available) */ setMoment: function(date, preventOnSelect) { if (hasMoment && moment.isMoment(date)) { this.setDate(date.toDate(), preventOnSelect); } }, /** * return a Date object of the current selection */ getDate: function() { return isDate(this._d) ? new Date(this._d.getTime()) : null; }, /** * set time components * Currently defaulting to setting date to today if not set */ setTime: function(hours, minutes, seconds) { if (!this._d) { this._d = new Date(); this._d.setHours(0, 0, 0, 0); } if (hours) { this._d.setHours(hours); } if (minutes) { this._d.setMinutes(minutes); } if (seconds) { this._d.setSeconds(seconds); } this.setDate(this._d); }, /** * set the current selection */ setDate: function(date, preventOnSelect) { if (!date) { this._d = null; if (this._o.field) { this._o.field.value = ''; fireEvent(this._o.field, 'change', { firedBy: this }); } return this.draw(); } if (typeof date === 'string') { date = new Date(Date.parse(date)); } if (!isDate(date)) { return; } var min = this._o.minDate, max = this._o.maxDate; if (isDate(min) && date < min) { date = min; } else if (isDate(max) && date > max) { date = max; } this._d = new Date(date.getTime()); if (this._o.showTime && !this._o.showSeconds) { this._d.setSeconds(0); } else if (!this._o.showTime) { setToStartOfDay(this._d); } this.gotoDate(this._d); if (this._o.field) { this._o.field.value = this.toString(); fireEvent(this._o.field, 'change', { firedBy: this }); } if (!preventOnSelect && typeof this._o.onSelect === 'function') { this._o.onSelect.call(this, this.getDate()); } }, /** * change view to a specific date */ gotoDate: function(date) { var newCalendar = true; if (!isDate(date)) { return; } if (this.calendars) { var firstVisibleDate = new Date( this.calendars[0].year, this.calendars[0].month, 1 ), lastVisibleDate = new Date( this.calendars[this.calendars.length - 1].year, this.calendars[this.calendars.length - 1].month, 1 ), visibleDate = date.getTime(); // get the end of the month lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1); lastVisibleDate.setDate(lastVisibleDate.getDate() - 1); newCalendar = visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate; } if (newCalendar) { this.calendars = [ { month: date.getMonth(), year: date.getFullYear(), hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds() } ]; if (this._o.mainCalendar === 'right') { this.calendars[0].month += 1 - this._o.numberOfMonths; } } this.adjustCalendars(); }, adjustCalendars: function() { this.calendars[0] = adjustCalendar(this.calendars[0]); for (var c = 1; c < this._o.numberOfMonths; c++) { this.calendars[c] = adjustCalendar({ month: this.calendars[0].month + c, year: this.calendars[0].year }); } this.draw(); }, gotoToday: function() { this.gotoDate(new Date()); }, /** * change view to a specific month (zero-index, e.g. 0: January) */ gotoMonth: function(month) { if (!isNaN(month)) { this.calendars[0].month = parseInt(month, 10); this.adjustCalendars(); } }, nextMonth: function() { this.calendars[0].month++; this.adjustCalendars(); }, prevMonth: function() { this.calendars[0].month--; this.adjustCalendars(); }, /** * change view to a specific full year (e.g. "2012") */ gotoYear: function(year) { if (!isNaN(year)) { this.calendars[0].year = parseInt(year, 10); this.adjustCalendars(); } }, /** * change the minDate */ setMinDate: function(value) { if (!this._o.showTime) setToStartOfDay(this._o.minDate); setToStartOfDay(value); this._o.minDate = value; this._o.minYear = value.getFullYear(); this._o.minMonth = value.getMonth(); }, /** * change the maxDate */ setMaxDate: function(value) { this._o.maxDate = value; }, /** * refresh the HTML */ draw: function(force) { if (!this._v && !force) { return; } var opts = this._o, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth, html = ''; if (this._y <= minYear) { this._y = minYear; if (!isNaN(minMonth) && this._m < minMonth) { this._m = minMonth; } } if (this._y >= maxYear) { this._y = maxYear; if (!isNaN(maxMonth) && this._m > maxMonth) { this._m = maxMonth; } } var timeHtml = ''; if (opts.showTime) { timeHtml = '
' + renderTime( this._d ? this._d.getHours() : 0, this._d ? this._d.getMinutes() : 0, this._d ? this._d.getSeconds() : 0, opts ) + '
'; } for (var c = 0; c < opts.numberOfMonths; c++) { html += '
' + renderTitle( this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year ) + (opts.showTime && opts.showTimeFirst ? timeHtml : '') + this.render(this.calendars[c].year, this.calendars[c].month) + '
'; } if (opts.showTime && !opts.showTimeFirst) { html += timeHtml; } this.el.innerHTML = html; if (opts.bound) { if (opts.field.type !== 'hidden') { sto(function() { opts.trigger.focus(); }, 1); } } if (typeof this._o.onDraw === 'function') { var self = this; sto(function() { self._o.onDraw.call(self); }, 0); } }, adjustPosition: function() { if (this._o.container) return; var field = this._o.trigger, pEl = field, width = this.el.offsetWidth, height = this.el.offsetHeight, viewportWidth = window.innerWidth || document.documentElement.clientWidth, viewportHeight = window.innerHeight || document.documentElement.clientHeight, scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop, left, top, clientRect; if (typeof field.getBoundingClientRect === 'function') { clientRect = field.getBoundingClientRect(); left = clientRect.left + window.pageXOffset; top = clientRect.bottom + window.pageYOffset; } else { left = pEl.offsetLeft; top = pEl.offsetTop + pEl.offsetHeight; while ((pEl = pEl.offsetParent)) { left += pEl.offsetLeft; top += pEl.offsetTop; } } // default position is bottom & left if ( (this._o.reposition && left + width > viewportWidth) || (this._o.position.indexOf('right') > -1 && left - width + field.offsetWidth > 0) ) { left = left - width + field.offsetWidth; } if ( (this._o.reposition && top + height > viewportHeight + scrollTop) || (this._o.position.indexOf('top') > -1 && top - height - field.offsetHeight > 0) ) { top = top - height - field.offsetHeight; } this.el.style.cssText = [ 'position: absolute', 'left: ' + left + 'px', 'top: ' + top + 'px' ].join(';'); }, /** * render HTML for a particular month */ render: function(year, month) { var opts = this._o, now = new Date(), days = getDaysInMonth(year, month), before = new Date(year, month, 1).getDay(), data = [], row = []; if (!opts.showTime) setToStartOfDay(now); if (opts.firstDay > 0) { before -= opts.firstDay; if (before < 0) { before += 7; } } var cells = days + before, after = cells; while (after > 7) { after -= 7; } cells += 7 - after; // Ensure we only compare date portion when deciding to show a date in picker var minDate_date = opts.minDate ? new Date( opts.minDate.getFullYear(), opts.minDate.getMonth(), opts.minDate.getDate() ) : null; var maxDate_date = opts.maxDate ? new Date( opts.maxDate.getFullYear(), opts.maxDate.getMonth(), opts.maxDate.getDate() ) : null; for (var i = 0, r = 0; i < cells; i++) { var day = new Date(year, month, 1 + (i - before)), isSelected = isDate(this._d) ? compareDates(day, this._d) : false, isToday = compareDates(day, now), isEmpty = i < before || i >= days + before, isDisabled = (minDate_date && day < minDate_date) || (maxDate_date && day > maxDate_date) || (opts.disableWeekends && isWeekend(day)) || (opts.disableDayFn && opts.disableDayFn(day)); row.push( renderDay( 1 + (i - before), month, year, isSelected, isToday, isDisabled, isEmpty ) ); if (++r === 7) { if (opts.showWeekNumber) { row.unshift(renderWeek(i - before, month, year)); } data.push(renderRow(row, opts.isRTL)); row = []; r = 0; } } return renderTable(opts, data); }, isVisible: function() { return this._v; }, show: function() { if (!this._v) { removeClass(this.el, 'is-hidden'); this._v = true; this.draw(); if (this._o.bound) { addEvent(document, 'click', this._onClick); this.adjustPosition(); } if (typeof this._o.onOpen === 'function') { this._o.onOpen.call(this); } } }, hide: function() { var v = this._v; if (v !== false) { if (this._o.bound) { removeEvent(document, 'click', this._onClick); } this.el.style.cssText = ''; addClass(this.el, 'is-hidden'); this._v = false; if (v !== undefined && typeof this._o.onClose === 'function') { this._o.onClose.call(this); } } }, /** * GAME OVER */ destroy: function() { this.hide(); removeEvent(this.el, 'mousedown', this._onMouseDown, true); removeEvent(this.el, 'change', this._onChange); if (this._o.field) { removeEvent(this._o.field, 'change', this._onInputChange); if (this._o.bound) { removeEvent(this._o.trigger, 'click', this._onInputClick); removeEvent(this._o.trigger, 'focus', this._onInputFocus); removeEvent(this._o.trigger, 'blur', this._onInputBlur); } } if (this.el.parentNode) { this.el.parentNode.removeChild(this.el); } } }; export default Pikaday; ================================================ FILE: src/assets/js/components/select2.js ================================================ import $ from 'jquery'; export default function (selector) { return { templateSelection: function (result) { // placeholder. if (result.id === '') { result.element = $(selector).find('[data-placeholder]'); } let htmlText = '
' + result.text + '
'; const editUrl = $(result.element).data('edit-url'); if (editUrl) { const editText = papiL10n.edit; const editHtml = '' + editText + ''; htmlText = htmlText.replace('', editHtml); } const newUrl = $(result.element).data('new-url'); if (newUrl) { const newText = papiL10n.new; const newHtml = '' + newText + ''; htmlText = htmlText.replace('', newHtml); } if (typeof htmlText !== 'undefined') { const $html = $(htmlText); $html.find('a').on('mousedown', function(e) { e.stopPropagation(); }).on('click', function(e) { e.preventDefault(); }); return $html; } return result.text; } } }; ================================================ FILE: src/assets/js/core.js ================================================ import $ from 'jquery'; import select2Options from 'components/select2'; class Core { /** * Initialize Papi core class. */ static init () { const core = new Core(); core.addCurrentClassToMenuItem(); core.binds(); core.pageTypeSwitcher(); core.prepareBoxes(); core.setSelectedMenuItem(); } /** * Autosave fields on heartbeat. * * @param {object} e * @param {object} xhr * @param {object} options */ autosave (e, xhr, options) { const reg = /action=(.+?)&/; const val = reg.exec(options.data); if (val !== null && val.length && val[1] === 'heartbeat') { const formdata = $('form#post').serializeArray(); $.each(formdata, function (index, field) { if (field.name.substring(0, 5) === 'papi_' || field.name.substring(0, 5) === '_papi') { // Fetch editor id if any. const editorID = $('[name="' + field.name + '"]').attr('id'); // Test if the editor id is a editor. if (typeof window.tinymce !== 'undefined' && window.tinymce.get(editorID)) { const editor = window.tinymce.get(editorID); // Save the editor content. if (editor && editor.isDirty() && !editor.isHidden()) { editor.save(); } // Modify field content with real editor content. field.value = $('#' + editorID).val(); } options.data += '&' + field.name + '=' + field.value; } }); } } /** * Bind elements with functions. */ binds () { $('.papi-box-list > li > p').on('click', this.redirect); $('input[name="add-new-page-search"]').on('keyup', this.search); $('[data-papi-href]').on('click touchstart', this.redirect); if ('select2' in $.fn) { $('.inside .papi-table tr .papi-component-select2').each(function (i, elm) { $(elm).select2(select2Options(elm)); }); // Fix issue with browsers where selected attribute is not removed correct. $(document.body).on('change', 'select.papi-component-select2:not([multiple])', function () { $(this).find('option[selected]').removeAttr('selected'); }); } $('.papi-meta-type-term button.handlediv').on('click', this.handlediv); // Autosave fields on heartbeat. $(document).ajaxSend(this.autosave); } /** * Add current class to menu item. */ addCurrentClassToMenuItem () { let $submenu = $('.wp-has-current-submenu .wp-submenu'); let $menuitem = $submenu.find('a[href*="papi-add-new-page"]').parent(); if (!$menuitem.hasClass('current') && !$submenu.find('li.current').length) { $menuitem.addClass('current'); } } /** * Handle expanded postbox div. * * @param {object} e */ handlediv (e) { e.preventDefault(); const $this = $(this); const $parent = $this.parent(); const $inside = $parent.find('.inside'); $parent.parent().toggleClass('closed'); $inside.toggleClass('papi-hide'); $this.attr('aria-expanded', !$inside.hasClass('papi-hide')); } /** * Page type switcher. */ pageTypeSwitcher () { $('.misc-pub-section.curtime.misc-pub-section-last').removeClass('misc-pub-section-last'); $('#papi-page-type-switcher-edit').on('click', function (e) { e.preventDefault(); $(this).hide(); $('.papi-page-type-switcher > div').slideDown(); }); $('#papi-page-type-switcher-save').on('click', function (e) { e.preventDefault(); $('.papi-page-type-switcher > div').slideUp(); $('#papi-page-type-switcher-edit').show(); $('.papi-page-type-switcher > span').text($('.papi-page-type-switcher select :selected').text()); }); $('#papi-page-type-switcher-cancel').on('click', function (e) { e.preventDefault(); $('.papi-page-type-switcher > div').slideUp(); $('#papi-page-type-switcher-edit').show(); }); } /** * Redirect to location from `papi-href` data attribute * or closest tag with href attribute. * * @param {object} e */ redirect (e) { e.preventDefault(); let $this = $(this); let papiHref = $this.data().papiHref; if (papiHref !== undefined) { window.location = papiHref; } else { window.location = $(this).closest('[href]').attr('href'); } } /** * Search in page types box list. * * @param {object} e */ search (e) { e.preventDefault(); let $this = $(this); let $list = $('.papi-box-list'); let val = $this.val(); // Destroy masonry before searching the list. $('.papi-box-list').masonry('destroy'); $list.find('.papi-box-item').each(function () { let $item = $(this); if ($item.text().toLowerCase().indexOf(val) === -1) { $item.addClass('papi-hide'); } else { $item.removeClass('papi-hide'); } }); // Enable masonry after searching the list. $('.papi-box-list').masonry({ itemSelector: '.papi-box-item:not(.papi-hide)', isResizable: true }); } /** * Prepare boxes with equal height. */ prepareBoxes () { let $boxItems = $('.papi-box-item'); let thumbnails = $boxItems.find('.papi-page-type-screenshot').length; let boxMaxHeight = 0; if (!thumbnails) { $boxItems = $('.papi-page-type-info'); } $boxItems.each(function () { let $this = $(this); if (thumbnails) { $this.find('.papi-post-type-info').removeAttr('style'); } else { $this.removeAttr('style'); } let height = $this.height(); boxMaxHeight = height > boxMaxHeight ? height : boxMaxHeight; }); $boxItems.each(function () { let $this = $(this); let height = boxMaxHeight; if (thumbnails) { let $thumb = $this.find('.papi-page-type-screenshot'); if ($thumb.length) { height = height - $thumb.height(); } else { height += 5; } $this.find('.papi-page-type-info').height(height); } else { $this.height(height); } }); // Enable masonry after setting equal height. $('.papi-box-list').masonry({ itemSelector: '.papi-box-item:not(.papi-hide)', isResizable: true }); } /** * Set selected menu item if it isn't selected. */ setSelectedMenuItem () { let href = typeof window.location === 'string' ? window.location : window.location.href; let $adminmenu = $('#adminmenu'); if (!$adminmenu.find('li.current > a.current').length) { href = href.substr(href.lastIndexOf('/') + 1); href = href.replace(/%2F/g, '/'); $('a[href="' + href + '"]', $adminmenu).addClass('current').parent().addClass('current'); } } } export default Core; ================================================ FILE: src/assets/js/modals/iframe.js ================================================ import $ from 'jquery'; /** * Iframe modal. */ class Iframe { /** * The iframe template to use. * * @return {function} */ get template() { const template = [ ''; } /** * Get default settings. * * @return array */ public function get_default_settings() { return [ 'allow_html' => false, 'items' => [], ]; } /** * Render property html. */ public function html() { $value = $this->get_value(); $data = $this->get_setting( 'items' ); if ( ! is_array( $data ) ) { return; } // Convert key/value array to [key, value] value. foreach ( $data as $key => $value ) { if ( is_array( $value ) ) { continue; } $data[$key] = [$key, $value]; } echo $this->build_table( $data ); // wpcs: xss ok } } ================================================ FILE: src/properties/class-papi-property-term.php ================================================ get_setting( 'meta_key' ); if ( is_string( $value ) ) { $value = trim( $value ); } if ( papi_is_empty( $value ) ) { return $this->default_value; } if ( empty( $meta_key ) ) { if ( is_numeric( $value ) && intval( $value ) !== 0 ) { $term_id = $value; } } else { $args = [ 'fields' => 'ids', 'meta_key' => $meta_key, 'meta_value' => $value, 'hide_empty' => false, 'taxonomy' => $this->get_setting( 'taxonomy' ), 'number' => 1 ]; $terms = get_terms( $args ); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { $term_id = $terms[0]; } } // Allow only id to be returned. if ( ! papi_is_admin() && $this->get_setting( 'fields' ) === 'ids' ) { $term = $this->get_term_value( $term_id ); } elseif ( ! empty( $term_id ) ) { $term = get_term( $term_id ); } if ( empty( $term ) || is_wp_error( $term ) ) { $term = $this->default_value; } return $term; } /** * Get default settings. * * @return array */ public function get_default_settings() { return [ 'allow_clear' => true, 'fields' => '', 'labels' => [ 'select_taxonomy' => __( 'Select Taxonomy', 'papi' ), 'select_item' => __( 'Select %s term', 'papi' ) ], 'layout' => 'single', // Single or advanced 'meta_key' => '', 'placeholder' => null, 'taxonomy' => '', 'select2' => true, 'query' => [] ]; } /** * Get labels from taxonomies. * * @return array */ protected function get_labels() { $results = []; foreach ( $this->get_taxonomies() as $taxonomy ) { if ( taxonomy_exists( $taxonomy ) ) { $taxonomy_object = get_taxonomy( $taxonomy ); $results[$taxonomy] = $taxonomy_object->labels->name; } } return $results; } /** * Get taxonomies. * * @return array */ protected function get_taxonomies() { return papi_to_array( $this->get_setting( 'taxonomy' ) ); } /** * Get terms for specified taxonomy. * * @param string $taxonomy * * @return array */ protected function get_terms( $taxonomy ) { // Prepare arguments for get_terms. $query = $this->get_setting( 'query' ); $args = array_merge( [ 'fields' => 'id=>name' ], $query ); $terms = []; if ( taxonomy_exists( $taxonomy ) ) { $terms = get_terms( $taxonomy, $args ); } return $terms; } /** * Get matching value based on key from a term. * * @param mixed $term * * @return mixed */ protected function get_term_value( $term ) { $meta_key = $this->get_setting( 'meta_key' ); if ( is_numeric( $term ) ) { $term_id = $term; } else { $term = get_term( $term ); if ( $term instanceof WP_Term === false ) { return 0; } $term_id = $term->term_id; } if ( ! empty( $meta_key ) ) { $value = get_term_meta( $term_id, $meta_key, true ); } else { $value = $term_id; } return $value; } /** * Render property html. */ public function html() { $settings = $this->get_settings(); $layout = $settings->layout; $labels = $this->get_labels(); $taxonomies = $this->get_taxonomies(); $render_label = count( $taxonomies ) > 1; $advanced = $render_label && $layout === 'advanced'; $single = $render_label && $layout !== 'advanced'; $classes = count( $taxonomies ) > 1 ? '' : 'papi-fullwidth'; $value = $this->get_value(); $selected_term = get_term( $value ); $selected_term = is_wp_error( $selected_term ) || empty( $selected_term ) ? '' : $selected_term; $selected_taxonomy = empty( $selected_term ) ? reset( $taxonomies ) : $selected_term->taxonomy; $value = $this->get_term_value( $value ); $selected_label = reset( $labels ); if ( $settings->select2 ) { $classes = ' papi-component-select2'; } ?>
placeholder ) ? $settings->placeholder : ''; $placeholder = papi_is_empty( $placeholder ) ? ' ' : $placeholder; ?>
get_setting( 'allow_html' ) ) { $value = maybe_unserialize( $value ); if ( ! is_string( $value ) ) { $value = ''; } $value = wp_strip_all_tags( $value ); if ( ! papi_is_admin() ) { $value = $this->get_setting( 'nl2br' ) ? nl2br( $value ) : $value; } } return $value; } /** * Get default settings. * * @return array */ public function get_default_settings() { return [ 'allow_html' => false, 'nl2br' => true ]; } /** * Get value from the database. * * @return string */ public function get_value() { $value = $this->format_value( parent::get_value(), $this->get_slug(), papi_get_post_id() ); return $this->get_setting( 'allow_html' ) ? $value : esc_html( $value ); } /** * Render property html. */ public function html() { papi_render_html_tag( 'textarea', [ 'class' => 'papi-property-text', 'id' => esc_attr( $this->html_id() ), 'name' => esc_attr( $this->html_name() ), $this->get_value() ] ); } } ================================================ FILE: src/properties/class-papi-property-url.php ================================================ false ]; } /** * Render property html. */ public function html() { $settings = $this->get_settings(); papi_render_html_tag( 'input', [ 'class' => $settings->mediauploader ? 'papi-url-media-input' : null, 'id' => esc_attr( $this->html_id() ), 'name' => esc_attr( $this->html_name() ), 'type' => 'url', 'value' => $this->get_value() ] ); if ( $settings->mediauploader ) { echo ' '; papi_render_html_tag( 'input', [ 'class' => 'button papi-url-media-button', 'data-papi-action' => 'mediauploader', 'id' => esc_attr( $this->html_id() ), 'name' => esc_attr( $this->html_name() . '_button' ), 'type' => 'button', 'value' => esc_attr__( 'Select file', 'papi' ) ] ); } } /** * Change value after it's loaded from the database. * * @param mixed $value * @param string $slug * @param int $post_id * * @return mixed */ public function load_value( $value, $slug, $post_id ) { if ( filter_var( $value, FILTER_VALIDATE_URL ) ) { return $value; } } /** * Update value before it's saved to the database. * * @param mixed $value * @param string $slug * @param int $post_id * * @return mixed */ public function update_value( $value, $slug, $post_id ) { return $this->load_value( $value, $slug, $post_id ); } } ================================================ FILE: src/properties/class-papi-property-user.php ================================================ ID ) ) { $value = $value->ID; } if ( is_numeric( $value ) ) { return $value === 0 ? null : new WP_User( $value ); } return $value; } /** * Get default settings. * * @return array */ public function get_default_settings() { return [ 'allow_clear' => true, 'capabilities' => [], 'placeholder' => '', 'select2' => true ]; } /** * Get value from database. * * @return int */ public function get_value() { $user = parent::get_value(); if ( is_object( $user ) && isset( $user->ID ) ) { return $user->ID; } return 0; } /** * Get users as dropdown items. * * @return array */ public function get_items() { $capabilities = papi_to_array( $this->get_setting( 'capabilities' ) ); $users = get_users(); $items = []; foreach ( $users as $user ) { $allcaps = $user->allcaps; if ( count( array_diff( $capabilities, array_keys( $allcaps ) ) ) === 0 ) { $items[$user->display_name] = $user->ID; } } ksort( $items ); return $items; } /** * Change value after it's loaded from the database. * * @param mixed $value * @param string $slug * @param int $post_id * * @return int */ public function load_value( $value, $slug, $post_id ) { return (int) $value; } /** * Update value before it's saved to the database. * * @param mixed $value * @param string $slug * @param int $post_id * * @return int */ public function update_value( $value, $slug, $post_id ) { if ( $value instanceof WP_User ) { $value = $value->ID; } return (int) $value; } } ================================================ FILE: src/properties/class-papi-property.php ================================================ get_option( 'value' ); if ( papi_is_empty( $value ) ) { $type = papi_get_meta_type(); $slug = $this->get_slug( true ); $value = papi_get_field( $slug, null, $type ); $post_status = get_post_status( $this->get_post_id() ); if ( papi_is_empty( $value ) && ( $post_status === false || $post_status === 'auto-draft' ) ) { $value = $this->get_option( 'default' ); } } if ( papi_is_empty( $value ) ) { return $this->default_value; } if ( $this->convert_type === 'string' ) { $value = papi_convert_to_string( $value ); } return papi_santize_data( $value ); } /** * Render property html. */ public function html() { } /** * Determine if the property can be rendered or not. * * @return bool */ public function can_render() { // Check if current user can view the property. if ( ! $this->current_user_can() ) { return false; } // A disabled property should not be rendered. if ( $this->disabled() ) { return false; } // Check language option, so we don't render properties on a different language. if ( $lang = $this->get_option( 'lang' ) ) { return in_array( papi_get_lang(), papi_to_array( $lang ), true ); } // If no valid lang query string exists we have to override the display property. return $this->get_option( 'lang' ) === false; } /** * Render the property. */ public function render() { // Bail if we can't render the property. if ( ! $this->can_render() ) { return; } // Override display with rules check. if ( $this->display() ) { $this->display = $this->render_is_allowed_by_rules(); } // Render property. $this->render_row_html(); } /** * Render AJAX request. */ public function render_ajax_request() { papi_render_property( $this ); } /** * Render the property description. */ protected function render_description_html() { if ( papi_is_empty( $this->get_option( 'description' ) ) ) { return; } papi_render_html_tag( 'p', [ papi_nl2br( $this->get_option( 'description' ) ) ] ); } /** * Output hidden input field that cointains which property is used. */ protected function render_hidden_html() { $slug = $this->get_option( 'slug' ); if ( substr( $slug, - 1 ) === ']' ) { $slug = substr( $slug, 0, - 1 ); $slug = papi_get_property_type_key( $slug ); $slug .= ']'; } else { $slug = papi_get_property_type_key( $slug ); } $slug = papify( $slug ); $options = $this->get_options(); $property_json = base64_encode( papi_maybe_json_encode( $options ) ); papi_render_html_tag( 'input', [ 'data-property' => strtolower( $this->get_option( 'type' ) ), 'name' => $slug, 'type' => 'hidden', 'value' => $property_json ] ); } /** * Render label for the property. */ protected function render_label_html() { $title = $this->get_option( 'title' ); papi_render_html_tag( 'label', [ 'for' => $this->html_id(), 'title' => trim( $title . ' ' . papi_property_require_text( $this->get_options() ) ), $title, papi_property_required_html( $this ) ] ); } /** * Render property html. */ protected function render_property_html() { papi_render_html_tag( 'div', [ 'class' => 'papi-before-html ' . $this->get_option( 'before_class' ), 'data-property' => $this->get_option( 'type' ), papi_maybe_get_callable_value( $this->get_option( 'before_html' ) ) ] ); $this->html(); papi_render_html_tag( 'div', [ 'class' => 'papi-after-html ' . $this->get_option( 'after_class' ), 'data-property' => $this->get_option( 'type' ), papi_maybe_get_callable_value( $this->get_option( 'after_html' ) ) ] ); } /** * Render the final html that is displayed in the table. */ protected function render_row_html() { $display_class = $this->display() ? '' : ' papi-hide'; $rules_class = papi_is_empty( $this->get_rules() ) ? '' : ' papi-rules-exists'; $css_class = trim( $display_class . $rules_class ); $css_class .= sprintf( ' papi-layout-%s', $this->get_option( 'layout' ) ); if ( $this->get_option( 'raw' ) ) { echo sprintf( '
', esc_attr( $css_class ) ); $this->render_property_html(); $this->render_hidden_html(); $this->render_rules_json(); echo '
'; } else { ?> get_option( 'sidebar' ) && $this->get_option( 'layout' ) === 'horizontal' ): ?> render_label_html(); $this->render_description_html(); ?> get_option( 'sidebar' ) && $this->get_option( 'layout' ) === 'horizontal' ? '' : 'colspan="2"'; ?>> get_option( 'layout' ) === 'vertical' && $this->get_option( 'sidebar' ) ) { $this->render_label_html(); $this->render_description_html(); } $this->render_property_html(); $this->render_hidden_html(); $this->render_rules_json(); ?> get_rules(); if ( empty( $rules ) ) { return; } $rules = $this->conditional->prepare_rules( $rules, $this ); papi_render_html_tag( 'script', [ 'data-papi-rule-source-slug' => $this->html_name(), 'data-papi-rules' => 'true', 'type' => 'application/json', papi_maybe_json_encode( $rules ) ] ); } } ================================================ FILE: src/query/class-papi-query.php ================================================ '' ]; /** * The query type. * * @var string */ protected $type; /** * The query instance. * * @var WP_Term_Query|WP_Query */ protected $query; /** * Query constructor. * * @param array $args * @param string $type */ public function __construct( array $args = [], $type = 'post' ) { $this->type = $type === 'page' ? 'post' : $type; $this->query = $this->get_query_class(); $this->args = $args; } /** * Dynamically access query properties. * * @param string $key * * @return mixed */ public function __get( $key ) { switch ( $key ) { case 'posts': case 'terms': return $this->get_result(); default: break; } } /** * Get first item of result. * * @return array */ public function first() { $result = $this->get_result(); return array_shift( $result ); } /** * Parse query arguments. * * @param array $args */ public function parse_args( array $args ) { $args = array_merge( $this->default_args, $args ); // Since a page type has defined post types we should use them. // With a fallback on `post_type` args or `any` value. if ( $this->type === 'post' ) { $args = $this->parse_post_args( $args ); } else if ( $this->type === 'term' ) { $args = $this->parse_term_args( $args ); } $this->args = $args; } /** * Parse post query arguments. * * @param array $args * * @return array */ protected function parse_post_args( array $args ) { if ( isset( $args['page_type'] ) ) { $args['entry_type'] = $args['page_type']; unset( $args['page_type'] ); } $entry_type = papi_get_entry_type_by_id( $args['entry_type'] ); if ( $entry_type instanceof Papi_Page_Type ) { $args['post_type'] = papi_to_array( $entry_type->post_type ); } else { $args['post_type'] = isset( $args['post_type'] ) ? $args['post_type'] : ''; } return $args; } /** * Parse term query arguments. * * @param array $args * * @return array */ protected function parse_term_args( array $args ) { if ( isset( $args['taxonomy_type'] ) ) { $args['entry_type'] = $args['taxonomy_type']; unset( $args['taxonomy_type'] ); } $entry_type = papi_get_entry_type_by_id( $args['entry_type'] ); if ( $entry_type instanceof Papi_Taxonomy_Type ) { $args['taxonomy'] = papi_to_array( $entry_type->taxonomy ); } else { $args['taxonomy'] = isset( $args['taxonomy'] ) ? $args['taxonomy'] : ''; } return $args; } /** * Get query object for right query type. * * @return WP_Query|WP_Term_Query */ public function get_query_class() { switch ( $this->type ) { case 'post': case 'page': return new WP_Query; case 'term': // `WP_Term_Query` was added in WordPress 4.6. if ( class_exists( 'WP_Term_Query' ) ) { return new WP_Term_Query; } break; default: break; } } /** * Get real query arguments without Papi Query specific arguments. * * @return array */ public function get_query_args() { $args = $this->args; if ( empty( $args['meta_query'] ) ) { // Add new meta key/value if `meta_key` or `meta_value` is empty. if ( empty( $args['meta_key'] ) || empty( $args['meta_value'] ) ) { $args['meta_key'] = papi_get_page_type_key(); $args['meta_value'] = $args['entry_type']; } else if ( papi_entry_type_exists( $args['entry_type'] ) ) { $item = [ 'key' => $args['meta_key'], 'value' => $args['meta_value'] ]; // Add `meta_compare` if set. if ( isset( $args['meta_compare'] ) ) { $item['compare'] = $args['meta_compare']; unset( $args['meta_compare'] ); } // Add new meta query item. $args['meta_query'][] = $item; // Add Papi entry/page type meta query. $args['meta_query'][] = [ 'key' => papi_get_page_type_key(), 'value' => $args['entry_type'] ]; // Add meta query relation when two query items. if ( isset( $args['relation'] ) ) { $args['meta_query']['relation'] = $args['relation']; } else { $args['meta_query']['relation'] = 'AND'; } unset( $args['meta_key'] ); unset( $args['meta_value'] ); } } else if ( papi_entry_type_exists( $args['entry_type'] ) ) { // Add Papi entry/page type meta query. $args['meta_query'][] = [ 'key' => papi_get_page_type_key(), 'value' => $args['entry_type'] ]; // Add meta query relation if not set. if ( ! isset( $args['meta_query']['relation'] ) ) { $args['meta_query']['relation'] = 'AND'; } } // Since the real query classes don't support // custom arguments the should be deleted. foreach ( array_keys( $this->default_args ) as $key ) { if ( isset( $args[$key] ) ) { unset( $args[$key] ); } } return $args; } /** * Get result. * * Works for all query types. * * @return array */ public function get_result() { if ( ! method_exists( $this->query, 'query' ) ) { return []; } $this->parse_args( $this->args ); return $this->query->query( $this->get_query_args() ); } /** * Get last item of result. * * @return array */ public function last() { $result = $this->get_result(); return array_pop( $result ); } } ================================================ FILE: src/rest-api/class-papi-rest-api-post.php ================================================ ID ) ) ) { return $post; } // Register all properties fields with register meta. foreach ( $page_type->get_properties() as $property ) { $property->register(); } // Add filter to prepare the response for a post type. add_filter( 'rest_prepare_' . $post->post_type, [$this, 'prepare_response'] ); return $post; } /** * Prepare response. * * @param WP_REST_Response $response * * @return WP_REST_Response */ public function prepare_response( $response ) { if ( ! isset( $response->data['meta'] ) ) { return $response; } foreach ( $response->data['meta'] as $key => $value ) { $response->data['meta'][$key] = papi_get_field( $key, $value, 'post' ); } return $response; } /** * Setup REST API fields. */ public function setup_fields() { if ( ! function_exists( 'register_rest_field' ) ) { return; } $post_types = papi_get_post_types(); foreach ( $post_types as $post_type ) { register_rest_field( $post_type, 'page_type', [ 'get_callback' => [$this, 'get_page_type'] ] ); } } } new Papi_REST_API_Post; ================================================ FILE: src/rest-api/class-papi-rest-api-settings.php ================================================ entries = papi_get_all_entry_types( [ 'types' => 'option' ] ); foreach ( $this->entries as $entry ) { foreach ( $entry->get_properties() as $property ) { $property->register( 'option' ); } } } /** * Setup request after callbacks filter so it's only runs on settings endpoint. * * When the filter is added the `rest_pre_get_setting` will be removed since it's * not used to anything good. * * @param mixed $value * * @return mixed */ public function pre_get_setting( $value ) { if ( ! has_filter( 'rest_request_after_callbacks', [$this, 'prepare_response'] ) ) { add_filter( 'rest_request_after_callbacks', [$this, 'prepare_response'] ); remove_filter( 'rest_pre_get_setting', [$this, 'pre_get_setting'] ); } return $value; } /** * Get setting value for a property. * * @param string $key * @param string $value * * @return mixed */ public function get_setting( $key, $value ) { $property = null; foreach ( (array) $this->entries as $entry ) { if ( $property = $entry->get_property( $key ) ) { break; } } if ( is_null( $property ) ) { return $value; } $value = papi_get_option( $key ); return $property->rest_prepare_value( $value ); } /** * Prepare settings response. * * @param WP_HTTP_Response $response * * @return array */ public function prepare_response( $response ) { $response = (array) $response; foreach ( $response as $key => $value ) { $setting = $this->get_setting( $key, $value ); if ( $setting !== $value ) { $response[$key] = $setting; } } return $response; } } new Papi_REST_API_Settings; ================================================ FILE: src/rest-api/class-papi-rest-api.php ================================================ load_files(); $this->setup_actions(); } /** * Load admin files that are not loaded by the autoload. */ protected function load_files() { require_once __DIR__ . '/class-papi-rest-api-post.php'; require_once __DIR__ . '/class-papi-rest-api-settings.php'; } /** * Register REST API routes. */ public function register_routes() { } /** * REST API init callback. */ public function rest_api_init() { papi_get_all_entry_types(); } /** * Setup actions. */ protected function setup_actions() { add_action( 'rest_api_init', [$this, 'rest_api_init'] ); add_action( 'rest_api_init', [$this, 'register_routes'] ); } } new Papi_REST_API; ================================================ FILE: src/stores/class-papi-option-store.php ================================================ id = 0; } /** * Load property from page type. * * @param string $slug * @param string $child_slug * * @return null|object */ public function get_property( $slug, $child_slug = '' ) { $entry_type_id = papi_get_qs( 'page' ); if ( empty( $entry_type_id ) ) { $property = null; $entry_types = papi_get_all_entry_types( [ 'types' => 'option' ] ); foreach ( $entry_types as $entry_type ) { if ( $property = $entry_type->get_property( $slug, $child_slug ) ) { break; } } if ( is_null( $property ) ) { return; } return $property; } $entry_type = papi_get_entry_type_by_id( $entry_type_id ); if ( $entry_type instanceof Papi_Option_Type === false ) { return; } if ( $property = $entry_type->get_property( $slug, $child_slug ) ) { return $this->prepare_property( $property ); } } /** * Check if it's a valid store. * * @return bool */ public function valid() { return $this->id === 0; } } ================================================ FILE: src/stores/class-papi-post-store.php ================================================ id = papi_get_post_id( $id ); $this->post = get_post( $this->id ); $id = papi_get_page_type_id( $this->id ); $this->type_class = papi_get_entry_type_by_id( $id ); } /** * Get the permalink for the page. * * @return string */ public function get_permalink() { return get_permalink( $this->id ); } /** * Get the WordPress post object. * * @return WP_Post */ public function get_post() { return $this->post; } /** * Get the post status of a page. * * @return string */ public function get_status() { return get_post_status( $this->id ); } /** * Load property from page type. * * @param string $slug * @param string $child_slug * * @return null|Papi_Core_Property */ public function get_property( $slug, $child_slug = '' ) { $page_type_id = papi_get_page_type_id( $this->id ); $page_type = papi_get_entry_type_by_id( $page_type_id ); if ( $page_type instanceof Papi_Page_Type === false ) { return; } if ( $property = $page_type->get_property( $slug, $child_slug ) ) { return $this->prepare_property( $property ); } } /** * Prepare load value. * * @param Papi_Core_Property $property * @param mixed $value * * @return mixed */ protected function prepare_load_value( Papi_Core_Property $property, $value ) { if ( $property->overwrite ) { // Clear post cache to solve issue with cached post objects // when selecting post field. clean_post_cache( $this->id ); $slug = $property->get_slug( true ); $context = papi_is_admin() ? 'edit' : 'display'; $value = get_post_field( $slug, $this->id, $context ); } return $value; } /** * Check if the page has the post object and that it's not null. * * @return bool */ public function valid() { return ! is_null( $this->post ); } } ================================================ FILE: src/stores/class-papi-term-store.php ================================================ id = papi_get_term_id( $id ); $this->term = get_term( $this->id, '' ); $id = papi_get_taxonomy_type_id( $this->id ); $this->type_class = papi_get_entry_type_by_id( $id ); } /** * Get the permalink for the term. * * @return string */ public function get_permalink() { return get_term_link( $this->id ); } /** * Get the WordPress term object. * * @return WP_Term */ public function get_term() { return $this->term; } /** * Check if the term is a valid term object. * * @return bool */ public function valid() { return $this->term instanceof WP_Term; } /** * Load property from page type. * * @param string $slug * @param string $child_slug * * @return null|Papi_Core_Property */ public function get_property( $slug, $child_slug = '' ) { $taxonomy_type_id = papi_get_taxonomy_type_id( $this->id, 'term' ); $taxonomy_type = papi_get_entry_type_by_id( $taxonomy_type_id ); if ( $taxonomy_type instanceof Papi_Taxonomy_Type === false ) { return; } if ( $property = $taxonomy_type->get_property( $slug, $child_slug ) ) { return $this->prepare_property( $property ); } } } ================================================ FILE: src/types/class-papi-attachment-type.php ================================================ post_type[0]; } /** * Setup filters. */ protected function setup_filters() { // Don't add any filters on post.php page. if ( ! isset( $_GET['post'] ) ) { add_filter( 'attachment_fields_to_edit', [$this, 'edit_attachment'], 10, 2 ); add_filter( 'attachment_fields_to_save', [$this, 'save_attachment'], 10 ); } } /** * Add attachment fields. * * @param array $form_fields * @param WP_Post $post * * @return array */ public function edit_attachment( $form_fields, $post ) { foreach ( $this->get_boxes() as $box ) { if ( ! empty( $box->title ) ) { $form_fields['papi-media-title-' . uniqid()] = [ 'label' => '', 'input' => 'html', 'html' => '

' . $box->title . '

' ]; } foreach ( $box->properties as $prop ) { // Raw output is required. $prop->raw = true; // Set post id to the property. $prop->set_post_id( $post->ID ); // Add property to form fields. $form_fields[$prop->get_slug()] = [ 'label' => $prop->title, 'input' => 'html', 'helps' => $prop->description, 'html' => papi_maybe_get_callable_value( 'papi_render_property', $prop ) ]; } } // Add nonce field. $form_fields['papi_meta_nonce'] = [ 'label' => '', 'input' => 'html', 'html' => sprintf( '', wp_create_nonce( 'papi_save_data' ) ) ]; return $form_fields; } /** * Save attachment post data. * * @param array $post * * @return array */ public function save_attachment( $post ) { update_post_meta( $post['ID'], papi_get_page_type_key(), $this->get_id() ); $handler = new Papi_Admin_Meta_Handler(); $handler->save_meta_boxes( $post['ID'], $post ); return $post; } /** * Check if the entry type is a singleton. * * @return bool */ public function singleton() { $key = sprintf( 'entry_type_id.post_type.%s', $this->get_post_type() ); if ( papi()->exists( $key ) ) { return true; } papi()->singleton( $key, $this->get_id() ); return false; } } ================================================ FILE: src/types/class-papi-entry-type.php ================================================ help(); $screen = get_current_screen(); // No screen available. if ( $screen instanceof WP_Screen === false ) { return; } // Clean up all existing tabs. if ( ! $this->show_help_tabs || ! empty( $help ) ) { $screen->remove_help_tabs(); } // No new help tabs available. if ( empty( $help ) ) { return; } // Add help sidebar content. By default it will be disabled // since `help_sidebar` method returns false. $help_sidebar = $this->help_sidebar(); $help_sidebar = papi_maybe_get_callable_value( $help_sidebar ); $screen->set_help_sidebar( wpautop( $help_sidebar ) ); foreach ( $help as $key => $value ) { $args = [ 'id' => papi_html_name( $key ), 'title' => $key ]; if ( is_callable( $value ) ) { $args['callback'] = function () use ( $value ) { return wpautop( $value() ); }; } else { $args['content'] = wpautop( $value ); } $screen->add_help_tab( $args ); } } /** * Get custom admin body classes. * * @return array */ public function body_classes() { return []; } /** * Add new meta box with properties. * * @param mixed $file_or_options * @param array $properties */ protected function box( $file_or_options = [], $properties = [] ) { if ( ! is_string( $file_or_options ) && ! is_array( $file_or_options ) && ! is_object( $file_or_options ) ) { return; } list( $options, $properties ) = papi_get_options_and_properties( $file_or_options, $properties, true ); // Check so we have a post the to add the box to. // @codeCoverageIgnoreStart if ( ! $this->load_boxes ) { return; } // @codeCoverageIgnoreEnd if ( is_callable( $properties ) ) { $properties = call_user_func( $properties ); } // Check and convert all non properties objects to properties objects. $properties = $this->convert_properties( $properties ); // Create a core box instance and add it to the boxes array. array_push( $this->boxes, new Papi_Core_Box( $options, $properties ) ); } /** * Call parent register if it exists * to collect boxes on the parent entry type. */ protected function call_parent_register() { $parent_class = get_parent_class( $this ); if ( ! method_exists( $parent_class, 'register' ) ) { return; } $rc = new ReflectionClass( $parent_class ); // Bail if not instantiable. if ( ! $rc->isinstantiable() ) { return; } $parent = $rc->newInstance(); $parent->register(); $this->boxes = $parent->get_boxes(); } /** * Convert properties to properties objects. * * @param array|object $properties * * @return array */ protected function convert_properties( $properties ) { if ( is_array( $properties ) ) { if ( isset( $properties['type'] ) ) { $properties = [$properties]; } else if ( isset( $properties[0] ) && $properties[0] instanceof Papi_Core_Tab ) { foreach ( $properties as $items ) { $items->properties = array_map( 'papi_get_property_type', $items->properties ); } return $properties; } } if ( is_object( $properties ) ) { $properties = papi_get_property_type( $properties ); } if ( papi_is_property( $properties ) ) { $properties = [$properties]; } $properties = is_array( $properties ) ? $properties : []; $properties = array_map( 'papi_get_property_type', $properties ); return array_filter( $properties, 'papi_is_property' ); } /** * Modify fields that are returned from the entry type. * * @param array $fields * * @return array */ public function fields( $fields ) { return $fields; } /** * Get admin body css classes. * * Use `body_classes` method to add custom admin body classes. * * @return array */ public function get_body_classes() { $arr = $this->body_classes(); $arr = is_string( $arr ) ? [$arr] : $arr; $arr = is_array( $arr ) ? $arr : []; return array_merge( $arr, [] ); } /** * Get boxes from the page type. * * @return array */ public function get_boxes() { if ( empty( $this->boxes ) && $this->load_boxes === false ) { if ( ! method_exists( $this, 'register' ) ) { return []; } $this->load_boxes = true; $this->call_parent_register(); $this->register(); } // Merge boxes, e.g a parent box with a child box. $this->boxes = $this->merge_boxes( $this->boxes ); /** * Modify boxes array. * * @param array $boxes * @param string $id */ $this->boxes = apply_filters( 'papi/get_boxes', $this->boxes, $this->get_id() ); $this->boxes = is_array( $this->boxes ) ? $this->boxes : []; // Go through all boxes and only add boxes // that is a array and remove boxes that isn't // a instance of core box class. foreach ( $this->boxes as $index => $box ) { if ( is_array( $box ) ) { if ( is_string( $index ) ) { $box['title'] = $index; } $this->box( $box ); unset( $this->boxes[$index] ); continue; } // Remove boxes that isn't a instanceof core box class. if ( $box instanceof Papi_Core_Box === false ) { unset( $this->boxes[$index] ); continue; } // Remove box if site id isn't zero and isn't the current blog id. if ( $box->site_id !== 0 && $box->site_id !== get_current_blog_id() ) { unset( $this->boxes[$index] ); continue; } } return papi_sort_order( array_reverse( $this->boxes ) ); } /** * Get labels that should be changed * when using `fill_labels` option. * * @return array */ public function get_labels() { return []; } /** * Get menu to render entry type on. * * @return string */ public function get_menu() { return $this->menu; } /** * Get property from entry type. * * @param string $slug * @param string $child_slug * * @return Papi_Property */ public function get_property( $slug, $child_slug = '' ) { $boxes = $this->get_boxes(); $parts = preg_match( '/\[\d+\]/', $slug ) ? preg_split( '/\[\d+\]/', $slug ) : explode( '[', $slug ); $parts = array_map( function ( $part ) { return preg_replace( '/(\[|\])/', '', $part ); }, $parts ); if ( count( $parts ) > 1 ) { $property = null; for ( $i = 0, $l = count( $parts ); $i < $l; $i++ ) { $child = isset( $parts[$i + 1] ) ? $parts[$i + 1] : ''; $property = $this->get_property( $parts[$i], $child ); if ( isset( $parts[$i + 1] ) ) { $i++; } } /** * Modify property. * * @param Papi_Core_Property $property */ return apply_filters( 'papi/get_property', $property ); } foreach ( $boxes as $box ) { foreach ( $box->properties as $property ) { $property = papi_get_property_type( $property ); if ( papi_is_property( $property ) && $property->match_slug( $slug ) ) { if ( empty( $child_slug ) ) { /** * Modify property. * * @param Papi_Core_Property $property */ return apply_filters( 'papi/get_property', $property ); } $property = $property->get_child_property( $child_slug ); if ( papi_is_property( $property ) ) { /** * Modify property. * * @param Papi_Core_Property $property */ return apply_filters( 'papi/get_property', $property ); } } } } } /** * Get root properties. * * @return array */ public function get_properties() { $boxes = $this->get_boxes(); $list = []; foreach ( $boxes as $box ) { foreach ( $box->properties as $property ) { $list[] = $property; } } return $list; } /** * Add admin help tabs. * * Example: * 'My custom title' => 'My custom content' * * @return array */ public function help() { return []; } /** * Add help sidebar content. * * By default we return false to disable * the sidebar content. * * @return bool */ public function help_sidebar() { return false; } /** * Merge boxes with same title. * * @param array $boxes * * @return array */ protected function merge_boxes( array $boxes ) { $result = []; foreach ( $boxes as $box ) { if ( ! isset( $result[$box->id] ) ) { $result[$box->id] = $box; continue; } foreach ( $box->properties as $property ) { $result[$box->id]->properties[] = $property; } $result[$box->id]->properties = array_unique( $result[$box->id]->properties ); } return array_values( $result ); } /** * Add new property to the page using array or rendering property template file. * * @param array|string $file_or_options * @param array $values * * @return null|Papi_Property */ protected function property( $file_or_options = [], $values = [] ) { return papi_property( $file_or_options, $values ); } /** * Check if the entry type is a singleton. * * @return bool */ public function singleton() { return false; } /** * Setup entry type. */ public function setup() { add_action( 'in_admin_header', [$this, 'add_help_tabs'] ); add_filter( 'screen_options_show_screen', function () { return $this->show_screen_options; } ); // @codeCoverageIgnoreStart if ( ! method_exists( $this, 'register' ) ) { return; } // @codeCoverageIgnoreEnd $this->register(); foreach ( $this->get_boxes() as $box ) { new Papi_Admin_Meta_Box( $box ); } } /** * Add a new tab. * * @param mixed $file_or_options * @param array $properties * * @return null|Papi_Core_Tab */ protected function tab( $file_or_options = [], $properties = [] ) { if ( ! is_string( $file_or_options ) && ! is_array( $file_or_options ) ) { return; } return papi_tab( $file_or_options, $properties ); } /** * Load template file. * * @param string $file * @param array $values * * @return array */ protected function template( $file, $values = [] ) { return papi_template( $file, $values ); } } ================================================ FILE: src/types/class-papi-front-page-type.php ================================================

name ); ?>

description ) ); // wpcs: xss ok ?>
boxes as $box ) { do_meta_boxes( $box->id, 'normal', null ); } ?>
setup_post_types(); $this->setup_page_templates(); } /** * Determine if the page type is allowed by capabilities and post type. * * @return bool */ public function allowed() { $args = func_get_args(); if ( empty( $args ) ) { return parent::allowed(); } return papi_current_user_is_allowed( $this->capabilities ) && isset( $args[0] ) && in_array( $args[0], $this->post_type, true ); } /** * Should the Page Type be displayed in WordPress admin or not? * * @param string $post_type * * @return bool */ public function display( $post_type ) { return true; } /** * Get body css classes. * * @return array */ public function get_body_classes() { $classes = parent::get_body_classes(); if ( ! $this->show_permalink ) { $classes[] = 'papi-hide-edit-slug-box'; } if ( ! $this->show_page_attributes ) { $classes[] = 'papi-hide-pageparentdiv'; } return $classes; } /** * Get child page types that lives under the current page type. * * @return array */ public function get_child_types() { $child_types = []; foreach ( papi_to_array( $this->child_types ) as $id ) { $child_type = papi_get_entry_type_by_id( $id ); if ( $child_type instanceof Papi_Page_Type ) { $child_types[] = $child_type; } } return $child_types; } /** * Get labels that should be changed * when using `fill_labels` option. * * @return array */ public function get_labels() { if ( ! $this->fill_labels ) { return $this->labels; } return array_merge( $this->labels, [ 'add_new_item' => sprintf( '%s %s', __( 'Add New', 'papi' ), $this->name ), 'edit_item' => sprintf( '%s %s', __( 'Edit', 'papi' ), $this->name ), 'view_item' => sprintf( '%s %s', __( 'View', 'papi' ), $this->name ) ] ); } /** * Get post type. * * @return string */ public function get_post_type() { return papi_get_post_type(); } /** * Get post type supports that will be removed. * * @return array */ protected function get_post_type_supports() { $supports = ['custom-fields']; if ( method_exists( $this, 'remove' ) ) { $output = $this->remove(); $output = is_string( $output ) ? [$output] : $output; $output = is_array( $output ) ? $output : []; $output = array_filter( $output, 'is_string' ); $supports = array_merge( $supports, $output ); } $parent_class = get_parent_class( $this ); $parent_remove = method_exists( $parent_class, 'remove' ); while ( $parent_remove ) { $parent = new $parent_class(); $output = $parent->remove(); $output = is_string( $output ) ? [$output] : $output; $output = is_array( $output ) ? $output : []; $output = array_filter( $output, 'is_string' ); $supports = array_merge( $supports, $output ); $parent_class = get_parent_class( $parent_class ); $parent_remove = method_exists( $parent_class, 'remove' ); } return $supports; } /** * Get page type image thumbnail. * * @return string */ public function get_thumbnail() { if ( empty( $this->thumbnail ) ) { return ''; } return $this->thumbnail; } /** * Check if the given post is allowed to use the page type. * * @param string $post_type * * @return bool */ public function has_post_type( $post_type ) { return in_array( $post_type, $this->post_type, true ); } /** * Remove post type support action. */ public function remove_post_type_support() { global $_wp_post_type_features; $post_type = $this->get_post_type(); if ( empty( $post_type ) ) { return; } $post_type_supports = $this->get_post_type_supports(); foreach ( $post_type_supports as $key => $value ) { if ( is_numeric( $key ) ) { $key = $value; $value = ''; } if ( isset( $_wp_post_type_features[$post_type], $_wp_post_type_features[$post_type][$key] ) ) { unset( $_wp_post_type_features[$post_type][$key] ); continue; } if ( in_array( strtolower( $key ), ['all', 'normal', 'side', 'advanced'], true ) ) { $value = strtolower( $key ); } else if ( empty( $value ) ) { $value = 'normal'; } $this->remove_meta_boxes[] = [$key, $value]; } add_action( 'add_meta_boxes', [$this, 'remove_meta_boxes'], 999 ); } /** * Remove meta boxes. */ public function remove_meta_boxes() { global $wp_meta_boxes; $post_type = $this->get_post_type(); $context = []; foreach ( $this->remove_meta_boxes as $item ) { if ( $item[0] !== $item[1] ) { remove_meta_box( $item[0], $post_type, $item[1] ); continue; } $context = $item[0]; // Our special context. if ( $context === 'all' ) { $context = ['normal', 'side', 'advanced']; } else { $context = [strtolower( $context )]; } foreach ( $context as $ctx ) { if ( ! isset( $wp_meta_boxes[$post_type], $wp_meta_boxes[$post_type][$ctx] ) ) { continue; } $meta_boxes = $wp_meta_boxes[$post_type][$ctx]; if ( ! is_array( $meta_boxes ) ) { continue; } foreach ( $meta_boxes as $level ) { foreach ( $level as $id => $box ) { // Don't allow removing of papi boxes. if ( strpos( $id, '_papi' ) !== false ) { continue; } // Don't allow removing of submitdiv. if ( $id === 'submitdiv' ) { continue; } remove_meta_box( $id, $post_type, $ctx ); } } } } // Special for editor in normal context. if ( in_array( 'normal', $context, true ) ) { remove_post_type_support( 'page', 'editor' ); } } /** * Setup page type. */ public function setup() { parent::setup(); // Remove post type support and meta boxes. $this->remove_post_type_support(); // Add support for displaying information in publish box from a page type. if ( method_exists( $this, 'publish_box' ) ) { add_action( 'post_submitbox_misc_actions', [$this, 'publish_box'] ); } // Hide page template dropdown if it shouldn't be showed. if ( ! $this->show_page_template ) { add_filter( 'theme_page_templates', '__return_empty_array' ); } // Main title input placeholder. if ( ! empty( $this->labels['title_placeholder'] ) ) { add_filter( 'enter_title_here', function () { return $this->labels['title_placeholder']; } ); } } /** * Setup post types array. */ protected function setup_post_types() { $this->post_type = papi_to_array( $this->post_type ); // Set a default value to post types array // if we don't have a array or a empty array. if ( empty( $this->post_type ) ) { $this->post_type = ['page']; } if ( count( $this->post_type ) === 1 && $this->post_type[0] === 'any' ) { $this->post_type = get_post_types( '', 'names' ); $this->post_type = array_values( $this->post_type ); } } /** * Setup page templates if templates is a array. */ protected function setup_page_templates() { if ( ! is_array( $this->template ) || ! $this->has_post_type( papi_get_post_type() ) ) { return; } $this->show_page_template = true; foreach ( $this->post_type as $post_type ) { // Can't use `theme_templates` filter since it's added in 4.9.6. add_filter( "theme_{$post_type}_templates", function( $templates ) { foreach ( $this->template as $template ) { if ( ! is_array( $template ) || ! isset( $template['template'], $template['label'] ) ) { continue; } $templates[$template['template']] = $template['label']; } return $templates; } ); } } } ================================================ FILE: src/types/class-papi-taxonomy-type.php ================================================ taxonomy, true ); } /** * Should the Taxonomy Type be displayed in WordPress admin or not? * * @param string $taxonomy * * @return bool */ public function display( $taxonomy ) { return true; } /** * Get labels that should be changed * when using `fill_labels` option. * * @return array */ public function get_labels() { if ( ! $this->fill_labels ) { return $this->labels; } return array_merge( $this->labels, [ 'add_new_item' => sprintf( '%s %s', __( 'Add New', 'papi' ), $this->name ), 'edit_item' => sprintf( '%s %s', __( 'Edit', 'papi' ), $this->name ), 'view_item' => sprintf( '%s %s', __( 'View', 'papi' ), $this->name ) ] ); } /** * Setup actions. */ protected function setup_actions() { foreach ( papi_to_array( $this->taxonomy ) as $taxonomy ) { if ( is_string( $taxonomy ) && taxonomy_exists( $taxonomy ) ) { add_action( $taxonomy . '_edit_form', [$this, 'edit_form'] ); } } } /** * Render term edit form. */ public function edit_form() { ?>
boxes as $box ) { do_meta_boxes( $box->id, 'normal', null ); } ?>
taxonomy = papi_to_array( $this->taxonomy ); } } ================================================ FILE: tests/Dockerfile ================================================ FROM jitesoft/composer:7.4 RUN apk --no-cache add bash mysql-client zlib-dev libjpeg-turbo-dev libpng-dev freetype-dev subversion RUN docker-php-ext-install gd ================================================ FILE: tests/README.md ================================================ # Papi Tests ## Run tests with VVV This guide will describe how to use [VVV](https://github.com/varying-vagrant-vagrants/vvv/) to run Papi tests. 1. Download [VVV](https://github.com/varying-vagrant-vagrants/vvv/) which is an evolving Vagrant configuration focused on WordPress development. 2. Clone Papi to `path/to/vvv/www/wordpress-default/wp-content/plugins/`. 2. Go to Run `path/to/vvv/www/wordpress-default/wp-content/plugins/papi/` and run `composer install` on your host machine. If you have configured Composer right then you can run this in your VVV machine. 3. Log in to your vagrant machine and go to `/srv/www/wordpress-default/wp-content/plugins/papi/`, `/srv/` is equal to your VVV directory. 4. Run `vendor/bin/phpunit` (PHPUnit is installed with Composer) and PHPUnit will start to test Papi. ## VVV tips If using VVV you can run `xdebug_on` to turn Xdebug on so you can generate code coverage. You can turn it off by running `xdebug_off` ## PHPUnit tips You can run specific tests by providing the path and filename to the test class: ``` $ vendor/bin/phpunit tests/cases/admin ``` You can run specific test method by using `--filter`: ``` $ vendor/bin/phpunit --filter test_save_meta_boxes ``` A text code coverage summary can be displayed using the `--coverage-text` option: ``` $ vendor/bin/phpunit --coverage-text ``` ## Writing Tests * Each test file should roughly correspond to an associated source file, e.g `src/admin/class-papi-admin-ajax.php` should have a test file named `tests/cases/admin/class-papi-admin-ajax-test.php` * Each test method should cover a single method or function with one or more assertions * A single method or function can have multiple associated test methods if it's a large or complex method * For code that cannot be tested or should not be tested use `// @codeCoverageIgnoreStart` and `// @codeCoverageIgnoreEnd` before and after the code. * In addition to covering each line of a method/function, make sure to test common input and edge cases. When resolving a issue you should create a test for it. * Prefer `assertsSame()` where possible as it tests equality. When testing objects you should use `assertEquals()` since object's can be different but with same data. * Remember that only methods prefixed with `test` will be run. * Remember that files that test code should end with `-test.php` prefix. * Filters persist between test cases so be sure to remove them in your test method or in the `tearDown()` method. ## Automated Tests Tests are automatically run with [Travis-CI](https://travis-ci.org) for each commit and pull request. You can check the current test status [here](https://travis-ci.org/wp-papi/papi). This is the current build status for `master` branch: [![Build Status](https://travis-ci.org/wp-papi/papi.svg?branch=master)](https://travis-ci.org/wp-papi/papi) ## Code Coverage Code coverage is available on [Codecov](https://codecov.io/) which receives updated data after each Travis build. You can check the current code coverage [here](https://codecov.io/github/wp-papi/papi/). This is the current code coverage for `master` branch: [![Coverage Status](https://img.shields.io/codecov/c/github/wp-papi/papi.svg?style=flat)](https://codecov.io/github/wp-papi/papi) ================================================ FILE: tests/bin/install-cp-tests.sh ================================================ #!/usr/bin/env bash if [ $# -lt 3 ]; then echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" exit 1 fi DB_NAME=$1 DB_USER=$2 DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-master} SKIP_DB_CREATE=${6-false} TMPDIR=${TMPDIR-/tmp} # need wp directories to support our test suite. WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} download() { if [ `which curl` ]; then curl -L -s "$1" > "$2"; elif [ `which wget` ]; then wget -nv -O "$2" "$1" fi } set -ex install_wp() { echo "download and install ClassicPress ${WP_VERSION}" if [ ! -d $WP_CORE_DIR ] then mkdir -p $WP_CORE_DIR download https://github.com/ClassicPress/ClassicPress-release/archive/${WP_VERSION}.tar.gz $TMPDIR/cp.tar.gz tar --strip-components=1 -zxmf $TMPDIR/cp.tar.gz -C $WP_CORE_DIR fi } install_test_suite() { echo "download test-suite" # portable in-place argument for both GNU sed and Mac OSX sed if [[ $(uname -s) == 'Darwin' ]]; then local ioption='-i .bak' else local ioption='-i' fi # set up testing suite if it doesn't yet exist if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR TMP_STR=$$; git clone --depth 1 --branch $WP_VERSION https://github.com/ClassicPress/ClassicPress.git /tmp/cp-core-${TMP_STR} mv -v /tmp/cp-core-${TMP_STR}/tests/phpunit/includes $WP_TESTS_DIR/includes mv -v /tmp/cp-core-${TMP_STR}/tests/phpunit/data $WP_TESTS_DIR/data fi if [ ! -f wp-tests-config.php ]; then download https://raw.githubusercontent.com/ClassicPress/ClassicPress/${WP_VERSION}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php # remove all forward slashes in the end WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php fi } install_db() { if [ ${SKIP_DB_CREATE} = "true" ]; then return 0 fi echo "initializing DB" # parse DB_HOST for port or socket references local PARTS=(${DB_HOST//\:/ }) local DB_HOSTNAME=${PARTS[0]}; local DB_SOCK_OR_PORT=${PARTS[1]}; local EXTRA="" if ! [ -z $DB_HOSTNAME ] ; then if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" elif ! [ -z $DB_SOCK_OR_PORT ] ; then EXTRA=" --socket=$DB_SOCK_OR_PORT" elif ! [ -z $DB_HOSTNAME ] ; then EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" fi fi # create database mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA } install_wp install_test_suite install_db ================================================ FILE: tests/bootstrap.php ================================================ ajax = new Papi_Admin_Ajax(); add_filter( 'wp_die_ajax_handler', [$this, 'get_wp_die_handler'], 1, 1 ); } public function tearDown() { parent::tearDown(); unset( $_GET, $_POST, $this->ajax ); remove_filter( 'wp_die_ajax_handler', [$this, 'get_wp_die_handler'], 1, 1 ); } public function wp_die_handler( $message ) { } public function test_actions() { $this->assertSame( 10, has_action( 'init', [$this->ajax, 'add_endpoint'] ) ); $this->assertSame( 10, has_action( 'parse_request', [$this->ajax, 'handle_papi_ajax'] ) ); $this->assertSame( 10, has_action( 'admin_enqueue_scripts', [$this->ajax, 'ajax_url'] ) ); $this->assertSame( 10, has_action( 'papi/ajax/get_property', [$this->ajax, 'get_property'] ) ); $this->assertSame( 10, has_action( 'papi/ajax/get_properties', [$this->ajax, 'get_properties'] ) ); } public function test_endpoint() { $ajax = new Papi_Admin_Ajax(); $ajax->add_endpoint(); global $wp_rewrite; $this->assertTrue( ! isset( $wp_rewrite->extra_rules_top['papi-ajax/([^/]*)/?'] ) ); add_filter( 'pre_option_permalink_structure', function() { return 'not empty'; } ); $ajax = new Papi_Admin_Ajax(); $ajax->add_endpoint(); $this->assertNotNull( $wp_rewrite->extra_rules_top['papi-ajax/([^/]*)/?'] ); $this->assertSame( 'index.php?action=$matches[1]', $wp_rewrite->extra_rules_top['papi-ajax/([^/]*)/?'] ); } public function test_handle_papi_ajax_doing_ajax() { $this->assertNull( $this->ajax->handle_papi_ajax() ); } public function test_handle_papi_ajax_action() { $_GET = [ 'action' => 'get_property', 'slug' => 'hello', 'type' => 'string' ]; $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $this->ajax->handle_papi_ajax(); wp_set_current_user( 0 ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/papi\_hello/' ); } public function test_handle_papi_ajax() { $this->assertNull( $this->ajax->handle_papi_ajax() ); $this->expectOutputRegex( '//' ); } public function test_get_entry_type_fail() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_GET = [ 'entry_type' => 'properties-page-type' ]; do_action( 'papi/ajax/get_entry_type' ); $this->expectOutputRegex( '/\{\"error\"\:\"No entry type found\"\}/' ); } public function test_get_entry_type_success() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_GET = [ 'entry_type' => 'properties-page-type' ]; add_filter( 'papi/settings/directories', function () { return PAPI_FIXTURE_DIR . '/page-types'; } ); do_action( 'papi/ajax/get_entry_type' ); $this->expectOutputRegex( '/properties\-page/' ); } public function test_get_posts() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $post_id = $this->factory->post->create(); do_action( 'papi/ajax/get_posts' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( sprintf( '/\"ID\"\:%d\,/', $post_id ) ); } public function test_get_posts_fields() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $post_id = $this->factory->post->create(); $_GET = [ 'fields' => ['ID'] ]; do_action( 'papi/ajax/get_posts' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( sprintf( '/\{\"ID\"\:%d\}/', $post_id ) ); } public function test_get_posts_fake_post_type() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_GET = [ 'query' => [ 'post_type' => 'get_posts' ] ]; do_action( 'papi/ajax/get_posts' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\[\]/' ); } public function test_get_property() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_GET = [ 'slug' => 'hello', 'type' => 'string' ]; do_action( 'papi/ajax/get_property' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/papi\_hello/' ); } public function test_get_property_fail() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_GET = [ 'slug' => 'hello', 'type' => 'fake' ]; do_action( 'papi/ajax/get_property' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No property found\"\}/' ); } public function test_get_properties() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $property = papi_get_property_type( [ 'slug' => 'name', 'type' => 'string' ] ); $_POST = [ 'properties' => json_encode( [ $property->get_options(), [ 'type' => 'string', 'title' => 'nyckel' ] ] ) ]; do_action( 'papi/ajax/get_properties' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/papi\_name/' ); $this->expectOutputRegex( '/papi\_nyckel/' ); } public function test_get_properties_fail() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_POST = [ 'properties' => json_encode( [ [ 'type' => 'fake', 'title' => 'nyckel' ] ] ) ]; do_action( 'papi/ajax/get_properties' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No properties found\"\}/' ); } public function test_get_properties_fail_2() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_POST = []; do_action( 'papi/ajax/get_properties' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No properties found\"\}/' ); } public function test_get_properties_fail_3() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_POST = [ 'properties' => json_encode( [] ) ]; do_action( 'papi/ajax/get_properties' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No properties found\"\}/' ); } public function test_get_rules_result_success() { $_GET = [ 'page_type' => 'rule-page-type', 'post' => $this->factory->post->create() ]; $_POST = [ 'data' => json_encode( [ 'rules' => [ [ 'operator' => '=', 'slug' => 'rules1', 'source' => '', 'value' => 123 ] ], 'slug' => 'rules_1' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"render\"\:false\}/' ); } public function test_get_rules_result_success_2() { $_GET = [ 'page_type' => 'rule-page-type', 'post' => $this->factory->post->create() ]; $_POST = [ 'data' => json_encode( [ 'rules' => [ [ 'operator' => 'NOT EXISTS', 'slug' => 'rules2', 'source' => '' ] ], 'slug' => 'rules_2' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"render\"\:true\}/' ); } public function test_get_rules_result_success_3() { $_GET = [ 'page_type' => 'rule-page-type', 'post' => $this->factory->post->create() ]; $_POST = [ 'data' => json_encode( [ 'rules' => [ [ 'operator' => '=', 'slug' => 'rules_3', 'source' => 'hello', 'value' => 'hello' ] ], 'slug' => 'rules_3' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"render\"\:true\}/' ); } public function test_get_rules_result_fail() { $_GET = [ 'slug' => 'name' ]; do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No rule found\"\}/' ); } public function test_get_rules_result_fail_2() { $_GET = [ 'page_type' => 'name' ]; do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No rule found\"\}/' ); } public function test_get_rules_result_fail_3() { $_GET = [ 'slug' => 'name', 'page_type' => 'fake' ]; do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No rule found\"\}/' ); } public function test_get_rules_result_fail_4() { $_GET = [ 'page_type' => 'simple-page-type' ]; $_POST = [ 'data' => json_encode( [ 'slug' => 'fake' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No rule found\"\}/' ); } public function test_get_rules_result_fail_5() { $_GET = [ 'page_type' => 'simple-page-type' ]; $_POST = [ 'data' => json_encode( [] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No rule found\"\}/' ); } public function test_get_rules_result_fail_6() { $_GET = [ 'page_type' => 'rule-page-type', 'post' => $this->factory->post->create() ]; $_POST = [ 'data' => json_encode( [ 'rules' => [ [ 'operator' => '=', 'slug' => 'rules_4', 'source' => 'fredrik', 'value' => 'hello' ] ], 'slug' => 'rules_3' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"render\"\:false\}/' ); } public function test_get_rules_result_fail_7() { $_GET = [ 'page_type' => 'rule-page-type', 'post' => $this->factory->post->create() ]; $_POST = [ 'data' => json_encode( [ 'rules' => [ [ 'operator' => '=', 'slug' => 'rules_4', 'source' => 'fredrik', 'value' => 'hello' ] ], 'slug' => 'rules_3[]' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"render\"\:false\}/' ); } public function test_get_rules_result_fail_8() { $_GET = [ 'page_type' => 'rule-page-type', 'post' => $this->factory->post->create() ]; $_POST = [ 'data' => json_encode( [ 'rules' => [ [ 'operator' => '=', 'slug' => 'rules_fake', 'source' => 'fredrik', 'value' => 'hello' ] ], 'slug' => 'rules_4' ] ) ]; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); if ( ! defined( 'DOING_PAPI_AJAX' ) ) { define( 'DOING_PAPI_AJAX', true ); } do_action( 'papi/ajax/get_rules_result' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No rule found\"\}/' ); } public function test_get_shortcode_fail() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_GET = ['action' => 'get_shortcode']; do_action( 'papi/ajax/get_shortcode' ); $this->expectOutputRegex( '/{\"html\"\:\"\"\}/' ); } public function test_get_shortcode_success() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } add_shortcode( 'hello', function () { return 'hello'; } ); $_GET = ['action' => 'get_shortcode', 'shortcode' => '[hello]']; do_action( 'papi/ajax/get_shortcode' ); $this->expectOutputRegex( '/\"hello\"/' ); } public function test_get_terms() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } register_taxonomy( 'test_taxonomy', 'post' ); $term_id = $this->factory->term->create( [ 'taxonomy' => 'test_taxonomy', 'name' => 'Apple', 'description' => 'A yummy apple' ] ); $_GET = [ 'taxonomy' => 'test_taxonomy' ]; $post_id = $this->factory->post->create(); wp_set_object_terms( $post_id, $term_id, 'test_taxonomy' ); do_action( 'papi/ajax/get_terms' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( sprintf( '/{\"%s\"\:\"Apple\"\}/', $term_id ) ); } public function test_render_error() { if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $this->ajax->render_error( 'No property found' ); $this->expectOutputRegex( '/.*\S.*/' ); $this->expectOutputRegex( '/\{\"error\"\:\"No property found\"\}/' ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-assets-test.php ================================================ assets = new Papi_Admin_Assets; } public function tearDown() { parent::tearDown(); unset( $this->assets ); } public function test_actions() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); $assets = new Papi_Admin_Assets; $this->assertGreaterThan( 0, has_action( 'admin_enqueue_scripts', [$assets, 'enqueue_css'] ) ); $this->assertGreaterThan( 0, has_action( 'admin_enqueue_scripts', [$assets, 'enqueue_js'] ) ); $this->assertGreaterThan( 0, has_action( 'admin_enqueue_scripts', [$assets, 'enqueue_locale'] ) ); $current_screen = null; } public function test_enqueue_css() { $this->assertNull( $this->assets->enqueue_css() ); } public function test_enqueue_js() { $_SERVER['REQUEST_URI'] = 'plugins.php'; $this->assertNull( $this->assets->enqueue_js() ); $_SERVER['REQUEST_URI'] = ''; $this->assertNull( $this->assets->enqueue_js() ); } public function test_enqueue_locale() { $this->assertNull( $this->assets->enqueue_locale() ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-columns-test.php ================================================ post_id = $this->factory->post->create(); $this->term_id = $this->factory->term->create(); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types', PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); } public function tearDown() { parent::tearDown(); unset( $_GET, $this->post_id, $this->term_id ); } public function test_manage_page_type_posts_columns() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $arr = $admin->manage_page_type_posts_columns( [] ); $this->assertSame( ['entry_type' => 'Type'], $arr ); $_GET['post_type'] = 'fake'; $admin = new Papi_Admin_Columns; $arr = $admin->manage_page_type_posts_columns( [] ); $this->assertEmpty( $arr ); unset( $_GET['post_type'] ); } public function test_manage_page_type_posts_columns_hide_filter() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; add_filter( 'papi/settings/column_hide_page', '__return_true' ); $arr = $admin->manage_page_type_posts_columns( [] ); $this->assertFalse( isset( $arr['entry_type'] ) ); unset( $_GET['post_type'] ); } public function test_manage_page_type_sortable_columns() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $arr = $admin->manage_page_type_sortable_columns( [] ); $this->assertSame( ['entry_type' => 'entry_type'], $arr ); } public function test_manage_page_type_posts_columns_title_filter() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $arr = $admin->manage_page_type_posts_columns( [] ); $this->assertSame( ['entry_type' => 'Type'], $arr ); add_filter( 'papi/settings/column_title_page', function () { return 'Typer'; } ); $arr = $admin->manage_page_type_posts_columns( [] ); $this->assertSame( ['entry_type' => 'Typer'], $arr ); unset( $_GET['post_type'] ); } public function test_manage_page_type_posts_custom_column_standard() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $admin->manage_page_type_posts_custom_column( 'entry_type', $this->post_id ); $this->expectOutputRegex( '/Standard\sPage/' ); unset( $_GET['post_type'] ); } public function test_manage_page_type_posts_custom_column_empty() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $admin->manage_page_type_posts_custom_column( '', $this->post_id ); $this->expectOutputRegex( '//' ); unset( $_GET['post_type'] ); } public function test_manage_page_type_posts_custom_column_auto() { $_GET['post_type'] = 'page'; update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); $admin = new Papi_Admin_Columns; $admin->manage_page_type_posts_custom_column( 'entry_type', $this->post_id ); $this->expectOutputRegex( '/Simple page/' ); unset( $_GET['post_type'] ); } public function test_manage_page_type_posts_custom_column_fake() { $post_id = $this->factory->post->create(); $_GET['post_type'] = 'fake'; $admin = new Papi_Admin_Columns; $admin->manage_page_type_posts_custom_column( 'entry_type', $post_id ); $this->expectOutputRegex( '//' ); unset( $_GET['post_type'] ); } public function test_manage_taxonomy_posts_custom_column_empty() { $_GET['taxonomy'] = 'category'; $admin = new Papi_Admin_Columns; $admin->manage_page_type_posts_custom_column( '', '', $this->term_id ); $this->expectOutputRegex( '//' ); unset( $_GET['taxonomy'] ); } public function test_manage_page_type_posts_custom_column_hide_filter() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); add_filter( 'papi/settings/column_hide_page', '__return_true' ); $admin->manage_page_type_posts_custom_column( 'entry_type', $this->post_id ); $this->expectOutputRegex( '//' ); unset( $_GET['post_type'] ); } public function test_pre_get_posts() { global $pagenow; $pagenow = 'edit.php'; $admin = new Papi_Admin_Columns; $_GET['page_type'] = 'simple-page-type'; $query = $admin->pre_get_posts( new WP_Query() ); $this->assertSame( [ 'meta_key' => papi_get_page_type_key(), 'meta_value' => 'simple-page-type' ], $query->query_vars ); $_GET['page_type'] = 'papi-standard-page'; $query = $admin->pre_get_posts( new WP_Query() ); $this->assertSame( [ [ 'key' => papi_get_page_type_key(), 'compare' => 'NOT EXISTS' ] ], $query->query_vars['meta_query'] ); unset( $_GET['page_type'] ); $_GET['page_type'] = 'papi-standard-page'; $query = new WP_Query(); $query->set( 'orderby', 'entry_type' ); $query = $admin->pre_get_posts( $query ); $this->assertSame( papi_get_page_type_key(), $query->query_vars['meta_key'] ); $this->assertSame( 'meta_value', $query->query_vars['orderby'] ); unset( $_GET['page_type'] ); } public function test_restrict_page_types() { $_GET['post_type'] = ''; $admin = new Papi_Admin_Columns; $admin->restrict_page_types(); $this->expectOutputRegex( '//' ); unset( $_GET['post_type'] ); } public function test_restrict_page_types_2() { $_GET['post_type'] = 'page'; add_filter( 'papi/settings/show_standard_page_type_in_filter_page', '__return_true' ); $admin = new Papi_Admin_Columns; $admin->restrict_page_types(); $this->expectOutputRegex( '/.*\S.*/' ); unset( $_GET['post_type'] ); } public function test_setup_actions() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $this->assertSame( 10, has_action( 'restrict_manage_posts', [$admin, 'restrict_page_types'] ) ); unset( $_GET['post_type'] ); } public function test_setup_filters() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Columns; $this->assertSame( 10, has_filter( 'pre_get_posts', [$admin, 'pre_get_posts'] ) ); $this->assertSame( 10, has_filter( 'manage_page_posts_columns', [$admin, 'manage_page_type_posts_columns'] ) ); $this->assertSame( 10, has_filter( 'manage_page_posts_custom_column', [$admin, 'manage_page_type_posts_custom_column'] ) ); unset( $_GET['post_type'] ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-entry-post-test.php ================================================ reset(); $this->admin = new Papi_Admin_Entry_Post; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); } public function tearDown() { parent::tearDown(); unset( $_GET ); } public function test_hidden_meta_boxes() { $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Entry_Post; $this->assertNull( $admin->hidden_meta_boxes() ); do_meta_boxes( 'papi-hidden-editor', 'normal', null ); $this->expectOutputRegex( '/.*\S.*/' ); } public function test_hidden_meta_boxes_2() { $_GET['post_type'] = 'fake'; $admin = new Papi_Admin_Entry_Post; $this->assertNull( $admin->hidden_meta_boxes() ); do_meta_boxes( 'papi-hidden-editor', 'normal', null ); $this->expectOutputRegex( '//' ); } public function test_hidden_meta_box_editor() { $this->admin->hidden_meta_box_editor(); $this->expectOutputRegex( '/wp\-editor\-wrap/' ); } public function test_load_post_new() { $_GET['post_type'] = ''; $admin = new Papi_Admin_Entry_Post; $admin->load_post_new(); $this->expectOutputRegex( '//' ); } public function test_load_post_new_2() { $_SERVER['REQUEST_URI'] = 'http://site.com/wp-admin/post-new.php?post_type=page'; add_filter( 'wp_redirect', function( $location ) { $this->assertTrue( strpos( $location, 'edit.php?post_type=page&page=papi-add-new-page,page') !== false ); return false; } ); $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Entry_Post; $admin->load_post_new(); } public function test_load_post_new_3() { $_SERVER['REQUEST_URI'] = 'http://site.com/wp-admin/post-new.php?post_type=page'; add_filter( 'wp_redirect', function( $location ) { $this->assertTrue( strpos( $location, 'post-new.php?page_type=simple-page-type&post_type=page') !== false ); return false; } ); add_filter( 'papi/settings/only_page_type_page', function () { return 'simple-page-type'; } ); $_GET['post_type'] = 'page'; $admin = new Papi_Admin_Entry_Post; $admin->load_post_new(); } public function test_load_post_new_4() { papi_test_register_book_post_type(); add_filter( 'papi/settings/show_standard_page_type_book', '__return_false' ); $_SERVER['REQUEST_URI'] = 'http://site.com/wp-admin/post-new.php?post_type=book'; add_filter( 'wp_redirect', function( $location ) { $this->assertTrue( strpos( $location, 'post-new.php?page_type=book-page-type&post_type=book') !== false ); return false; } ); $_GET['post_type'] = 'book'; $admin = new Papi_Admin_Entry_Post; $admin->load_post_new(); } public function test_setup_actions() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); $admin = new Papi_Admin_Entry_Post; $this->assertSame( 10, has_action( 'load-post-new.php', [$admin, 'load_post_new'] ) ); $this->assertSame( 10, has_action( 'add_meta_boxes', [$admin, 'hidden_meta_boxes'] ) ); $this->assertSame( 10, has_action( 'redirect_post_location', [$admin, 'redirect_post_location'] ) ); $current_screen = null; } } ================================================ FILE: tests/cases/admin/class-papi-admin-entry-taxonomy-test.php ================================================ reset(); } public function tearDown() { parent::tearDown(); unset( $_GET ); } public function test_add_form_fields_empty() { $admin = new Papi_Admin_Entry_Taxonomy; $admin->add_form_fields(); $this->expectOutputRegex( '//' ); } public function test_add_form_fields_single() { add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); $_GET['taxonomy'] = 'category'; $admin = new Papi_Admin_Entry_Taxonomy; $admin->setup_taxonomies_hooks(); $admin->add_form_fields(); $this->expectOutputRegex( '/input.*name\=\"\_papi\_page\_type\"/' ); } public function test_add_form_fields_single_plus_standard() { add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); add_filter( 'papi/settings/show_standard_taxonomy_type_category', '__return_true' ); $_GET['taxonomy'] = 'category'; $admin = new Papi_Admin_Entry_Taxonomy; $admin->setup_taxonomies_hooks(); $admin->add_form_fields(); $this->expectOutputRegex( '/select.*name\=\"\_papi\_page\_type\"/' ); } public function test_add_form_fields_several() { add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); $_GET['taxonomy'] = 'post_tag'; $admin = new Papi_Admin_Entry_Taxonomy; $admin->setup_taxonomies_hooks(); $admin->add_form_fields(); $this->expectOutputRegex( '/select.*name\=\"\_papi\_page\_type\"/' ); } public function test_setup_actions() { $admin = new Papi_Admin_Entry_Taxonomy; $this->assertSame( 10, has_action( 'admin_init', [$admin, 'setup_taxonomies_hooks'] ) ); $this->assertFalse( has_action( 'category_add_form_fields', [$admin, 'add_form_fields'] ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); $admin->setup_taxonomies_hooks(); $this->assertSame( 10, has_action( 'category_add_form_fields', [$admin, 'add_form_fields'] ) ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-menu-test.php ================================================ reset(); $_GET = []; $_POST = []; $this->menu = new Papi_Admin_Menu(); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types', PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); } public function tearDown() { parent::tearDown(); unset( $_GET, $_POST, $this->menu ); } public function test_admin_bar_menu() { global $wp_post_types; $post_type = 'page'; $labels = $wp_post_types[$post_type]->labels; $_GET['page_type'] = 1; $this->menu->admin_bar_menu(); $this->assertSame( 'Add New Page', $labels->add_new_item ); $this->assertSame( 'Edit Page', $labels->edit_item ); $this->assertSame( 'View Page', $labels->view_item ); $_GET['page_type'] = 'faq-page-type'; $this->menu->admin_bar_menu(); $this->assertSame( 'Add New Page', $labels->add_new_item ); $this->assertSame( 'Edit Page', $labels->edit_item ); $this->assertSame( 'View Page', $labels->view_item ); $_GET['post_type'] = $post_type; $this->menu->admin_bar_menu(); $this->assertSame( 'Add New FAQ page', $labels->add_new_item ); $this->assertSame( 'Edit FAQ page', $labels->edit_item ); $this->assertSame( 'View FAQ page', $labels->view_item ); } public function test_admin_bar_menu_taxonomy() { global $wp_taxonomies; papi_test_register_faq_taxonomy(); $taxonomy = 'faq'; $labels = $wp_taxonomies[$taxonomy]->labels; $_GET['taxonomy'] = 1; $this->menu->admin_bar_menu(); $this->assertSame( 'Add New FAQ', $labels->add_new_item ); $this->assertSame( 'Edit FAQ', $labels->edit_item ); $this->assertSame( 'View FAQ', $labels->view_item ); $_GET['taxonomy'] = 'faq'; $_GET['entry_type'] = 'faq-taxonomy-type'; $this->menu->admin_bar_menu(); $this->assertSame( 'Add New FAQ taxonomy', $labels->add_new_item ); $this->assertSame( 'Edit FAQ taxonomy', $labels->edit_item ); $this->assertSame( 'View FAQ taxonomy', $labels->view_item ); } public function test_admin_bar_menu_2() { global $wp_post_types; $post_type = 'post'; $labels = $wp_post_types[$post_type]->labels; $_SERVER['REQUEST_URI'] = 'http://site.com/?page=papi/options/header-option-type'; $_GET['post_type'] = $post_type; $this->menu->admin_bar_menu(); $this->assertSame( 'Add New Post', $labels->add_new_item ); $this->assertSame( 'Edit Post', $labels->edit_item ); $this->assertSame( 'View Post', $labels->view_item ); $_SERVER['REQUEST_URI'] = ''; } public function test_page_items_menu() { $this->assertNull( $this->menu->page_items_menu() ); } public function test_post_types_menu() { global $submenu; $submenu = []; $submenu['edit.php'] = [ 5 => [ 'All Posts', 'edit_posts', 'edit.php' ], 10 => [ 'Add New', 'edit_posts', 'post-new.php' ] ]; $submenu['edit.php?post_type=page'] = [ 5 => [ 'All Pages', 'edit_pages', 'edit.php?post_type=page' ], 10 => [ 'Add New', 'edit_pages', 'post-new.php?post_type=page' ] ]; $this->assertNull( $this->menu->post_types_menu() ); $this->assertSame( 'post-new.php?page_type=post-page-type&post_type=post', $submenu['edit.php'][10][2] ); $this->assertSame( 'edit.php?post_type=page&page=papi-add-new-page,page', $submenu['edit.php?post_type=page'][10][2] ); } public function test_post_types_menu_2() { global $submenu; $submenu = []; $submenu['edit.php'] = [ 5 => [ 'All Posts', 'edit_posts', 'edit.php' ], 10 => [ 'Add New', 'edit_posts', 'post-new.php' ] ]; $submenu['edit.php?post_type=page'] = [ 5 => [ 'All Pages', 'edit_pages', 'edit.php?post_type=page' ], 10 => [ 'Add New', 'edit_pages', 'post-new.php?post_type=page' ] ]; $submenu['edit.php?post_type=book'] = [ 5 => [ 'All Pages', 'edit_pages', 'edit.php?post_type=book' ], 10 => [ 'Add New', 'edit_pages', 'post-new.php?post_type=book' ] ]; add_filter( 'papi/settings/only_page_type_post', function () { return 'post-page-type'; } ); add_filter( 'papi/settings/show_standard_page_type_hidden', '__return_true' ); papi_test_register_book_post_type(); papi_test_register_hidden_post_type(); $this->assertNull( $this->menu->post_types_menu() ); $this->assertSame( 'post-new.php?page_type=post-page-type&post_type=post', $submenu['edit.php'][10][2] ); $this->assertSame( 'edit.php?post_type=page&page=papi-add-new-page,page', $submenu['edit.php?post_type=page'][10][2] ); $this->assertSame( 'post-new.php?page_type=book-page-type&post_type=book', $submenu['edit.php?post_type=book'][10][2] ); $this->assertSame( 'edit.php?post_type=hidden&page=papi-add-new-page,hidden', $submenu['edit.php?post_type=hidden'][10][2] ); } public function test_post_types_menu_hidden_2() { global $submenu; $submenu = []; add_filter( 'papi/settings/only_page_type_hidden', function () { return 'hidden2-page-type'; } ); add_filter( 'papi/settings/show_standard_page_type_hidden', '__return_false' ); $this->assertNull( $this->menu->post_types_menu() ); $this->assertSame( 'post-new.php?page_type=hidden2-page-type&post_type=hidden', $submenu['edit.php?post_type=hidden'][10][2] ); } public function test_render_view() { $_GET['page'] = ''; $this->menu->render_view(); $this->expectOutputRegex( '/\Papi\s\-\s404\<\/h1\>/' ); $_GET['page'] = 'papi-add-new-page,page'; $this->menu->render_view(); $this->expectOutputRegex( '/Add New Page/' ); } public function test_setup_actions_admin() { global $current_screen; $this->assertNull( $current_screen ); $current_screen = WP_Screen::get( 'admin_init' ); $menu = new Papi_Admin_Menu(); $this->assertSame( 10, has_action( 'admin_init', [$menu, 'admin_bar_menu'] ) ); $this->assertSame( 10, has_action( 'admin_menu', [$menu, 'page_items_menu'] ) ); $this->assertSame( 10, has_action( 'admin_menu', [$menu, 'post_types_menu'] ) ); $current_screen = null; } public function test_setup_actions() { $this->assertSame( 10, has_action( 'admin_bar_menu', [$this->menu, 'admin_bar_menu'] ) ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-meta-box-tabs-test.php ================================================ tabs = [ papi_tab( [ 'title' => 'Content' ] ), papi_tab( [ 'title' => 'More', 'sort_order' => 1 ], [ papi_property( [ 'type' => 'string', 'title' => 'Name' ] ) ] ) ]; } public function tearDown() { parent::tearDown(); unset( $this->tabs ); } public function test_construct() { $class = new Papi_Admin_Meta_Box_Tabs(); $this->assertEmpty( $class->get_tabs() ); } public function test_papi_admin_meta_box_tab_class() { $class = new Papi_Admin_Meta_Box_Tabs( $this->tabs, false ); $tabs = $class->get_tabs(); $this->assertSame( 'More', $tabs[0]->title ); $this->assertSame( 1, $tabs[0]->sort_order ); $this->assertSame( 'string', $tabs[0]->properties[0]->type ); $this->assertSame( 'Name', $tabs[0]->properties[0]->title ); $this->assertSame( 'Content', $tabs[1]->title ); $this->assertSame( 1000, $tabs[1]->sort_order ); $this->assertEmpty( $tabs[1]->properties ); } public function test_render() { papi_render_properties( $this->tabs ); $this->expectOutputRegex( '/.*\S.*/' ); } public function test_tabs() { $this->assertSame( 'Content', $this->tabs[0]->title ); $this->assertEmpty( $this->tabs[0]->properties ); $this->assertSame( 'More', $this->tabs[1]->title ); $this->assertSame( 'string', $this->tabs[1]->properties[0]->type ); $this->assertSame( 'Name', $this->tabs[1]->properties[0]->title ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-meta-box-test.php ================================================ 'string', 'title' => 'Name' ] ); $class = new Papi_Admin_Meta_Box( new Papi_Core_Box( [], [$property] ) ); $properties = function ( Papi_Admin_Meta_Box $box ) { return $box->box->properties; }; $properties = Closure::bind( $properties, null, $class ); $this->assertSame( [$property], $properties( $class ) ); } public function test_after_title() { $box = new Papi_Core_Box( [ 'title' => 'Content' ] ); $class = new Papi_Admin_Meta_Box( $box ); $this->assertFalse( has_action( 'edit_form_after_title', [$class, 'move_meta_box_after_title'] ) ); $_GET['post_type'] = 'page'; $box = new Papi_Core_Box( [ 'context' => 'after_title', 'title' => 'Content' ] ); $class = new Papi_Admin_Meta_Box( $box ); $this->assertSame( 10, has_action( 'edit_form_after_title', [$class, 'move_meta_box_after_title'] ) ); unset( $_GET['post_type'] ); } public function test_admin_meta_box_construct() { $box = new Papi_Core_Box( [ 'title' => 'Content' ] ); $class = new Papi_Admin_Meta_Box( $box ); $class->setup_meta_box(); do_meta_boxes( '_papi_content', 'normal', null ); $this->expectOutputRegex( '//' ); } public function test_admin_meta_box_hidden_box() { $_GET['post_type'] = 'post'; $box = new Papi_Core_Box( [ 'title' => 'Hidden' ] ); $class = new Papi_Admin_Meta_Box( $box ); $this->assertSame( 10, has_action( 'add_meta_boxes', [$class, 'setup_meta_box'] ) ); $box = new Papi_Core_Box( [ 'title' => 'Hidden', 'display' => false ] ); $class = new Papi_Admin_Meta_Box( $box ); $this->assertFalse( has_action( 'add_meta_boxes', [$class, 'setup_meta_box'] ) ); } public function test_admin_meta_box_capabilities() { $box = new Papi_Core_Box( [ 'title' => 'Content', 'capabilities' => ['admin'] ] ); $class = new Papi_Admin_Meta_Box( $box ); $this->assertTrue( ! isset( $class->box ) ); } public function test_move_meta_box_after_title() { global $post, $wp_meta_boxes, $pagenow; $pagenow = 'post-new.php'; $post_id = $this->factory->post->create( [ 'post_type' => 'page' ] ); $post = get_post( $post_id ); $box = new Papi_Core_Box( [ 'title' => 'Content' ] ); $class = new Papi_Admin_Meta_Box( $box ); set_current_screen( $pagenow ); $class->move_meta_box_after_title(); $this->assertFalse( isset( $wp_meta_boxes['page']['normal'] ) ); $this->expectOutputRegex( '/.*\S.*/' ); $GLOBALS['current_screen'] = null; } public function test_meta_box_css_classes() { $box = new Papi_Core_Box; $class = new Papi_Admin_Meta_Box( $box ); $this->assertSame( ['papi-box'], $class->meta_box_css_classes( [] ) ); } public function test_render_meta_box() { $box = new Papi_Core_Box( [ 'title' => 'Content' ] ); $class = new Papi_Admin_Meta_Box( $box ); $this->assertNull( $class->render_meta_box( null, [] ) ); $property = papi_property( [ 'type' => 'string', 'title' => 'Name' ] ); $class->render_meta_box( null, [ 'args' => [$property] ] ); $this->expectOutputRegex( '/.*\S.*/' ); } public function test_required() { $property = papi_property( [ 'type' => 'string', 'title' => 'Name', 'required' => true ] ); $box = new Papi_Core_Box( [ 'title' => 'Content' ], [$property] ); $box->set_option( 'required', true ); $class = new Papi_Admin_Meta_Box( $box ); $class->setup_meta_box(); $title = function ( Papi_Admin_Meta_Box $box ) { return $box->get_title(); }; $title = Closure::bind( $title, null, $class ); $this->assertSame( sprintf( 'Content %s', $property->title, $property->slug, '(required field)' ), $title( $class ) ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-meta-handler-test.php ================================================ handler = new Papi_Admin_Meta_Handler; add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types', PAPI_FIXTURE_DIR . '/taxonomy-types']; } ); $this->term_id = $this->factory->term->create(); $this->post_id = $this->factory->post->create(); $_GET = []; $_GET['post'] = $this->post_id; update_post_meta( $this->post_id, papi_get_page_type_key(), 'properties-page-type' ); update_term_meta( $this->term_id, papi_get_page_type_key(), 'properties-taxonomy-type' ); $this->page_type = papi_get_entry_type_by_id( 'properties-page-type' ); $this->extra_page_type = papi_get_entry_type_by_id( 'extra-page-type' ); $this->taxonomy_type = papi_get_entry_type_by_id( 'properties-taxonomy-type' ); } public function tearDown() { parent::tearDown(); unset( $_GET, $_POST, $this->handler, $this->post_id, $this->term_id, $this->page_type, $this->extra_page_type, $this->taxonomy_type ); } public function test_actions() { $this->assertSame( 1, has_action( 'save_post', [$this->handler, 'save_meta_boxes'] ) ); $this->assertSame( 1, has_action( 'created_term', [$this->handler, 'save_meta_boxes'] ) ); $this->assertSame( 1, has_action( 'edit_term', [$this->handler, 'save_meta_boxes'] ) ); } public function test_save_meta_boxes() { $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $this->post_id; $this->handler->save_meta_boxes( $this->post_id, get_post( $this->post_id ) ); wp_set_current_user( 0 ); $this->assertSame( 'Hello, world!', papi_get_field( $this->post_id, $property->slug ) ); } public function test_save_meta_boxes_2() { $property = $this->page_type->get_property( 'bool_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'on' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $this->post_id; $this->handler->save_meta_boxes( $this->post_id, get_post( $this->post_id ) ); wp_set_current_user( 0 ); $this->assertTrue( papi_get_field( $this->post_id, $property->slug ) ); } public function test_save_meta_boxes_3() { $post_id = $this->factory->post->create(); $revs_id = wp_save_post_revision( $post_id ); $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $revs_id; $this->handler->save_meta_boxes( $revs_id, get_post( $revs_id ) ); wp_set_current_user( 0 ); $this->assertSame( 'Hello, world!', get_post_meta( $revs_id, unpapify( $property->slug ), true ) ); } /** * Autosave. */ public function test_save_meta_boxes_4() { $post_id = $this->factory->post->create(); $property = $this->page_type->get_property( 'string_test' ); $revs_id = wp_save_post_revision( $post_id ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['data'] = ['wp_autosave' => ['post_id' => $revs_id]]; $this->handler->save_meta_boxes( $post_id, get_post( $post_id ) ); wp_set_current_user( 0 ); $this->assertSame( 'Hello, world!', get_post_meta( $post_id, unpapify( $property->slug ), true ) ); } /** * Autosave draft. */ public function test_save_meta_boxes_5() { $post_id = $this->factory->post->create(); $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['data'] = ['wp_autosave' => ['post_id' => $post_id, 'auto_draft' => '1']]; $this->handler->save_meta_boxes( $post_id, get_post( $post_id ) ); wp_set_current_user( 0 ); $this->assertSame( 'Hello, world!', get_post_meta( $post_id, unpapify( $property->slug ), true ) ); } /** * @issue 126 */ public function test_save_meta_boxes_apostrophe() { $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => "I'm home" ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $this->post_id; $this->handler->save_meta_boxes( $this->post_id, get_post( $this->post_id ) ); wp_set_current_user( 0 ); $this->assertSame( "I'm home", papi_get_field( $this->post_id, $property->slug ) ); } /** * Wrong nonce. */ public function test_save_meta_boxes_fail_1() { $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = ''; $_POST['post_ID'] = $this->post_id; $this->handler->save_meta_boxes( $this->post_id, get_post( $this->post_id ) ); wp_set_current_user( 0 ); $this->assertNull( papi_get_field( $this->post_id, $property->slug ) ); } /** * Wrong post id. */ public function test_save_meta_boxes_fail_2() { $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $this->handler->save_meta_boxes( 0, null ); wp_set_current_user( 0 ); $this->assertNull( papi_get_field( $this->post_id, $property->slug ) ); } /** * Wrong capability. */ public function test_save_meta_boxes_fail_3() { $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'read' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $this->post_id; $this->handler->save_meta_boxes( $this->post_id, get_post( $this->post_id ) ); wp_set_current_user( 0 ); $this->assertNull( papi_get_field( $this->post_id, $property->slug ) ); } public function test_save_meta_boxes_fail_4() { $property = $this->page_type->get_property( 'bool_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => 'kvacker', 'value' => 'on' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $this->post_id; $this->handler->save_meta_boxes( $this->post_id, get_post( $this->post_id ) ); wp_set_current_user( 0 ); $this->assertNull( papi_get_field( $this->post_id, $property->slug ) ); } public function test_save_properties() { $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $this->handler->save_properties( $this->post_id ); $value = papi_get_field( $this->post_id, $property->slug ); $this->assertSame( 'Hello, world!', $value ); $property = $this->page_type->get_property( 'number_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 42 ], $_POST ); $this->handler->save_properties( 0 ); $value = papi_get_field( 0, $property->slug ); $this->assertNull( $value ); } public function test_pre_data() { $_POST = [ '_papi_item' => 'Item 42', '_papi_item_2' => '', '_papi_sections' => [ 0 => [ 'sort_order' => 'down' ] ] ]; $this->handler->save_properties( $this->post_id ); $this->assertSame( 'Item 42', get_post_meta( $this->post_id, '_papi_item', true ) ); $this->assertEmpty( get_post_meta( $this->post_id, '_papi_item_2', true ) ); $this->assertSame( 'down', get_post_meta( $this->post_id, '_papi_sections_0_sort_order', true ) ); } public function test_overwrite() { $post_id = $this->factory->post->create(); $property = $this->extra_page_type->get_property( 'post_content' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $_GET['post'] = $post_id; update_post_meta( $post_id, papi_get_page_type_key(), 'extra-page-type' ); $this->handler->save_properties( $post_id ); $this->flush_cache(); $value = papi_get_field( $post_id, $property->slug ); $this->assertSame( '

Hello, world!

', trim( $value ) ); $this->flush_cache(); $post = get_post( $post_id ); $this->assertSame( 'Hello, world!', trim( $post->post_content ) ); } public function test_save_meta_boxes_taxonomy() { $property = $this->taxonomy_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['term_id'] = $this->term_id; $_GET['meta_type'] = 'term'; $this->handler->save_meta_boxes( $this->term_id ); wp_set_current_user( 0 ); $this->assertSame( 'Hello, world!', papi_get_term_field( $this->term_id, $property->slug ) ); } /** * Wrong nonce. */ public function test_save_meta_boxes_taxonomy_fail_1() { $property = $this->taxonomy_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = ''; $_POST['term_id'] = $this->term_id; $_GET['meta_type'] = 'term'; $this->handler->save_meta_boxes( $this->term_id ); wp_set_current_user( 0 ); $this->assertNull( papi_get_term_field( $this->term_id, $property->slug ) ); } /** * Wrong term id. */ public function test_save_meta_boxes_taxonomy_fail_2() { $property = $this->taxonomy_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_GET['meta_type'] = 'term'; $this->handler->save_meta_boxes( 0, null ); wp_set_current_user( 0 ); $this->assertNull( papi_get_field( $this->term_id, $property->slug ) ); } /** * Wrong capability. */ public function test_save_meta_boxes_taxonomy_fail_3() { $property = $this->taxonomy_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'read' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['term_id'] = $this->term_id; $_GET['meta_type'] = 'term'; $this->handler->save_meta_boxes( $this->term_id ); wp_set_current_user( 0 ); $this->assertNull( papi_get_term_field( $this->term_id, $property->slug ) ); } public function test_restore_post_revision() { $post_id = $this->factory->post->create(); update_post_meta( $post_id, papi_get_page_type_key(), 'properties-page-type' ); $revs_id = wp_save_post_revision( $post_id ); $property = $this->page_type->get_property( 'string_test' ); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => 'Hello, world!' ], $_POST ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST['post_ID'] = $revs_id; $_POST[papi_get_page_type_key()] = 'properties-page-type'; $this->handler->save_meta_boxes( $revs_id, get_post( $revs_id ) ); wp_set_current_user( 0 ); $this->assertSame( 'Hello, world!', get_post_meta( $revs_id, unpapify( $property->slug ), true ) ); $this->handler->restore_post_revision( $post_id, $revs_id ); $this->assertSame( 'Hello, world!', get_post_meta( $post_id, unpapify( $property->slug ), true ) ); } public function test_save_revision() { $post_id = $this->factory->post->create(); update_post_meta( $post_id, papi_get_page_type_key(), 'properties-page-type' ); $revs_id = wp_save_post_revision( $post_id ); $property = $this->page_type->get_property( 'string_test' ); update_post_meta( $post_id, 'string_test', 'Hello, world!' ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $this->handler->save_revision( $revs_id ); $this->assertSame( 'Hello, world!', get_post_meta( $revs_id, 'string_test', true ) ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-option-handler-test.php ================================================ page_type = papi_get_entry_type_by_id( 'options/header-option-type' ); $this->property = $this->page_type->get_property( 'name' ); } public function tearDown() { parent::tearDown(); remove_filter( 'papi/is_admin', '__return_true' ); unset( $_POST, $_SERVER['REQUEST_METHOD'], $this->handler, $this->property, $this->page_type ); } public function test_actions() { $handler = new Papi_Admin_Option_Handler; $this->assertGreaterThan( 0, has_action( 'admin_init', [$handler, 'save_properties'] ) ); } public function test_save_options_without_nonce() { $_POST = papi_test_create_property_post_data( [ 'slug' => $this->property->slug, 'type' => $this->property, 'value' => 'Hello, world!' ], $_POST ); $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REQUEST_URI'] = 'http://site.com/wp-admin/options-general.php?page=papi/options/header-option-type'; ( new Papi_Admin_Option_Handler )->save_properties(); $this->assertNull( papi_get_option( $this->property->slug ) ); } public function test_save_options_with_nonce() { $_POST = papi_test_create_property_post_data( [ 'slug' => $this->property->slug, 'type' => $this->property, 'value' => 'Hello, world!' ], $_POST ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REQUEST_URI'] = 'http://site.com/wp-admin/options-general.php?page=papi/options/header-option-type'; ( new Papi_Admin_Option_Handler )->save_properties(); $this->assertSame( 'Hello, world!', papi_get_option( $this->property->slug ) ); } public function test_save_properties_fail() { $_POST = papi_test_create_property_post_data( [ 'slug' => $this->property->slug, 'type' => $this->property, 'value' => 'Hello, world!' ], $_POST ); $old_request_uri = $_SERVER['REQUEST_URI']; $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REQUEST_URI'] = 'http://site.com/wp-admin/options-general.php?page=papi/options/header-option-type'; ( new Papi_Admin_Option_Handler )->save_properties(); $_SERVER['REQUEST_URI'] = $old_request_uri; $this->assertNull( papi_get_option( $this->property->slug ) ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-page-type-switcher.php ================================================ admin_init(); $this->assertSame( 10, has_action( 'post_submitbox_misc_actions', [$switcher, 'metabox'] ) ); $this->assertSame( 10, has_action( 'save_post', [$switcher, 'save_post'] ) ); } public function test_metabox_1() { $switcher = new Papi_Admin_Page_Type_Switcher; $switcher->metabox(); $this->expectOutputRegex( '//' ); } public function test_metabox_2() { $switcher = new Papi_Admin_Page_Type_Switcher; $_GET = [ 'post_type' => 'page', 'page_type' => 'properties-page-type' ]; $switcher->metabox(); $this->expectOutputRegex( '/\
factory->post->create( ['post_type' => 'page'] ); $post = get_post( $post_id ); $_POST = []; // Bad values. $this->assertFalse( $switcher->save_post( 0, null ) ); $this->assertFalse( $switcher->save_post( 0, null ) ); // Nonce check. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); // Empty post values. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key()] = 'properties-page-type'; $_POST[papi_get_page_type_key( 'switch' )] = 'properties-page-type'; // Same post type ids. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key()] = 'properties-page-type'; $_POST[papi_get_page_type_key( 'switch' )] = 'no-existing-page-type'; // Bad page type and post type objects. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key( 'switch' )] = 'post-page-type'; $_POST['post_type'] = 'page'; // Bad post type. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key( 'switch' )] = 'display-not-page-type'; // Bad capabilities. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key( 'switch' )] = 'simple-page-type'; // Bad capabilities. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); update_post_meta( $post_id, papi_get_page_type_key(), 'properties-page-type' ); update_post_meta( $post_id, 'string_test', 'Fredrik' ); update_post_meta( $post_id, 'hidden_test', 'Fredrik' ); $this->assertSame( 'Fredrik', papi_get_field( $post_id, 'string_test' ) ); $this->assertSame( 'Fredrik', papi_get_field( $post_id, 'hidden_test' ) ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); // Create new nonce because of new user. $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST[papi_get_page_type_key( 'switch' )] = 'simple-page-type'; // Success! $this->assertTrue( $switcher->save_post( $post_id, $post ) ); $this->assertSame( 'Fredrik', papi_get_field( $post_id, 'string_test' ) ); $this->assertNull( papi_get_field( $post_id, 'hidden_test' ) ); wp_set_current_user( 0 ); } public function test_save_post_standard_type() { $switcher = new Papi_Admin_Page_Type_Switcher; $post_id = $this->factory->post->create( ['post_type' => 'page'] ); $post = get_post( $post_id ); $_POST = []; // Bad values. $this->assertFalse( $switcher->save_post( 0, null ) ); $this->assertFalse( $switcher->save_post( 0, null ) ); // Nonce check. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); // Empty post values. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key()] = 'properties-page-type'; $_POST[papi_get_page_type_key( 'switch' )] = papi_get_standard_page_type_id( $post->post_type ); // Same post type ids. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key()] = 'properties-page-type'; $_POST[papi_get_page_type_key( 'switch' )] = papi_get_standard_page_type_id( $post->post_type ); // Bad page type and post type objects. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key( 'switch' )] = 'post-page-type'; $_POST['post_type'] = 'page'; // Bad post type. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key( 'switch' )] = papi_get_standard_page_type_id( $post->post_type ); // Bad capabilities. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $_POST[papi_get_page_type_key( 'switch' )] = papi_get_standard_page_type_id( $post->post_type ); // Bad capabilities. $this->assertFalse( $switcher->save_post( $post_id, $post ) ); update_post_meta( $post_id, papi_get_page_type_key(), 'properties-page-type' ); update_post_meta( $post_id, 'string_test', 'Fredrik' ); update_post_meta( $post_id, 'hidden_test', 'Fredrik' ); $this->assertSame( 'Fredrik', papi_get_field( $post_id, 'string_test' ) ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); // Create new nonce because of new user. $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $_POST[papi_get_page_type_key( 'switch' )] = papi_get_standard_page_type_id( $post->post_type ); // Success! $this->assertTrue( $switcher->save_post( $post_id, $post ) ); $this->assertEmpty( papi_get_field( $post_id, 'string_test' ) ); wp_set_current_user( 0 ); } public function test_save_post_revision() { $switcher = new Papi_Admin_Page_Type_Switcher; $post_id = $this->factory->post->create( ['post_type' => 'revision'] ); $post = get_post( $post_id ); $_POST = []; $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['post_type'] = 'page'; $_POST[papi_get_page_type_key( 'switch' )] = 'simple-page-type'; $_POST[papi_get_page_type_key()] = 'properties-page-type'; $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $this->assertFalse( $switcher->save_post( $post_id, $post ) ); $post_id = $this->factory->post->create( ['post_type' => 'revision', 'post_parent' => $post_id] ); $post = get_post( $post_id ); $this->assertFalse( $switcher->save_post( $post_id, $post ) ); } public function test_save_post_autosave() { $switcher = new Papi_Admin_Page_Type_Switcher; $post_id = $this->factory->post->create( ['post_type' => 'page'] ); $post = get_post( $post_id ); $_POST = []; $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $_POST['post_type'] = 'page'; $_POST[papi_get_page_type_key( 'switch' )] = 'simple-page-type'; $_POST[papi_get_page_type_key()] = 'properties-page-type'; $_POST['papi_meta_nonce'] = wp_create_nonce( 'papi_save_data' ); $post_id = $this->factory->post->create( ['post_type' => 'revision', 'post_parent' => $post_id, 'post_name' => $post_id . '-autosave'] ); $post = get_post( $post_id ); $this->assertFalse( $switcher->save_post( $post_id, $post ) ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-test.php ================================================ admin = new Papi_Admin; $this->post_id = $this->factory->post->create( [ 'post_type' => 'page' ] ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); } public function tearDown() { parent::tearDown(); unset( $this->admin, $this->post_id, $_GET ); } public function register_template_paths( $new_templates ) { $cache_key = 'page_templates-' . md5( get_theme_root() . '/' . get_stylesheet() ); $templates = wp_get_theme()->get_page_templates(); if ( empty( $templates ) ) { $templates = []; } wp_cache_delete( $cache_key , 'themes' ); $templates = array_merge( $templates, $new_templates ); wp_cache_add( $cache_key, $templates, 'themes', 1800 ); return $new_templates; } public function test_admin_body_class() { papi()->reset(); $_GET['post'] = $this->factory->post->create(); $_GET['post_type'] = 'page'; $_GET['page'] = 'papi/page/simple-page-type'; $classes = $this->admin->admin_body_class( '' ); $this->assertTrue( (bool) preg_match( '/\spapi\-body papi\-meta\-type\-post/', $classes ) ); } public function test_admin_body_class_with_entry_type_body_classes() { papi()->reset(); $_GET['post'] = $this->factory->post->create(); $_GET['post_type'] = 'page'; $_GET['page'] = 'papi/page/simple-page-type'; $admin = new Papi_Admin; $classes = $admin->admin_body_class( '' ); $this->assertTrue( (bool) preg_match( '/\ssimple\-page\-type/', $classes ) ); } public function test_admin_init() { $admin = new Papi_Admin; $this->assertNull( $admin->admin_init() ); $_GET['post'] = $this->factory->post->create(); $_GET['post_type'] = 'page'; $_GET['page'] = 'papi/page/simple-page-type'; $admin = new Papi_Admin; $admin->admin_init(); } public function test_edit_form_after_title() { $this->admin->edit_form_after_title(); $this->expectOutputRegex( '/papi\_meta\_nonce/' ); } public function test_edit_form_after_title_2() { $_GET['entry_type'] = 'test'; $this->admin->edit_form_after_title(); $this->expectOutputRegex( '/name\=\"\_papi\_page\_type\"/' ); } public function test_plugin_row_meta() { $output = $this->admin->plugin_row_meta( [], 'fake/fake.php' ); $this->assertEmpty( $output ); $testroot = basename( dirname( PAPI_PLUGIN_DIR ) ); $output = $this->admin->plugin_row_meta( [], $testroot . '/papi-loader.php' ); $this->assertArrayHasKey( 'docs', $output ); } public function test_setup_actions() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); $admin = new Papi_Admin; $this->assertSame( 10, has_action( 'admin_init', [$admin, 'admin_init'] ) ); $_GET['taxonomy'] = 'post_tag'; $admin = new Papi_Admin; $this->assertSame( 10, has_action( 'post_tag_add_form', [$admin, 'edit_form_after_title'] ) ); $this->assertSame( 10, has_action( 'post_tag_edit_form', [$admin, 'edit_form_after_title'] ) ); $current_screen = null; } public function test_setup_filters() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); $admin = new Papi_Admin; $this->assertSame( 10, has_filter( 'admin_body_class', [$admin, 'admin_body_class'] ) ); $current_screen = null; } public function test_update_front_page() { $admin = new Papi_Admin; papi_set_page_type_id( $this->post_id, 'book-page-type' ); $admin->update_front_page( $this->post_id, 'page_on_front' ); $this->assertSame( 'front-page-type', papi_get_page_type_id( $this->post_id ) ); } public function test_wp_link_query() { $admin = new Papi_Admin; $post = [ 'ID' => $this->post_id, 'info' => 'Page' ]; $post2 = [ 'ID' => $this->post_id, 'info' => 'Standard Page' ]; $results = $admin->wp_link_query( [$post] ); $this->assertSame( [$post2], $results ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); $post3 = [ 'ID' => $this->post_id, 'info' => 'Simple page' ]; $results = $admin->wp_link_query( [$post] ); $this->assertSame( [$post3], $results ); } public function test_wp_refresh_nonces() { $admin = new Papi_Admin; $arr = []; $this->assertEmpty( $admin->wp_refresh_nonces( $arr ) ); $arr = [ 'wp-refresh-post-nonces' => [ 'replace' => [] ] ]; $arr2 = $admin->wp_refresh_nonces( $arr ); $this->assertArrayHasKey( 'papi_meta_nonce', $arr2['wp-refresh-post-nonces']['replace'] ); } } ================================================ FILE: tests/cases/admin/class-papi-admin-view-test.php ================================================ view = new Papi_Admin_View(); } public function tearDown() { unset( $this->view ); } public function test_exists() { $this->assertFalse( $this->view->exists( 'empty' ) ); $this->assertTrue( $this->view->exists( 'add-new-page' ) ); } public function test_render() { $this->view->render( 'add-new-page' ); $this->expectOutputRegex( '/.*\S.*/' ); } } ================================================ FILE: tests/cases/core/class-papi-conditional-rules-test.php ================================================ post_id = $this->factory->post->create(); $_GET = []; $_GET['post'] = $this->post_id; update_post_meta( $this->post_id, papi_get_page_type_key(), 'rule-page-type' ); } public function tearDown() { parent::tearDown(); unset( $this->post_id, $_GET ); } private function save_properties( $property ) { $handler = new Papi_Admin_Meta_Handler(); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => $property->value ], $_POST ); $handler->save_properties( $this->post_id ); } public function test_rule_equal_option() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); $_SERVER['REQUEST_URI'] = 'http://site.com/?page=papi/options/header-option-type'; $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT EXISTS', 'slug' => 'name' ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'name', 'value' => '' ] ); $this->assertFalse( $result ); update_option( 'name', 'Fredrik' ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->assertTrue( $result ); $_SERVER['REQUEST_URI'] = ''; $current_screen = null; } public function test_rule_equal() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'value' => 'Fredrik' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'name', 'value' => '' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->assertTrue( $result ); $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1.1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'number', 'value' => 1.1 ] ); $this->assertTrue( $result ); } public function test_rule_equal_bool_true() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'value' => 'true' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'name', 'value' => true ] ); $this->assertTrue( $result ); } public function test_rule_equal_bool_false() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'value' => 'false' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '=', 'slug' => 'name', 'value' => false ] ); $this->assertTrue( $result ); } public function test_rule_not_equal() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '!=', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '!=', 'slug' => 'name', 'value' => '' ] ); $this->assertTrue( $result ); } public function test_rule_not_equal_bool_true() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'value' => 'false' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '!=', 'slug' => 'name', 'value' => true ] ); $this->assertTrue( $result ); } public function test_rule_not_equal_bool_false() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'value' => 'true' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '!=', 'slug' => 'name', 'value' => false ] ); $this->assertTrue( $result ); } public function test_rule_greater_then() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>', 'slug' => 'fake', 'value' => 1 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>', 'slug' => 'number', 'value' => 1 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>', 'slug' => 'number', 'value' => '1.1' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>', 'slug' => 'number', 'value' => 0 ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>', 'slug' => 'number', 'value' => '0.9' ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>', 'slug' => 'number', 'source' => [1, 2], 'value' => 1 ] ); $this->assertTrue( $result ); } public function test_rule_greater_then_or_equal() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>=', 'slug' => 'fake', 'value' => 1 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>=', 'slug' => 'number', 'value' => 1 ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>=', 'slug' => 'number', 'value' => 0 ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>=', 'slug' => 'number', 'value' => '0' ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '>=', 'slug' => 'number', 'source' => [1, 2], 'value' => 2 ] ); $this->assertTrue( $result ); } public function test_rule_less_then() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<', 'slug' => 'fake', 'value' => 1 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<', 'slug' => 'number', 'value' => 1 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<', 'slug' => 'number', 'value' => 2 ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<', 'slug' => 'number', 'source' => [1, 2], 'value' => 3 ] ); $this->assertTrue( $result ); } public function test_rule_less_then_or_equal() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<=', 'slug' => 'fake', 'value' => 1 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<=', 'slug' => 'number', 'value' => 1 ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<=', 'slug' => 'number', 'value' => 2 ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => '<=', 'slug' => 'number', 'source' => [1, 2], 'value' => 2 ] ); $this->assertTrue( $result ); } public function test_rule_in() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'IN', 'slug' => 'number', 'value' => 10 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'IN', 'slug' => 'number', 'value' => [10, 20] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'IN', 'slug' => 'number', 'value' => [1, 2] ] ); $this->assertTrue( $result ); } public function test_rule_not_in() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT IN', 'slug' => 'number', 'value' => 10 ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT IN', 'slug' => 'number', 'value' => [1, 2] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT IN', 'slug' => 'number', 'value' => [1, null] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT IN', 'slug' => 'number', 'value' => [10, 20] ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT IN', 'slug' => 'number', 'value' => ['10', '20'] ] ); $this->assertTrue( $result ); } public function test_rule_like() { $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'LIKE', 'slug' => 'name', 'value' => 'Elli' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'LIKE', 'slug' => 'number', 'value' => '' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'LIKE', 'slug' => 'name', 'value' => 'rik' ] ); $this->assertTrue( $result ); $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'slug' => 'name2', 'value' => 124 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'LIKE', 'slug' => 'name2', 'value' => 1 ] ); $this->assertTrue( $result ); } public function test_rule_between() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'BETWEEN', 'slug' => 'number', 'value' => '' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'BETWEEN', 'slug' => 'number', 'value' => [10, 20] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'BETWEEN', 'slug' => 'number', 'value' => ['10', '20'] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'BETWEEN', 'slug' => 'number', 'value' => [1, null] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'BETWEEN', 'slug' => 'number', 'value' => [0, 2] ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'BETWEEN', 'slug' => 'number', 'value' => ['0', '2'] ] ); $this->assertTrue( $result ); } public function test_rule_not_between() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => '' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => [1, 2] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => ['0', '2'] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => [1, null] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => [0, 2] ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => ['10', '20'] ] ); $this->assertTrue( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT BETWEEN', 'slug' => 'number', 'value' => [10, 20] ] ); $this->assertTrue( $result ); } public function test_rule_exists() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'EXISTS', 'slug' => 'fake' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'EXISTS', 'slug' => 'number' ] ); $this->assertTrue( $result ); } public function test_rule_not_exists() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT EXISTS', 'slug' => 'number' ] ); $this->assertFalse( $result ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT EXISTS', 'slug' => 'fake' ] ); $this->assertTrue( $result ); } public function test_rule_empty() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'EMPTY', 'slug' => 'number' ] ); $this->assertTrue( $result ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'EMPTY', 'slug' => 'number' ] ); $this->assertFalse( $result ); } public function test_rule_not_empty() { $property = papi_property( [ 'title' => 'Number', 'type' => 'number', 'slug' => 'number', 'value' => 1 ] ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT EMPTY', 'slug' => 'number' ] ); $this->assertFalse( $result ); $this->save_properties( $property ); $result = papi_filter_conditional_rule_allowed( [ 'operator' => 'NOT EMPTY', 'slug' => 'number' ] ); $this->assertTrue( $result ); } public function test_setup_filters() { $rules = new Papi_Core_Conditional_Rules(); $this->assertNull( $rules->setup_filters() ); } } ================================================ FILE: tests/cases/core/class-papi-core-box-test.php ================================================ assertNull( $box->get_option( 'empty' ) ); } public function test_option_value() { $box = new Papi_Core_Box; $box->set_option( 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', $box->get_option( 'name' ) ); } public function test_options() { $box = new Papi_Core_Box( [ 'title' => 'Box' ] ); $this->assertSame( 'Box', $box->title ); $this->assertSame( '_papi_box', $box->id ); } public function test_excluded_options() { $box = new Papi_Core_Box( [ 'title' => 'Box', 'options' => null, 'properties' => null, ] ); $this->assertSame( 'Box', $box->title ); $this->assertSame( '_papi_box', $box->id ); $this->assertSame( [], $box->properties ); } } ================================================ FILE: tests/cases/core/class-papi-core-conditional-rule-test.php ================================================ rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'name', 'source' => 'Elli', 'value' => 'Fredrik' ] ); } public function tearDown() { parent::tearDown(); unset( $this->rule ); } public function test_operator() { $this->assertSame( '=', $this->rule->operator ); } public function test_slug() { $this->assertSame( 'papi_name', $this->rule->slug ); } public function test_source() { $this->assertSame( 'Elli', $this->rule->get_source() ); } public function test_source_callable_failied() { $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'numbers', 'source' => [new stdClass, 'fake'] ] ); $this->assertEmpty( $rule->get_source() ); $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'numbers', 'source' => [$this, 'fake'] ] ); $this->assertEmpty( $rule->get_source() ); $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'numbers', 'source' => '#source_callable' ] ); $this->assertSame( '#source_callable', $rule->get_source() ); } public function test_source_callable() { $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'numbers', 'source' => [$this, 'source_callable'] ] ); $this->assertSame( [1, 2], $rule->get_source() ); $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'name', 'source' => [$this, 'source_callable'] ] ); $this->assertSame( 'Fredrik', $rule->get_source() ); $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'numbers', 'source' => 'source_callable' ] ); $this->assertSame( [1, 2], $rule->get_source() ); $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'name', 'source' => 'source_callable' ] ); $this->assertSame( 'Fredrik', $rule->get_source() ); } public function test_source_closure() { $rule = new Papi_Core_Conditional_Rule( [ 'operator' => '=', 'slug' => 'numbers', 'source' => function ( $slug ) { if ( $slug === 'papi_numbers' ) { return [1, 2]; } else { return 'Fredrik'; } } ] ); $this->assertEmpty( $rule->get_source() ); } public function source_callable( $slug ) { if ( $slug === 'papi_numbers' ) { return [1, 2]; } else { return 'Fredrik'; } } public function test_value() { $this->assertSame( 'Fredrik', $this->rule->value ); } } function source_callable( $slug ) { if ( $slug === 'papi_numbers' ) { return [1, 2]; } else { return 'Fredrik'; } } ================================================ FILE: tests/cases/core/class-papi-core-conditional-test.php ================================================ conditional = new Papi_Core_Conditional(); } public function tearDown() { parent::tearDown(); unset( $this->conditional, $_GET ); } public function test_failed_display() { $result = $this->conditional->display( [ [ 'operator' => '=', 'slug' => 'fake', 'value' => '' ] ] ); $this->assertFalse( $result ); $result = $this->conditional->display( [ 'relation' => 'AND', [ 'operator' => '=', 'slug' => 'fake', 'value' => '' ], ] ); $this->assertFalse( $result ); $result = $this->conditional->display( [ [ 'operator' => '=', 'slug' => 'fake', 'value' => '' ], false, null ] ); $this->assertFalse( $result ); $result = $this->conditional->display( [ 'relation' => 'AND', [ 'operator' => '=', 'slug' => 'fake', 'value' => '' ], false, null ] ); $this->assertFalse( $result ); } public function test_success_display() { $result = $this->conditional->display( [] ); $this->assertTrue( $result ); $result = $this->conditional->display( [null] ); $this->assertTrue( $result ); $result = $this->conditional->display( [true] ); $this->assertTrue( $result ); $result = $this->conditional->display( [false] ); $this->assertTrue( $result ); $result = $this->conditional->display( ['hello'] ); $this->assertTrue( $result ); $result = $this->conditional->display( [ (object) []] ); $this->assertTrue( $result ); $result = $this->conditional->display( [ 'relation' => 'nil', [ (object) [] ] ] ); $this->assertTrue( $result ); } public function test_custom_display() { add_filter( 'papi/conditional/rule/==', function ( $rule ) { return $rule->value === 'hello'; } ); $result = $this->conditional->display( [ [ 'operator' => '==', 'slug' => 'fake', 'value' => '' ] ] ); $this->assertFalse( $result ); $result = $this->conditional->display( [ [ 'operator' => '==', 'slug' => 'fake', 'value' => 'hello' ] ] ); $this->assertTrue( $result ); add_filter( 'papi/conditional/rule/===', function ( $rule ) { return null; } ); $result = $this->conditional->display( [ [ 'operator' => '===', 'slug' => 'fake', 'value' => '' ] ] ); $this->assertFalse( $result ); } public function test_display_with_simple_slug() { add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); $post_id = $this->factory->post->create(); $_GET['post'] = $post_id; update_post_meta( $post_id, papi_get_page_type_key(), 'simple-page-type' ); $result = $this->conditional->display( [ [ 'operator' => 'NOT EXISTS', 'slug' => 'name', 'value' => '' ] ] ); $this->assertTrue( $result ); $property = papi_property( [ 'title' => 'Name', 'type' => 'string', 'value' => 'Fredrik' ] ); $handler = new Papi_Admin_Meta_Handler(); $_POST = papi_test_create_property_post_data( [ 'slug' => $property->slug, 'type' => $property, 'value' => $property->value ], $_POST ); $handler->save_properties( $post_id ); $result = $this->conditional->display( [ [ 'operator' => 'EXISTS', 'slug' => 'name', 'value' => '' ] ] ); $this->assertTrue( $result ); $result = $this->conditional->display( [ [ 'operator' => '=', 'slug' => 'name', 'value' => 'Fredrik' ] ] ); $this->assertTrue( $result ); } public function test_display_with_array_slug() { add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); $post_id = $this->factory->post->create(); $_GET['post'] = $post_id; update_post_meta( $post_id, papi_get_page_type_key(), 'simple-page-type' ); $simple_page_type = papi_get_entry_type_by_id( 'simple-page-type' ); $sections_prop = $simple_page_type->get_property( 'sections' ); $title_prop = $simple_page_type->get_property( 'sections[0][title]' ); $title_prop2 = clone $title_prop->get_options(); $title_prop3 = clone $title_prop->get_options(); $title_prop2 = Papi_Property::factory( $title_prop2 ); $title_prop2->slug = $sections_prop->html_name( $title_prop, 0 ); $title_prop3 = Papi_Property::factory( $title_prop3 ); $title_prop3->slug = $sections_prop->html_name( $title_prop, 0 ); $title_prop3->slug = str_replace( 'title', 'name', $title_prop3->slug ); $result = $this->conditional->display( [ [ 'operator' => 'NOT EXISTS', 'slug' => 'title', 'value' => '' ] ], $title_prop ); $this->assertTrue( $result ); $result = $this->conditional->display( [ [ 'operator' => 'NOT EXISTS', 'slug' => 'title', 'value' => '' ] ], $title_prop2 ); $this->assertTrue( $result ); $result = $this->conditional->display( [ [ 'operator' => 'NOT EXISTS', 'slug' => 'sections.0.title', 'value' => '' ] ] ); $this->assertTrue( $result ); $result = $this->conditional->display( [ [ 'operator' => 'NOT EXISTS', 'slug' => 'name', 'value' => '' ] ], $title_prop3 ); $this->assertTrue( $result ); $value_slug1 = $title_prop->get_slug( true ); $value_type_slug1 = papi_get_property_type_key( $value_slug1 ); $item = []; $item[$value_slug1] = 'Hello, world!'; $item[$value_type_slug1] = $title_prop; $handler = new Papi_Admin_Meta_Handler(); $_POST = papi_test_create_property_post_data( [ 'slug' => $sections_prop->slug, 'type' => $sections_prop, 'value' => [$item] ], $_POST ); $handler->save_properties( $post_id ); $result = $this->conditional->display( [ [ 'operator' => 'EXISTS', 'slug' => 'title', 'value' => '' ] ], $title_prop2 ); $this->assertTrue( $result ); $result = $this->conditional->display( [ [ 'operator' => 'EXISTS', 'slug' => 'sections.0.title', 'value' => '' ] ] ); $this->assertTrue( $result ); $result = $this->conditional->display( [ [ 'operator' => '=', 'slug' => 'sections.0.title', 'value' => 'Hello, world!' ] ] ); $this->assertTrue( $result ); } } ================================================ FILE: tests/cases/core/class-papi-core-container-test.php ================================================ container = new Papi_Core_Container; } public function tearDown() { parent::tearDown(); unset( $this->container ); } public function test_make_not_defined() { $this->setExpectedException( 'Exception', 'Identifier `fredrik` is not defined' ); $this->container->make( 'fredrik' ); } public function test_bind() { $this->container->bind( 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', $this->container->make( 'name' ) ); } public function test_closure() { $this->container->bind( 'num', 123 ); $this->container->bind( 'num2', function ( $c ) { return $c->make( 'num' ); } ); $this->container->bind( 'num3', function ( $c ) { return $c->make( 'num2' ); } ); $this->assertSame( 123, $this->container->make( 'num2' ) ); $this->assertSame( 123, $this->container->make( 'num3' ) ); } public function test_closure_injection() { $this->container->bind( 'num', 123 ); $this->container->bind( 'num2', function ( Papi_Core_Container $c ) { return $c->make( 'num' ); } ); $this->container->bind( 'num3', function ( Papi_Core_Container $c, $num ) { return $c->make( 'num2' ) + $num; } ); $this->assertSame( 123, $this->container->make( 'num2' ) ); $this->assertSame( 124, $this->container->make( 'num3', [1] ) ); require_once PAPI_FIXTURE_DIR . '/container/class-container-test-stub.php'; $this->container->bind( new \Papi\Tests\Fixtures\Container\Container_Test_Stub ); $this->container->bind( 'test-class', function ( \Papi\Tests\Fixtures\Container\Container_Test_Stub $test ) { return $test->value(); } ); $this->assertSame( 'Test class', $this->container->make( 'test-class' ) ); } public function test_exists() { $this->container->bind( 'name', 'Fredrik' ); $this->assertTrue( $this->container->exists( 'name' ) ); } public function test_once() { $this->assertNull( $this->container->once( null, null ) ); $this->container->once( 'Once', function () { return 'App'; } ); $this->assertSame( 'App', $this->container->make( 'Once' ) ); try { $this->container->once( 'Once', function () { return 'App'; } ); } catch ( \Exception $e ) { $this->assertNotEmpty( $e->getMessage() ); } } public function test_remove() { $this->container['plugin'] = 'Papi'; $this->container->remove( 'plugin' ); $this->assertFalse( isset( $this->container['plugin'] ) ); } public function test_reset() { $this->container['plugin'] = 'Papi'; $this->container['wp'] = true; $this->container->reset(); $this->assertFalse( isset( $this->container['plugin'] ) ); $this->assertFalse( isset( $this->container['wp'] ) ); } public function test_singleton() { $this->container->singleton( 'Singleton', 'App' ); $this->assertSame( 'App', $this->container->make( 'Singleton' ) ); try { $this->container->bind( 'Singleton', 'App' ); } catch ( \Exception $e ) { $this->assertNotEmpty( $e->getMessage() ); } try { $this->container->singleton( 'Singleton', 'App' ); } catch ( \Exception $e ) { $this->assertNotEmpty( $e->getMessage() ); } $this->assertSame( 'App', $this->container->make( 'Singleton' ) ); $this->assertTrue( $this->container->is_singleton( 'Singleton' ) ); try { $this->container->is_singleton( true ); } catch ( \Exception $e ) { $this->assertSame( 'Invalid argument. Must be string.', $e->getMessage() ); } } public function test_offset_exists() { $this->container->bind( 'name', 'Fredrik' ); $this->assertTrue( isset( $this->container['name'] ) ); } public function test_offset_get() { $this->container->bind( 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', $this->container['name'] ); } public function test_offset_set() { $this->container['plugin'] = 'Papi'; $this->assertSame( 'Papi', $this->container['plugin'] ); } public function test_offset_unset() { $this->container['plugin'] = 'Papi'; unset( $this->container['plugin'] ); $this->assertFalse( isset( $this->container['plugin'] ) ); } } ================================================ FILE: tests/cases/core/class-papi-core-data-test.php ================================================ post_id = $this->factory->post->create(); $this->term_id = $this->factory->term->create(); } public function tearDown() { parent::tearDown(); unset( $this->post_id, $this->term_id ); } public function test_delete() { $data = new Papi_Core_Data(); $this->assertFalse( $data->delete( $this->post_id, 'random223-page-type' ) ); update_post_meta( $this->post_id, 'random223-page-type', 'post' ); $this->assertTrue( $data->delete( $this->post_id, 'random223-page-type' ) ); update_post_meta( $this->post_id, 'random223-page-type', 'post' ); $this->assertTrue( $data->delete( $this->post_id, 'papi_random223-page-type' ) ); } public function test_delete_option() { $data = new Papi_Core_Data( 'option' ); $this->assertFalse( $data->delete( $this->post_id, 'random223-page-type' ) ); update_option( 'random223-page-type', 'option' ); $this->assertTrue( $data->delete( $this->post_id, 'random223-page-type' ) ); update_option( 'random223-page-type', 'option' ); $this->assertTrue( $data->delete( $this->post_id, 'papi_random223-page-type' ) ); } public function test_get() { $data = new Papi_Core_Data(); $this->assertEmpty( $data->get( $this->post_id, 'name' ) ); update_post_meta( $this->post_id, 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', $data->get( $this->post_id, 'name' ) ); } public function test_get_option() { $data = new Papi_Core_Data( 'option' ); $this->assertEmpty( $data->get( $this->post_id, 'name' ) ); update_option( 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', $data->get( $this->post_id, 'name' ) ); } public function test_get_term() { $data = new Papi_Core_Data( 'term' ); $this->assertEmpty( $data->get( $this->term_id, 'name' ) ); update_term_meta( $this->term_id, 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', $data->get( $this->term_id, 'name' ) ); } public function test_update() { foreach ( ['post', 'option', 'term'] as $type ) { $id = $type === 'term' ? $this->term_id : $this->post_id; $data = new Papi_Core_Data( $type ); $this->assertTrue( $data->update( $id, 'name', 'Fredrik' ) ); $this->assertFalse( $data->update( $id, 'name', 'Fredrik' ) ); $this->assertSame( 'Fredrik', $data->get( $id, 'name' ) ); $this->assertTrue( $data->update( $id, 'name', '' ) ); $this->assertEmpty( $data->get( $id, 'name' ) ); $this->assertTrue( $data->update( $id, 'what', [ 'firstname' => 'Fredrik' ] ) ); $this->assertSame( 'Fredrik', $data->get( $id, 'firstname' ) ); $this->assertTrue( $data->update( $id, 'what', [ 'Fredrik' ] ) ); $this->assertSame( ['Fredrik'], $data->get( $id, 'what' ) ); $this->assertTrue( $data->update( $id, 'what', '{}' ) ); $this->assertEmpty( $data->get( $id, 'what' ) ); } } } ================================================ FILE: tests/cases/core/class-papi-core-property-test.php ================================================ post_id = $this->factory->post->create(); $_GET['post'] = $this->post_id; } public function tearDown() { parent::tearDown(); unset( $_GET, $this->post_id ); } public function test_converter() { update_post_meta( $this->post_id, papi_get_page_type_key(), 'properties-page-type' ); $page_type = papi_get_entry_type_by_id( 'properties-page-type' ); $flexible = $page_type->get_property( 'flexible_test_other' ); $this->assertSame( 'flexible', $flexible->type ); $this->assertSame( 'flexible', $flexible->get_option( 'type' ) ); $this->assertSame( 'Flexible test', $flexible->title ); $this->assertSame( 'Flexible test', $flexible->get_option( 'title' ) ); $this->assertSame( 'papi_flexible_test_other', $flexible->slug ); $this->assertSame( 'papi_flexible_test_other', $flexible->get_option( 'slug' ) ); $this->assertSame( 'papi_flexible_test_other', $flexible->get_slug() ); $this->assertSame( 'flexible_test_other', $flexible->get_slug( true ) ); $flexible_children = $flexible->get_child_properties(); $this->assertSame( 'Twitter', $flexible_children['twitter']['title'] ); $this->assertSame( 'string', $flexible_children['twitter']['items'][0]->type ); $this->assertSame( 'string', $flexible_children['twitter']['items'][0]->get_option( 'type' ) ); $this->assertSame( 'papi_twitter_name', $flexible_children['twitter']['items'][0]->slug ); $this->assertSame( 'papi_twitter_name', $flexible_children['twitter']['items'][0]->get_option( 'slug' ) ); $this->assertSame( 'papi_twitter_name', $flexible_children['twitter']['items'][0]->get_slug() ); $this->assertSame( 'twitter_name', $flexible_children['twitter']['items'][0]->get_slug( true ) ); $this->assertSame( 'Twitter name', $flexible_children['twitter']['items'][0]->title ); $this->assertSame( 'Twitter name', $flexible_children['twitter']['items'][0]->get_option( 'title' ) ); $this->assertSame( 'Posts', $flexible_children['posts']['title'] ); $this->assertSame( 'Posts', $flexible_children['posts']['title'] ); $this->assertSame( 'post', $flexible_children['posts']['items'][0]->type ); $this->assertSame( 'post', $flexible_children['posts']['items'][0]->get_option( 'type' ) ); $this->assertSame( 'papi_post_one', $flexible_children['posts']['items'][0]->slug ); $this->assertSame( 'papi_post_one', $flexible_children['posts']['items'][0]->get_option( 'slug' ) ); $this->assertSame( 'papi_post_one', $flexible_children['posts']['items'][0]->get_slug() ); $this->assertSame( 'post_one', $flexible_children['posts']['items'][0]->get_slug( true ) ); $this->assertSame( 'Post one', $flexible_children['posts']['items'][0]->title ); $this->assertSame( 'Post one', $flexible_children['posts']['items'][0]->get_option( 'title' ) ); $this->assertSame( 'post', $flexible_children['posts']['items'][1]->type ); $this->assertSame( 'post', $flexible_children['posts']['items'][1]->get_option( 'type' ) ); $this->assertSame( 'papi_post_two', $flexible_children['posts']['items'][1]->slug ); $this->assertSame( 'papi_post_two', $flexible_children['posts']['items'][1]->get_option( 'slug' ) ); $this->assertSame( 'papi_post_two', $flexible_children['posts']['items'][1]->get_slug() ); $this->assertSame( 'post_two', $flexible_children['posts']['items'][1]->get_slug( true ) ); $this->assertSame( 'Post two', $flexible_children['posts']['items'][1]->title ); $this->assertSame( 'Post two', $flexible_children['posts']['items'][1]->get_option( 'title' ) ); $this->assertSame( 'List', $flexible_children['list']['title'] ); $repeater = $flexible_children['list']['items'][0]; $this->assertSame( 'repeater', $repeater->type ); $this->assertSame( 'repeater', $repeater->get_option( 'type' ) ); $this->assertSame( 'Repeater test', $repeater->title ); $this->assertSame( 'Repeater test', $repeater->get_option( 'title' ) ); $this->assertSame( 'papi_repeater_test_other', $repeater->slug ); $this->assertSame( 'papi_repeater_test_other', $repeater->get_option( 'slug' ) ); $this->assertSame( 'papi_repeater_test_other', $repeater->get_slug() ); $this->assertSame( 'repeater_test_other', $repeater->get_slug( true ) ); $repeater_children = $repeater->get_child_properties(); $this->assertSame( 'string', $repeater_children[0]->type ); $this->assertSame( 'string', $repeater_children[0]->get_option( 'type' ) ); $this->assertSame( 'papi_book_name', $repeater_children[0]->slug ); $this->assertSame( 'papi_book_name', $repeater_children[0]->get_option( 'slug' ) ); $this->assertSame( 'papi_book_name', $repeater_children[0]->get_slug() ); $this->assertSame( 'book_name', $repeater_children[0]->get_slug( true ) ); $this->assertSame( 'Book name', $repeater_children[0]->title ); $this->assertSame( 'Book name', $repeater_children[0]->get_option( 'title' ) ); $this->assertSame( 'bool', $repeater_children[1]->type ); $this->assertSame( 'bool', $repeater_children[1]->get_option( 'type' ) ); $this->assertSame( 'papi_is_open', $repeater_children[1]->slug ); $this->assertSame( 'papi_is_open', $repeater_children[1]->get_option( 'slug' ) ); $this->assertSame( 'papi_is_open', $repeater_children[1]->get_slug() ); $this->assertSame( 'is_open', $repeater_children[1]->get_slug( true ) ); $this->assertSame( 'Is open?', $repeater_children[1]->title ); $this->assertSame( 'Is open?', $repeater_children[1]->get_option( 'title' ) ); $this->assertSame( 'List 2', $flexible_children['list2']['title'] ); $repeater2 = $flexible_children['list2']['items'][0]; $this->assertSame( 'repeater', $repeater2->type ); $this->assertSame( 'repeater', $repeater2->get_option( 'type' ) ); $this->assertSame( 'Repeater test 2', $repeater2->title ); $this->assertSame( 'Repeater test 2', $repeater2->get_option( 'title' ) ); $this->assertSame( 'papi_repeater_test_other_2', $repeater2->slug ); $this->assertSame( 'papi_repeater_test_other_2', $repeater2->get_option( 'slug' ) ); $this->assertSame( 'papi_repeater_test_other_2', $repeater2->get_slug() ); $this->assertSame( 'repeater_test_other_2', $repeater2->get_slug( true ) ); $repeater_children2 = $repeater->get_child_properties(); $this->assertSame( 'string', $repeater_children2[0]->type ); $this->assertSame( 'string', $repeater_children2[0]->get_option( 'type' ) ); $this->assertSame( 'papi_book_name', $repeater_children2[0]->slug ); $this->assertSame( 'papi_book_name', $repeater_children2[0]->get_option( 'slug' ) ); $this->assertSame( 'papi_book_name', $repeater_children2[0]->get_slug() ); $this->assertSame( 'book_name', $repeater_children2[0]->get_slug( true ) ); $this->assertSame( 'Book name', $repeater_children2[0]->title ); $this->assertSame( 'Book name', $repeater_children2[0]->get_option( 'title' ) ); $this->assertSame( 'bool', $repeater_children2[1]->type ); $this->assertSame( 'bool', $repeater_children2[1]->get_option( 'type' ) ); $this->assertSame( 'papi_is_open', $repeater_children2[1]->slug ); $this->assertSame( 'papi_is_open', $repeater_children2[1]->get_option( 'slug' ) ); $this->assertSame( 'papi_is_open', $repeater_children2[1]->get_slug() ); $this->assertSame( 'is_open', $repeater_children2[1]->get_slug( true ) ); $this->assertSame( 'Is open?', $repeater_children2[1]->title ); $this->assertSame( 'Is open?', $repeater_children2[1]->get_option( 'title' ) ); } public function test_current_user_can() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertTrue( $property->current_user_can() ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name', 'capabilities' => ['fake'] ] ); $this->assertFalse( $property->current_user_can() ); } public function test_default_options() { $_GET['post'] = 0; $_GET['post_type'] = ''; $property = Papi_Core_Property::factory(); $options = $property->get_options(); $this->assertTrue( is_object( $options ) ); $this->assertEmpty( $options->after_class ); $this->assertEmpty( $options->after_html ); $this->assertEmpty( $options->before_class ); $this->assertEmpty( $options->before_html ); $this->assertSame( [], $options->capabilities ); $this->assertEmpty( $options->default ); $this->assertEmpty( $options->description ); $this->assertFalse( $options->disabled ); $this->assertTrue( $options->display ); $this->assertFalse( $options->lang ); $this->assertFalse( $options->overwrite ); $this->assertEmpty( $options->post_type ); $this->assertFalse( $options->raw ); $this->assertFalse( $options->required ); $this->assertSame( [], $options->rules ); $this->assertTrue( is_object( $options->settings ) ); $this->assertSame( 'papi_', $options->slug ); $this->assertSame( 1000, $options->sort_order ); $this->assertEmpty( $options->title ); $this->assertEmpty( $options->type ); $this->assertEmpty( $options->value ); unset( $_GET['post'] ); unset( $_GET['post_type'] ); } public function test_disabled() { $_GET['post_type'] = 'page'; $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertFalse( $property->disabled() ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name', 'site_id' => 2 ] ); $this->assertTrue( $property->disabled() ); unset( $_GET['post_type'] ); } public function test_display() { $page_type = papi_get_entry_type_by_id( 'properties-page-type' ); $property = $page_type->get_property( 'string_test' ); $this->assertTrue( $property->display() ); $page_type2 = papi_get_entry_type_by_id( 'faq-page-type' ); $property2 = $page_type2->get_property( 'type' ); $this->assertFalse( $property2->display() ); } public function test_factory() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertSame( $property->get_option( 'type' ), 'string' ); $this->assertSame( $property->get_option( 'title' ), 'Name' ); $this->assertSame( $property->get_option( 'slug' ), 'papi_name' ); } public function test_factory_fake() { require_once PAPI_FIXTURE_DIR . '/properties/class-papi-property-fake.php'; $this->assertNull( Papi_Core_Property::factory( '' ) ); $this->assertNull( Papi_Core_Property::factory( 'fake' ) ); } public function test_factory_bad_value() { papi()->bind( 'Papi_Core_Property_String', '' ); $this->assertTrue( Papi_Core_Property::factory( 'string' ) instanceof Papi_Core_Property ); } public function test_factory_property() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $this->assertTrue( Papi_Core_Property::factory( $property ) instanceof Papi_Core_Property ); } public function test_factory_slug() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name', 'slug' => 'name' ] ); $this->assertSame( $property->get_option( 'slug' ), 'papi_name' ); } public function test_factory_slug_empty() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertSame( $property->get_option( 'slug' ), 'papi_name' ); } public function test_factory_slug_false() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name', 'slug' => false ] ); $slug = unpapify( $property->get_option( 'slug' ) ); $slug = str_replace( '_', '', $slug ); $this->assertRegExp( '/^[a-f0-9]{32}$/', $slug ); } public function test_format_value() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $actual = $property->format_value( 'Fredrik', '', 0 ); $this->assertSame( 'Fredrik', $actual ); } public function test_get_child_property_fail() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $this->assertNull( $property->get_child_property( 'hello' ) ); } public function test_get_child_property_success() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello', 'settings' => [ 'items' => [ Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ) ] ] ] ); $child_property = $property->get_child_property( 'name' ); $this->assertInstanceOf( 'Papi_Core_Property', $child_property ); $this->assertSame( 'string', $child_property->type ); $this->assertSame( 'Name', $child_property->title ); } public function test_get_convert_type() { $property = Papi_Core_Property::factory(); $this->assertSame( 'string', $property->get_convert_type() ); } public function test_get_default_settings() { $property = Papi_Core_Property::factory(); $this->assertSame( [], $property->get_default_settings() ); } public function test_get_default_value_fail() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $this->assertEmpty( $property->get_value() ); $property = Papi_Core_Property::factory( [ 'default' => 'Hello', 'title' => 'Hello', ] ); $this->assertSame( 'Hello', $property->get_value() ); } public function test_get_default_value_success() { $_GET['post'] = 0; $property = Papi_Core_Property::factory( [ 'default' => 'Hello', 'type' => 'string', 'title' => 'Hello' ] ); $this->assertSame( 'Hello', $property->get_value() ); unset( $_GET['post'] ); } public function test_get_meta_type() { $property = new Papi_Core_Property(); $this->assertSame( 'post', $property->get_meta_type() ); } public function test_get_option() { $property = new Papi_Core_Property(); $property->set_option( 'title', 'Name' ); $this->assertSame( 'Name', $property->title ); $this->assertSame( 'Name', $property->get_option( 'title' ) ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertNull( $property->fake ); $this->assertNull( $property->get_option( 'fake' ) ); $this->assertSame( 'Name', $property->title ); $this->assertSame( 'Name', $property->get_option( 'title' ) ); $this->assertSame( 1000, $property->sort_order ); $this->assertSame( 1000, $property->get_option( 'sort_order' ) ); $property->title = 'Link'; $this->assertSame( 'Link', $property->title ); $settings = $property->get_option( 'settings' ); $this->assertTrue( is_object( $settings ) ); } public function test_get_options() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $options = $property->get_options(); $this->assertSame( 'Name', $options->title ); } public function test_get_store() { $property = new Papi_Core_Property(); $this->assertTrue( $property->get_store() instanceof Papi_Post_Store ); } public function test_get_post_id() { $property = Papi_Core_Property::factory(); $this->assertSame( $this->post_id, $property->get_post_id() ); } public function test_get_setting() { $property = new Papi_Core_Property(); $this->assertNull( $property->get_setting( null ) ); $this->assertNull( $property->get_setting( 'length' ) ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'settings' => [ 'length' => 50 ] ] ); $this->assertSame( 50, $property->get_setting( 'length' ) ); } public function test_get_settings() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'settings' => [ 'items' => [ [ 'type' => 'faker' ], [ 'type' => 'fake' ] ] ] ] ); $settings = $property->get_settings(); $this->assertTrue( is_object( $settings ) ); $this->assertNotEmpty( $settings->items ); } public function test_get_slug() { $property = new Papi_Core_Property(); $this->assertEmpty( $property->get_slug() ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->assertSame( 'papi_name', $property->get_slug() ); $this->assertSame( 'name', $property->get_slug( true ) ); } public function test_get_value() { $this->assertNull( ( new Papi_Core_Property )->get_value() ); } public function test_html_id() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'slug' => 'name' ] ); $this->assertSame( '_papi_name', $property->html_id() ); $this->assertSame( '_papi_name_suffix', $property->html_id( 'suffix' ) ); $this->assertSame( '_papi_name_black', $property->html_id( 'Black' ) ); $this->assertSame( '_papi_name_lank', $property->html_id( 'Länk' ) ); } public function test_html_id_array() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'slug' => 'name' ] ); $sub_property = Papi_Core_Property::factory( [ 'type' => 'number', 'slug' => 'age' ] ); $this->assertSame( '_papi_name[age]', $property->html_id( $sub_property ) ); $this->assertSame( '_papi_name[0][age]', $property->html_id( $sub_property, 0 ) ); $sub_property = (object) [ 'type' => 'number', 'slug' => 'age' ]; $this->assertSame( '_papi_name[age]', $property->html_id( $sub_property ) ); $this->assertSame( '_papi_name[0][age]', $property->html_id( $sub_property, 0 ) ); $sub_property = 'non array or object'; $this->assertSame( '_papi_name_non_array_or_object', $property->html_id( $sub_property ) ); $this->assertSame( '_papi_name_non_array_or_object', $property->html_id( $sub_property, 0 ) ); $property = Papi_Core_Property::factory( [ 'type' => 'number', 'slug' => 'sections[0][age]' ] ); $this->assertSame( '_papi_sections[0][age_sort_order]', $property->html_id( 'sort_order' ) ); } public function test_html_name() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'slug' => 'name' ] ); $this->assertSame( 'papi_name', $property->html_name() ); } public function test_html_name_array() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'slug' => 'name' ] ); $sub_property = Papi_Core_Property::factory( [ 'type' => 'number', 'slug' => 'age' ] ); $this->assertSame( 'papi_name[age]', $property->html_name( $sub_property ) ); $this->assertSame( 'papi_name[0][age]', $property->html_name( $sub_property, 0 ) ); $sub_property = (object) [ 'type' => 'number', 'slug' => 'age' ]; $this->assertSame( 'papi_name[age]', $property->html_name( $sub_property ) ); $this->assertSame( 'papi_name[0][age]', $property->html_name( $sub_property, 0 ) ); $sub_property = 'non array or object'; $this->assertSame( 'papi_name', $property->html_name( $sub_property ) ); $this->assertSame( 'papi_name[0]', $property->html_name( $sub_property, 0 ) ); } public function test_load_value() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $actual = $property->load_value( 'Fredrik', '', 0 ); $this->assertSame( 'Fredrik', $actual ); } public function test_layout() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'slug' => 'name' ] ); $this->assertSame( 'horizontal', $property->get_option( 'layout' ) ); $this->assertTrue( $property->get_option( 'sidebar' ) ); $property = Papi_Core_Property::factory( [ 'layout' => 'vertical', 'type' => 'string', 'slug' => 'name' ] ); $this->assertSame( 'vertical', $property->get_option( 'layout' ) ); $this->assertTrue( $property->get_option( 'sidebar' ) ); } public function test_match_slug() { $property = Papi_Core_Property::factory( [ 'description' => 'Test', 'type' => 'string', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->assertTrue( $property->match_slug( 'name' ) ); $this->assertTrue( $property->match_slug( 'papi_name' ) ); $this->assertFalse( $property->match_slug( 'kvack' ) ); $this->assertFalse( $property->match_slug( 'papi_kvack' ) ); $this->assertFalse( $property->match_slug( null ) ); $this->assertFalse( $property->match_slug( true ) ); $this->assertFalse( $property->match_slug( false ) ); $this->assertFalse( $property->match_slug( 1 ) ); $this->assertFalse( $property->match_slug( 0 ) ); $this->assertFalse( $property->match_slug( [] ) ); $this->assertFalse( $property->match_slug( (object) [] ) ); $this->assertFalse( $property->match_slug( '' ) ); } public function test_post_type_option() { $_GET['post_type'] = 'faq'; $page_type2 = papi_get_entry_type_by_id( 'faq-page-type' ); $property2 = $page_type2->get_property( 'question' ); $this->assertFalse( $property2->disabled() ); $_GET['post_type'] = 'page'; $page_type2 = papi_get_entry_type_by_id( 'faq-page-type' ); $property2 = $page_type2->get_property( 'question' ); $this->assertTrue( $property2->disabled() ); unset( $_GET['post_type'] ); } public function test_set_option() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $property->set_option( 'title', 'Name' ); $value = $property->get_option( 'title' ); $this->assertSame( 'Name', $value ); } public function test_set_options() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $property->set_options( [ 'title' => 'Name' ] ); $this->assertSame( 'Name', $property->get_option( 'title' ) ); $property = Papi_Core_Property::factory( [ 'type' => 'string' ] ); $this->assertSame( 'papi_string', $property->get_option( 'slug' ) ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'description' => 'test' ] ); $this->assertSame( 'test', $property->get_option( 'description' ) ); $property = Papi_Core_Property::factory( [ 'type' => 'string', 'desc' => 'test' ] ); $this->assertSame( 'test', $property->get_option( 'description' ) ); } public function test_set_post_id() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello' ] ); $property->set_post_id( null ); $this->assertNotEmpty( $property->get_post_id() ); $post_id = $this->factory->post->create(); $property->set_post_id( $post_id ); $this->assertSame( $post_id, $property->get_post_id() ); } public function test_set_settings() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Hello', 'settings' => [] ] ); $this->assertFalse( $property->get_setting( 'allow_html' ) ); $property->set_setting( 'allow_html', true ); $this->assertTrue( $property->get_setting( 'allow_html' ) ); } public function test_update_value() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $actual = $property->update_value( 'Fredrik', '', 0 ); $this->assertSame( 'Fredrik', $actual ); } public function test_update_value_empty() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $value = $property->update_value( [null], '', 0 ); $this->assertNull( $value ); $value1 = $property->load_value( $value, '', 0 ); $this->assertNull( $value1 ); } public function test_update_value_with_empty_values() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $value = $property->update_value( ['', 75, 87], '', 0 ); $this->assertTrue( is_string( $value ) ); $value1 = $property->load_value( $value, '', 0 ); $this->assertSame( [75, 87], $value1 ); } public function test_update_value_with_key_value() { $property = Papi_Core_Property::factory( [ 'type' => 'string', 'title' => 'Name' ] ); $value = $property->update_value( ['name' => 'Fredrik'], '', 0 ); $this->assertTrue( is_string( $value ) ); $value1 = $property->load_value( $value, '', 0 ); $this->assertSame( 'Fredrik', $value1->name ); } public function test_value_serialize() { $property = Papi_Core_Property::factory( [ 'title' => 'Name' ] ); $value = $property->update_value( [1, 2, 3], '', 0 ); $this->assertTrue( is_string( $value ) ); $value1 = $property->load_value( $value, '', 0 ); $this->assertSame( [1, 2, 3], $value1 ); $value2 = $property->format_value( $value, '', 0 ); $this->assertSame( [1, 2, 3], $value2 ); } } ================================================ FILE: tests/cases/core/class-papi-core-tab-test.php ================================================ 'Tab' ] ); $this->assertSame( 'Tab', $tab->title ); $this->assertSame( '_papi_tab', $tab->id ); } } ================================================ FILE: tests/cases/core/class-papi-core-type-test.php ================================================ info_core_path = PAPI_FIXTURE_DIR . '/core-types/info-core-type.php'; $this->info2_core_path = PAPI_FIXTURE_DIR . '/core-types/info2-core-type.php'; $this->info_core_type = new Papi_Core_Type( $this->info_core_path ); if ( ! class_exists( 'Info_Core_Type' ) ) { require_once $this->info_core_path; } if ( ! class_exists( 'Info2_Core_Type' ) ) { require $this->info2_core_path; } } public function tearDown() { parent::tearDown(); unset( $this->info_core_path, $this->info2_core_type, $this->info_core_type ); } public function test_core_type_allowed() { $this->assertTrue( $this->info_core_type->allowed() ); } public function test_core_type_get_id() { $this->assertRegExp( '/\/core-types\/info-core-type$/', $this->info_core_type->get_id() ); } public function test_core_type_get_meta() { $class = new Info_Core_Type( $this->info_core_path ); $this->assertSame( 'Info core type', $class->name ); $this->assertSame( 500, $class->sort_order ); $class2 = new Info2_Core_Type( $this->info2_core_path ); $this->assertSame( 'Info2 core type', $class2->name ); $this->assertSame( 500, $class2->sort_order ); } public function test_core_type_get_meta_abstract() { $path = PAPI_FIXTURE_DIR . '/core-types/abstract-core-type.php'; if ( ! class_exists( 'Abstract_Core_Type' ) ) { require_once $path; } $class = new Abstract_Core_Type( $path ); $this->assertSame( 'Abstract core', $class->name ); } public function test_core_type_get_type() { $this->assertSame( 'core', $this->info_core_type->get_type() ); } public function test_core_type_has_name() { $this->assertFalse( $this->info_core_type->has_name() ); $class = new Info_Core_Type( $this->info_core_path ); $this->assertTrue( $class->has_name() ); } public function test_core_type_match_id() { $this->assertTrue( $this->info_core_type->match_id( $this->info_core_type->get_id() ) ); $this->assertFalse( $this->info_core_type->match_id( '' ) ); } public function test_core_type_new_class() { $class = $this->info_core_type->new_class(); $this->assertInstanceOf( 'Papi_Core_Type', $class ); } public function test_set_id() { $class = new Papi_Core_Type; $this->assertEmpty( $class->get_id() ); $class->set_id( 'hello' ); $this->assertSame( 'hello', $class->get_id() ); } } ================================================ FILE: tests/cases/lib/core/cache-test.php ================================================ post_id = $this->factory->post->create(); update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); } public function tearDown() { parent::tearDown(); unset( $this->post_id ); } public function test_papi_cache_delete_1() { papi_cache_set( 'test', $this->post_id, 'fredrik' ); $this->assertSame( 'fredrik', papi_cache_get( 'test', $this->post_id ) ); papi_cache_set( 'test', $this->post_id, 'elli' ); $this->assertSame( 'elli', papi_cache_get( 'test', $this->post_id ) ); papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); } public function test_papi_cache_delete_2() { $this->assertTrue( papi_update_field( $this->post_id, 'namn', 'fredrik' ) ); $this->assertSame( 'fredrik', papi_get_field( $this->post_id, 'namn' ) ); $this->assertTrue( papi_update_field( $this->post_id, 'namn', 'elli' ) ); $this->assertSame( 'elli', papi_get_field( $this->post_id, 'namn' ) ); } public function test_papi_cache_delete_admin() { papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); papi_cache_set( 'test', $this->post_id, 'elli' ); $this->assertSame( 'elli', papi_cache_get( 'test', $this->post_id ) ); papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); $current_screen = null; } public function test_papi_cache_get() { papi_cache_set( 'get', $this->post_id, 'elli' ); $this->assertSame( 'elli', papi_cache_get( 'get', $this->post_id ) ); } public function test_papi_cache_get_admin() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); papi_cache_set( 'test', $this->post_id, 'elli' ); $this->assertSame( 'elli', papi_cache_get( 'test', $this->post_id ) ); $current_screen = null; papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); $current_screen = null; } public function test_papi_cache_key() { $this->assertEmpty( papi_cache_key( 0, 1 ) ); $this->assertEmpty( papi_cache_key( [], 'hello' ) ); $this->assertEmpty( papi_cache_key( (object) [], 230 ) ); $this->assertEmpty( papi_cache_key( true, 'false' ) ); $this->assertEmpty( papi_cache_key( false, 'true' ) ); $this->assertEmpty( papi_cache_key( null, 2 ) ); global $post; $post_id = $this->factory->post->create(); $post = get_post( $post_id ); $this->assertSame( 'papi_post_page_' . $post_id, papi_cache_key( 'page', $post_id ) ); $this->assertSame( 'papi_post_page_' . $post_id, papi_cache_key( 'papi_page', $post_id ) ); $this->assertSame( 'papi_post_page_920', papi_cache_key( 'page', 920 ) ); unset( $post ); } public function test_papi_cache_set() { papi_cache_set( 'set', $this->post_id, 'elli' ); $this->assertSame( 'elli', papi_cache_get( 'set', $this->post_id ) ); } public function test_papi_cache_set_admin() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); papi_cache_set( 'test', $this->post_id, 'elli' ); $this->assertSame( 'elli', papi_cache_get( 'test', $this->post_id ) ); $current_screen = null; papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); papi_cache_delete( 'test', $this->post_id ); $this->assertEmpty( papi_cache_get( 'test', $this->post_id ) ); $current_screen = null; } } ================================================ FILE: tests/cases/lib/core/conditional-test.php ================================================ assertFalse( papi_is_rule( null ) ); $this->assertFalse( papi_is_rule( true ) ); $this->assertFalse( papi_is_rule( false ) ); $this->assertFalse( papi_is_rule( 1 ) ); $this->assertFalse( papi_is_rule( '' ) ); $this->assertFalse( papi_is_rule( [] ) ); $this->assertFalse( papi_is_rule( (object) [] ) ); $this->assertTrue( papi_is_rule( papi_rule( [ 'operator' => '>', 'slug' => 'name', 'value' => 'Fredrik' ] ) ) ); } public function test_papi_rule() { $this->assertNull( papi_rule( null ) ); $this->assertNull( papi_rule( true ) ); $this->assertNull( papi_rule( false ) ); $this->assertNull( papi_rule( 1 ) ); $this->assertNull( papi_rule( '' ) ); $this->assertNull( papi_rule( [] ) ); $this->assertNull( papi_rule( (object) [] ) ); $rule = papi_rule( [ 'operator' => '>', 'slug' => 'name', 'value' => 'Fredrik' ] ); $this->assertTrue( papi_is_rule( $rule ) ); $this->assertTrue( papi_is_rule( papi_rule( $rule ) ) ); } } ================================================ FILE: tests/cases/lib/core/data-test.php ================================================ post_id = $this->factory->post->create(); } public function tearDown() { parent::tearDown(); unset( $this->post_id ); } public function test_papi_data_delete() { $this->assertFalse( papi_data_delete( $this->post_id, 'name' ) ); papi_data_update( $this->post_id, 'name', 'Fredrik' ); $this->assertTrue( papi_data_delete( $this->post_id, 'name' ) ); } public function test_papi_data_get() { $this->assertEmpty( papi_data_get( $this->post_id, 'name' ) ); papi_data_update( $this->post_id, 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', papi_data_get( $this->post_id, 'name' ) ); } public function test_papi_data_update() { $this->assertEmpty( papi_data_get( $this->post_id, 'name' ) ); papi_data_update( $this->post_id, 'name', 'Fredrik' ); $this->assertSame( 'Fredrik', papi_data_get( $this->post_id, 'name' ) ); } } ================================================ FILE: tests/cases/lib/core/deprecated-test.php ================================================ post_id = $this->factory->post->create(); update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); } public function deprecated_function_run( $function ) { add_filter( 'deprecated_function_trigger_error', '__return_false' ); } public function tearDown() { parent::tearDown(); remove_filter( 'deprecated_function_trigger_error', '__return_false' ); unset( $_GET, $this->post_id ); } /** * `papi_get_page` is deprecated since 3.2.0 */ public function test_papi_get_page() { $page = papi_get_page( $this->post_id ); $this->assertTrue( is_object( $page ) ); $page = papi_get_page( $this->post_id, 'fake' ); $this->assertNull( $page ); } } ================================================ FILE: tests/cases/lib/core/io-test.php ================================================ assertEmpty( register_papi_directory( null ) ); $this->assertEmpty( register_papi_directory( null ) ); register_papi_directory( 'fake-path' ); $this->assertEquals( $defaults, papi_filter_settings_directories() ); register_papi_directory( ['fake-path'] ); $this->assertEquals( $defaults, papi_filter_settings_directories() ); register_papi_directory( PAPI_FIXTURE_DIR . '/entry-types' ); $this->assertSame( [PAPI_FIXTURE_DIR . '/entry-types'], papi_filter_settings_directories() ); } public function test_papi_get_all_files_in_directory() { $this->assertEmpty( papi_get_all_files_in_directory( 1 ) ); $this->assertEmpty( papi_get_all_files_in_directory( true ) ); $this->assertEmpty( papi_get_all_files_in_directory( false ) ); $this->assertEmpty( papi_get_all_files_in_directory( [] ) ); $this->assertEmpty( papi_get_all_files_in_directory( (object) [] ) ); $this->assertEmpty( papi_get_all_files_in_directory( '' ) ); $this->assertEmpty( papi_get_all_files_in_directory() ); $this->assertTrue( is_array( papi_get_all_files_in_directory() ) ); $actual = papi_get_all_files_in_directory( PAPI_FIXTURE_DIR . '/page-types' ); $expected = PAPI_FIXTURE_DIR . '/page-types/simple-page-type.php'; $this->assertTrue( is_array( $actual ) ); $this->assertTrue( ! empty( $actual ) ); $this->assertTrue( in_array( $expected, $actual ) ); } public function test_papi_get_core_type_file_path() { $this->assertEmpty( papi_get_core_type_file_path( '' ) ); add_filter( 'papi/settings/directories', function () { return [PAPI_FIXTURE_DIR . '/entry-types', PAPI_FIXTURE_DIR . '/entry-types2']; } ); $output = papi_get_all_core_type_files(); $file_path = ''; foreach ( $output as $file ) { if ( strpos( 'entry-types2/term-entry-type.php', $file ) !== -1 ) { $this->assertTrue( true ); $file_path = $file; } } if ( empty( $file_path ) ) { $this->assertTrue( false ); } $file_path = str_replace( 'types2', 'types', $file_path ); $file_path = papi_get_core_type_file_path( $file_path ); $this->assertTrue( strpos( 'entry-types2/term-entry-type.php', $file ) !== -1 ); } public function test_papi_get_all_core_type_files() { papi()->reset(); $this->assertEmpty( papi_get_all_core_type_files() ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); papi()->reset(); $actual = papi_get_all_core_type_files(); $this->assertFalse( empty( $actual ) ); $this->assertTrue( is_array( $actual ) ); } public function test_papi_get_file_path() { $this->assertNull( papi_get_file_path( 1 ) ); $this->assertNull( papi_get_file_path( null ) ); $this->assertNull( papi_get_file_path( true ) ); $this->assertNull( papi_get_file_path( false ) ); $this->assertNull( papi_get_file_path( [] ) ); $this->assertNull( papi_get_file_path( (object) [] ) ); $this->assertNull( papi_get_file_path( '' ) ); $this->assertNull( papi_get_file_path( 'simple-page-type' ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); $path1 = papi_get_file_path( 'simple-page-type' ); $path2 = papi_get_file_path( 'simple-page-type.php' ); $this->assertTrue( strpos( $path1, 'simple-page-type.php' ) !== false ); $this->assertTrue( strpos( $path2, 'simple-page-type.php' ) !== false ); } public function test_papi_get_core_type_base_path() { $this->assertEmpty( papi_get_core_type_base_path( 1 ) ); $this->assertEmpty( papi_get_core_type_base_path( true ) ); $this->assertEmpty( papi_get_core_type_base_path( false ) ); $this->assertEmpty( papi_get_core_type_base_path( [] ) ); $this->assertEmpty( papi_get_core_type_base_path( (object) [] ) ); $this->assertEmpty( papi_get_core_type_base_path( '' ) ); $this->assertSame( 'simple-page-type', papi_get_core_type_base_path( 'simple-page-type' ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); $path = papi_get_file_path( 'simple-page-type' ); $this->assertSame( 'simple-page-type', papi_get_core_type_base_path( $path ) ); $this->assertEmpty( papi_get_core_type_base_path( '' ) ); $this->assertEmpty( papi_get_core_type_base_path( null ) ); } } ================================================ FILE: tests/cases/lib/core/meta-test.php ================================================ post_id = $this->factory->post->create(); $this->term_id = $this->factory->term->create(); } public function tearDown() { parent::tearDown(); unset( $_GET, $this->post_id, $this->term_id ); } public function test_papi_get_meta_id() { $this->assertSame( 0, papi_get_meta_id( 'option' ) ); $_GET['post'] = 1; $this->assertSame( 1, papi_get_meta_id() ); $this->assertSame( 1, papi_get_meta_id( 'post' ) ); unset( $_GET['post'] ); $_GET['term_id'] = 2; $this->assertSame( 2, papi_get_meta_id( 'term' ) ); unset( $_GET['term_id'] ); } public function test_papi_get_meta_id_column() { $this->assertSame( 'post_id', papi_get_meta_id_column() ); $this->assertSame( 'post_id', papi_get_meta_id_column( 'post' ) ); $this->assertSame( 'post_id', papi_get_meta_id_column( 'page' ) ); $this->assertSame( 'term_id', papi_get_meta_id_column( 'term' ) ); $this->assertSame( 'term_id', papi_get_meta_id_column( 'taxonomy' ) ); $this->assertNull( papi_get_meta_id_column( 'hello' ) ); } public function test_papi_get_meta_store() { $this->assertInstanceOf( 'Papi_Post_Store', papi_get_meta_store( $this->post_id ) ); $this->assertInstanceOf( 'Papi_Option_Store', papi_get_meta_store( 0, 'option' ) ); $store = papi_get_meta_store( $this->post_id, 'fake' ); $this->assertNull( $store ); if ( function_exists( 'get_term_meta' ) ) { $this->assertInstanceOf( 'Papi_Term_Store', papi_get_meta_store( $this->term_id, 'term' ) ); } } public function test_papi_get_meta_type() { $this->assertSame( 'post', papi_get_meta_type() ); $this->assertSame( 'post', papi_get_meta_type( 'post' ) ); $this->assertSame( 'post', papi_get_meta_type( 'page' ) ); $this->assertSame( 'term', papi_get_meta_type( 'term' ) ); $this->assertSame( 'term', papi_get_meta_type( 'taxonomy' ) ); $this->assertSame( 'option', papi_get_meta_type( 'option' ) ); $this->assertNull( papi_get_meta_type( 'hello' ) ); $_GET['meta_type'] = 'test'; $this->assertSame( 'test', papi_get_meta_type() ); unset( $_GET['meta_type'] ); $this->assertSame( 'post', papi_get_meta_type() ); } public function test_papi_get_meta_type_quried_object() { global $wp_query; // Test term object. $wp_query->is_category = true; $category_id = $this->factory->category->create(); $wp_query->query_vars['cat'] = $category_id; $this->assertSame( 'term', papi_get_meta_type() ); $this->assertTrue( isset( get_queried_object()->term_id ) ); // Turn off category query. $wp_query->queried_object = null; $wp_query->is_category = false; // Test post object. $post_id = $this->factory->post->create(); $wp_query->is_singular = true; $wp_query->post = get_post( $post_id ); $this->assertSame( 'post', papi_get_meta_type() ); $this->assertTrue( isset( get_queried_object()->post_type ) ); // Turn off post query. $wp_query->queried_object = null; $wp_query->is_singular = false; $wp_query->post = null; } public function test_papi_get_meta_type_wp_query() { global $wp_query; $wp_query->is_tag = true; $this->assertSame( 'term', papi_get_meta_type() ); $wp_query->is_tag = false; $wp_query->is_category = true; $this->assertSame( 'term', papi_get_meta_type() ); $wp_query->is_category = false; } public function test_papi_get_meta_type_admin() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); $_SERVER['REQUEST_URI'] = 'http://site.com/?taxonomy=test'; $this->assertSame( 'term', papi_get_meta_type() ); $_SERVER['REQUEST_URI'] = ''; $_SERVER['REQUEST_URI'] = 'http://site.com/?page=papi/option/test'; $this->assertSame( 'option', papi_get_meta_type() ); $_SERVER['REQUEST_URI'] = ''; $current_screen = null; } public function test_papi_get_meta_type_admin_ajax() { global $current_screen; $current_screen = WP_Screen::get( 'admin_init' ); if ( ! defined( 'DOING_AJAX' ) ) { define( 'DOING_AJAX', true ); } $_POST['post_type'] = 'post'; $_POST['taxonomy'] = 'test'; $this->assertSame( 'term', papi_get_meta_type() ); unset( $_POST['taxonomy'] ); $this->assertSame( 'post', papi_get_meta_type() ); unset( $_POST['post_type'] ); $current_screen = null; } } ================================================ FILE: tests/cases/lib/core/post-test.php ================================================ factory->post->create(); $post = get_post( $post_id ); $this->assertSame( 1, papi_get_post_id( 1 ) ); $this->assertSame( $post_id, papi_get_post_id() ); $this->assertSame( $post_id, papi_get_post_id( null ) ); $this->assertSame( $post_id, papi_get_post_id( $post ) ); $this->assertSame( 1, papi_get_post_id( '1' ) ); $post = null; $_GET = ['post' => $post_id]; $this->assertSame( $post_id, papi_get_post_id() ); unset( $_GET ); $_GET = ['post' => [1, 2, 3]]; $this->assertSame( 0, papi_get_post_id() ); unset( $_GET ); $_GET = ['page_id' => $post_id]; $this->assertSame( $post_id, papi_get_post_id() ); unset( $_GET ); $_POST = [ 'action' => 'query-attachments', 'query' => [ 'item' => $post_id ] ]; $this->assertSame( $post_id, papi_get_post_id() ); unset( $_POST ); $_GET = [ 'post' => $post_id ]; $_POST = [ 'action' => 'query-attachments' ]; $this->assertSame( $post_id, papi_get_post_id() ); unset( $_POST ); } public function test_papi_get_parent_post_id() { $this->assertEmpty( papi_get_parent_post_id() ); $_GET['post_parent'] = 7; $this->assertSame( 7, papi_get_parent_post_id() ); unset( $_GET ); } public function test_papi_get_post_type() { global $post; $this->assertEmpty( papi_get_post_type() ); $_GET = ['post_type' => 'post']; $this->assertSame( 'post', papi_get_post_type() ); $_GET = ['page' => 'papi-add-new-page,books']; $this->assertSame( 'books', papi_get_post_type() ); $_GET = ['page' => 'papi-add-new-page,dash-post']; $this->assertSame( 'dash-post', papi_get_post_type() ); $_GET = ['page' => 'papi-add-new-page,und_post']; $this->assertSame( 'und_post', papi_get_post_type() ); $_GET = ['page' => 'papi-add-new-page,3414']; $this->assertSame( '3414', papi_get_post_type() ); $_GET = ['page' => 'papi-add-new-page,dash13']; $this->assertSame( 'dash13', papi_get_post_type() ); $_GET = ['page' => '']; $this->assertEmpty( papi_get_post_type() ); $_GET = ['page' => 'papi-add-new-page,']; $this->assertEmpty( papi_get_post_type() ); unset( $_GET ); $_POST = ['post_type' => 'page']; $this->assertSame( 'page', papi_get_post_type() ); unset( $_POST ); $_SERVER['REQUEST_URI'] = 'wordpress/wp-admin/post-new.php'; $this->assertSame( 'post', papi_get_post_type() ); $_SERVER['REQUEST_URI'] = ''; $post_id = $this->factory->post->create(); $post = get_post( $post_id ); $this->assertSame( 'post', papi_get_post_type() ); } public function test_papi_get_post_type_label() { $this->assertEmpty( papi_get_post_type_label( 'fake', 'name', '' ) ); $this->assertSame( 'Posts', papi_get_post_type_label( 'post', 'name' ) ); } } ================================================ FILE: tests/cases/lib/core/property-test.php ================================================ post_id = $this->factory->post->create(); $post = get_post( $this->post_id ); } public function tearDown() { parent::tearDown(); unset( $this->post_id ); } public function test_papi_property_from_array_slugs() { $actual = papi_from_property_array_slugs( [ 'repeater' => 1, 'repeater_0_image' => 1, '_repeater_0_image_property' => 'image' ], 'repeater' ); $expected = [ [ 'image' => 1, '_image_property' => 'image' ] ]; $this->assertSame( $expected, $actual ); $this->assertEmpty( papi_from_property_array_slugs( [], 'custom_slug' ) ); } public function test_papi_is_property() { $this->assertTrue( papi_is_property( new Papi_Property() ) ); $this->assertTrue( papi_is_property( new Papi_Property_String() ) ); $this->assertFalse( papi_is_property( (object) [] ) ); $this->assertFalse( papi_is_property( [] ) ); $this->assertFalse( papi_is_property( null ) ); $this->assertFalse( papi_is_property( 1 ) ); $this->assertFalse( papi_is_property( true ) ); $this->assertFalse( papi_is_property( false ) ); $this->assertFalse( papi_is_property( '' ) ); } public function test_papi_get_options_and_properties() { $simple_box = PAPI_FIXTURE_DIR . '/page-types/boxes/simple.php'; $options = papi_get_options_and_properties( $simple_box, [ 'test' => 'test' ] ); $this->assertSame( 'Simple', $options[0]['title'] ); $this->assertSame( 'test', $options[0]['test'] ); $this->assertSame( 'Name', $options[1][0]->title ); $this->assertSame( 'string', $options[1][0]->type ); $options = papi_get_options_and_properties( 'hello' ); $this->assertSame( 'hello', $options[0]['title'] ); $options = papi_get_options_and_properties( [ 'title' => 'Simple', papi_property( [ 'type' => 'string', 'title' => 'Name' ] ) ], [], false ); $this->assertSame( 'Simple', $options[0]['title'] ); $this->assertSame( 'Name', $options[1][0]->title ); $this->assertSame( 'string', $options[1][0]->type ); $options = papi_get_options_and_properties( [ 'title' => 'Simple' ] ); $this->assertSame( 'Simple', $options[0]['title'] ); $options = papi_get_options_and_properties( [] ); $this->assertEmpty( $options[0]['title'] ); $options = papi_get_options_and_properties( [ papi_property( [ 'type' => 'string', 'title' => 'Name' ] ) ] ); $this->assertSame( 'Name', $options[0]['title'] ); $this->assertSame( 'Name', $options[1][0]->title ); $this->assertSame( 'string', $options[1][0]->type ); $options = papi_get_options_and_properties( [ papi_property( [ 'type' => 'string', 'title' => 'Name', 'sidebar' => false, 'required' => true ] ) ] ); $this->assertSame( 'Name', $options[0]['title'] ); $this->assertSame( 'Name', $options[1][0]->title ); $this->assertSame( 'string', $options[1][0]->type ); $options = papi_get_options_and_properties( [ (object) [ 'options' => [ 'title' => 'Name' ] ] ] ); $this->assertSame( 'Name', $options[0]['title'] ); $options = papi_get_options_and_properties( ['title' => 'Test', 'context' => 'side'] ); $this->assertSame( ['title' => 'Test', 'context' => 'side'], $options[0] ); list( $options, $properties ) = papi_get_options_and_properties( [ 'title' => 'Content', 'properties' => [ papi_property( [ 'type' => 'string', 'title' => 'Name', ] ), ], ] ); $this->assertSame( [ 'title' => 'Content', ], $options ); $this->assertSame( 'Name', $properties[0]->title ); list( $options, $properties ) = papi_get_options_and_properties( PAPI_FIXTURE_DIR . '/page-types/boxes/big.php' ); $this->assertSame( [ 'title' => 'Content', ], $options ); $this->assertSame( 'Name', $properties[0]->title ); list( $options, $properties ) = papi_get_options_and_properties( [ 'title' => 'Content', 'props' => [ papi_property( [ 'type' => 'string', 'title' => 'Name', ] ), ], ] ); $this->assertSame( [ 'title' => 'Content', ], $options ); $this->assertSame( 'Name', $properties[0]->title ); } public function test_papi_get_property_class_name() { $this->assertSame( 'Papi_Property_String', papi_get_property_class_name( 'PropertyString' ) ); $this->assertSame( 'Papi_Property_String', papi_get_property_class_name( 'string' ) ); $this->assertSame( 'Papi_Property_Fake', papi_get_property_class_name( 'fake' ) ); $this->assertSame( 'Papi_Property_Test_Form_1', papi_get_property_class_name( 'test-form-1' ) ); $this->assertNull( papi_get_property_class_name( null ) ); $this->assertNull( papi_get_property_class_name( false ) ); $this->assertNull( papi_get_property_class_name( true ) ); $this->assertNull( papi_get_property_class_name( [] ) ); $this->assertNull( papi_get_property_class_name( new stdClass() ) ); $this->assertNull( papi_get_property_class_name( 1 ) ); } public function test_papi_get_property_type() { $this->assertTrue( papi_get_property_type( 'string' ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( null ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( 'fake' ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( 1 ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( true ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( false ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( [] ) instanceof Papi_Property_String ); $this->assertFalse( papi_get_property_type( new stdClass() ) instanceof Papi_Property_String ); $options = Papi_Core_Property::factory( [ 'type' => 'string' ] )->get_options(); $this->assertTrue( papi_get_property_type( $options ) instanceof Papi_Property_String ); } public function test_papi_get_property_type_custom() { require_once PAPI_FIXTURE_DIR . '/properties/class-papi-property-kvack.php'; $this->assertTrue( papi_get_property_type( 'kvack' ) instanceof Papi_Property_Kvack ); } public function test_papi_get_property_type_key() { $this->assertSame( 'image_property', papi_get_property_type_key( 'image' ) ); $this->assertSame( '_property', papi_get_property_type_key( null ) ); $this->assertSame( '_property', papi_get_property_type_key( false ) ); $this->assertSame( '_property', papi_get_property_type_key( true ) ); $this->assertSame( '_property', papi_get_property_type_key( [] ) ); $this->assertSame( '_property', papi_get_property_type_key( 1 ) ); $this->assertSame( '_property', papi_get_property_type_key( new stdClass() ) ); $this->assertSame( 'my_slug[0][key_property]', papi_get_property_type_key( 'my_slug[0][key]' ) ); } public function test_papi_get_property_type_f() { $this->assertSame( '_image_property', papi_get_property_type_key_f( 'image' ) ); $this->assertSame( '_property', papi_get_property_type_key_f( null ) ); $this->assertSame( '_property', papi_get_property_type_key_f( true ) ); $this->assertSame( '_property', papi_get_property_type_key_f( false ) ); $this->assertSame( '_property', papi_get_property_type_key_f( 1 ) ); $this->assertSame( '_property', papi_get_property_type_key_f( [] ) ); $this->assertSame( '_property', papi_get_property_type_key_f( new stdClass() ) ); } public function test_papi_is_property_type_key() { $this->assertTrue( papi_is_property_type_key( 'image_property' ) ); $this->assertTrue( papi_is_property_type_key( '_image_property' ) ); $this->assertFalse( papi_is_property_type_key( 'kvack' ) ); $this->assertFalse( papi_is_property_type_key( 1 ) ); $this->assertFalse( papi_is_property_type_key( false ) ); $this->assertFalse( papi_is_property_type_key( true ) ); } public function test_papi_render_property() { $property = papi_property( [ 'title' => 'Name' ] ); $this->assertEmpty( papi_render_property( $property ) ); $property = papi_property( [ 'type' => 'fake', 'title' => 'Name' ] ); $this->assertEmpty( papi_render_property( $property ) ); $user_id = $this->factory->user->create( ['role' => 'administrator'] ); wp_set_current_user( $user_id ); $_GET = ['lang' => 'se']; $property = papi_property( [ 'type' => 'string', 'title' => 'Name', 'lang' => 'dk', 'capabilities' => 'administrator' ] ); $this->assertEmpty( papi_render_property( $property ) ); $this->expectOutputRegex( '//' ); unset( $_GET ); $user_id = $this->factory->user->create( [ 'role' => 'read' ] ); wp_set_current_user( $user_id ); $property = papi_property( [ 'type' => 'string', 'title' => 'Name', 'capabilities' => 'administrator' ] ); $this->assertEmpty( papi_render_property( $property ) ); $this->expectOutputRegex( '//' ); wp_set_current_user( 0 ); } public function test_papi_render_required_property() { $property = papi_property( [ 'slug' => 'required_name', 'type' => 'string', 'title' => 'Name', 'required' => true ] ); papi_render_property( $property ); $this->expectOutputRegex( '/class\=\"papi\-rq\"/' ); } public function test_papi_render_properties() { $tab = papi_tab( 'Content', [] ); papi_render_properties( [ $tab ] ); $this->expectOutputRegex( '/class\=\"papi\-tabs\-wrapper\"/' ); $property = papi_property( [ 'type' => 'string', 'title' => 'Name' ] ); papi_render_properties( [ $property ] ); $this->expectOutputRegex( '/table\s*class\=\"papi\-table\"/' ); } public function test_papi_require_text() { $this->assertEmpty( papi_property_require_text( null ) ); $property = papi_property( [ 'type' => 'string', 'title' => 'Name', 'required' => true ] ); $this->assertSame( '(required field)', papi_property_require_text( $property ) ); } public function test_papi_required_html() { $this->assertEmpty( papi_property_required_html( null ) ); $property = papi_property( [ 'type' => 'string', 'title' => 'Name', 'required' => true ] ); $this->assertRegExp( '/class\=\"papi\-rq\"/', papi_property_required_html( $property ) ); } public function test_papi_populate_properties() { $this->assertEmpty( papi_populate_properties( [] ) ); $this->assertEmpty( papi_populate_properties( null ) ); $this->assertEmpty( papi_populate_properties( true ) ); $this->assertEmpty( papi_populate_properties( false ) ); $this->assertEmpty( papi_populate_properties( 1 ) ); $actual = papi_populate_properties( new stdClass() ); $this->assertTrue( is_object( $actual[0] ) ); $actual = papi_populate_properties( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertSame( 'Name', $actual[0]->title ); $this->assertSame( 'string', $actual[0]->type ); $this->assertSame( [ $actual[0] ], papi_populate_properties( $actual[0] ) ); $actual = papi_populate_properties( [ [ 'type' => 'string', 'title' => 'Name 1' ], [ 'type' => 'string', 'title' => 'Name 2' ] ] ); $this->assertSame( 'Name 1', $actual[0]->title ); $this->assertSame( 'string', $actual[0]->type ); $this->assertSame( 'Name 2', $actual[1]->title ); $this->assertSame( 'string', $actual[1]->type ); $tab = papi_tab( 'Content', [] ); $actual = papi_populate_properties( [$tab] ); $this->assertSame( 'Content', $actual[0]->title ); $this->assertEmpty( $actual[0]->properties ); $actual = papi_populate_properties( [ [ 'type' => 'string', 'title' => 'Name 1', 'sort_order' => 1 ], [ 'type' => 'string', 'title' => 'Name 3' ], [ 'type' => 'string', 'title' => 'Name 2', 'sort_order' => 0 ] ] ); $this->assertSame( 'Name 2', $actual[0]->title ); $this->assertSame( 'string', $actual[0]->type ); $this->assertSame( 'Name 1', $actual[1]->title ); $this->assertSame( 'string', $actual[1]->type ); $this->assertSame( 'Name 3', $actual[2]->title ); $this->assertSame( 'string', $actual[2]->type ); } public function test_papi_property() { $actual = papi_property( [ 'type' => 'string', 'title' => 'Name' ] ); $this->assertSame( 'Name', $actual->title ); $this->assertSame( 'string', $actual->type ); $this->assertNull( papi_property( [] ) ); $this->assertNull( papi_property( null ) ); $this->assertNull( papi_property( true ) ); $this->assertNull( papi_property( false ) ); $this->assertNull( papi_property( 1 ) ); } public function test_papi_property_template() { $actual = papi_property( PAPI_FIXTURE_DIR . '/properties/simple.php' ); $this->assertSame( 'Name', $actual->title ); $this->assertSame( 'string', $actual->type ); } public function test_papi_property_template_in_page_type() { add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); $page_type = papi_get_entry_type_by_id( 'name-page-type' ); $boxes = $page_type->get_boxes(); $properties = $boxes[0]->properties; $this->assertSame( 'papi_my_name_is', $properties[0]->get_slug() ); } public function test_papi_property_to_array_slugs() { $actual = papi_property_to_array_slugs( [ [ 'image' => 1, 'image_property' => 'image', 0 => false ] ], 'repeater' ); $expected = [ 'repeater' => 1, 'repeater_0_image' => 1, '_repeater_0_image_property' => 'image' ]; $this->assertEquals( $expected, $actual ); $actual = papi_property_to_array_slugs( [1, '', true, false], 'repeater' ); $expected = [ 'repeater' => 0 ]; $this->assertEquals( $expected, $actual ); } } ================================================ FILE: tests/cases/lib/core/slug-test.php ================================================ assertSame( 'papi_hello_world', papify( 'hello_world' ) ); $this->assertSame( 'papi_hello_world', papify( 'papi_hello_world' ) ); $this->assertSame( 'papi_hello_world', papify( '_hello_world' ) ); $this->assertEmpty( papify( null ) ); $this->assertEmpty( papify( true ) ); $this->assertEmpty( papify( false ) ); $this->assertEmpty( papify( 1 ) ); $this->assertEmpty( papify( [] ) ); $this->assertEmpty( papify( new stdClass ) ); } public function test_unpapify() { $this->assertSame( 'hello-world', unpapify( 'papi-hello-world' ) ); $this->assertEmpty( unpapify( null ) ); $this->assertEmpty( unpapify( true ) ); $this->assertEmpty( unpapify( false ) ); $this->assertEmpty( unpapify( 1 ) ); $this->assertEmpty( unpapify( [] ) ); $this->assertEmpty( unpapify( new stdClass() ) ); } } ================================================ FILE: tests/cases/lib/core/tabs-test.php ================================================ assertSame( 'Content', $tabs[0]->title ); $this->assertSame( 1000, $tabs[0]->sort_order ); $tabs = papi_tabs_setup( [1] ); $this->assertEmpty( $tabs ); $tabs = papi_tabs_setup( [] ); $this->assertEmpty( $tabs ); } /** * Test papi_tab. */ public function test_papi_tab() { $actual = papi_tab( 'Content', [ papi_property( [ 'type' => 'string', 'title' => 'Name' ] ) ] ); $this->assertTrue( $actual->tab ); $this->assertSame( 'Content', $actual->title ); $this->assertSame( 'Name', $actual->properties[0]->title ); $this->assertSame( 'string', $actual->properties[0]->type ); } } ================================================ FILE: tests/cases/lib/core/taxonomy-test.php ================================================ assertSame( 1, papi_get_term_id( 1 ) ); $this->assertSame( 1, papi_get_term_id( '1' ) ); $term_id = $this->factory->term->create(); $term = get_term( $term_id ); $this->assertSame( $term_id, papi_get_term_id( $term ) ); $_GET['term_id'] = $term_id; $this->assertSame( $term_id, papi_get_term_id() ); $this->assertSame( $term_id, papi_get_term_id( null ) ); unset( $_GET['term_id'] ); $_GET['tag_ID'] = $term_id; $this->assertSame( $term_id, papi_get_term_id() ); $this->assertSame( $term_id, papi_get_term_id( null ) ); unset( $_GET['tag_ID'] ); } public function test_papi_get_term_id_wp_query() { $term_id = $this->factory->term->create( ['slug' => 'category_test'] ); $term = get_term_by( 'slug', 'category_test', 'post_tag' ); $this->go_to( get_term_link( $term ) ); $this->assertSame( $term_id, papi_get_term_id() ); } public function test_papi_get_taxonomy() { $this->assertSame( '', papi_get_taxonomy() ); $_GET['taxonomy'] = 'post_tag'; $this->assertSame( 'post_tag', papi_get_taxonomy() ); $this->assertSame( 'post_tag', papi_get_taxonomy( null ) ); unset( $_GET['taxonomy'] ); $_GET['term_id'] = $this->factory->term->create(); $this->assertSame( get_term( $_GET['term_id'] )->taxonomy, papi_get_taxonomy() ); unset( $_GET['term_id'] ); } public function test_papi_get_taxonomy_label() { $this->assertSame( 'Categories', papi_get_taxonomy_label( 'category', 'name' ) ); $this->assertSame( 'Fake', papi_get_taxonomy_label( 'Fake', 'name', 'Fake' ) ); } } ================================================ FILE: tests/cases/lib/core/template-test.php ================================================ post_id = $this->factory->post->create( [ 'post_type' => 'page' ] ); } public function tearDown() { parent::tearDown(); unset( $this->post_id ); } public function test_papi_body_class() { global $post; $this->assertEmpty( papi_body_class( [] ) ); $post = get_post( $this->post_id ); $this->go_to( get_permalink( $this->post_id ) ); $this->assertEmpty( papi_body_class( [] ) ); update_post_meta( $this->post_id, papi_get_page_type_key(), '/' ); $this->assertEmpty( papi_body_class( [] ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'dot-page-type' ); $this->assertSame( ['custom-css-class', 'dot-page-type'], papi_body_class( [] ) ); } public function test_papi_get_template_file_name() { $this->assertNull( papi_get_template_file_name( '' ) ); $this->assertNull( papi_get_template_file_name( true ) ); $this->assertNull( papi_get_template_file_name( false ) ); $this->assertNull( papi_get_template_file_name( null ) ); $this->assertNull( papi_get_template_file_name( 1 ) ); $this->assertNull( papi_get_template_file_name( 0 ) ); $this->assertNull( papi_get_template_file_name( '' ) ); $this->assertNull( papi_get_template_file_name( [] ) ); $this->assertNull( papi_get_template_file_name( (object) [] ) ); $this->assertSame( 'hello.world.php', papi_get_template_file_name( 'hello.world' ) ); $this->assertSame( 'hello/world.php', papi_get_template_file_name( 'hello/world' ) ); $this->assertSame( 'hello/world.php', papi_get_template_file_name( 'hello/world.php' ) ); } public function test_papi_include_template() { $this->assertEmpty( papi_include_template( '' ) ); $this->assertEmpty( papi_include_template( 1 ) ); $this->assertEmpty( papi_include_template( null ) ); $this->assertEmpty( papi_include_template( [] ) ); $this->assertEmpty( papi_include_template( new stdClass ) ); $this->assertEmpty( papi_include_template( true ) ); $this->assertEmpty( papi_include_template( false ) ); $this->assertEmpty( papi_include_template( 'path/to/fake/file.php' ) ); papi_include_template( 'admin/views/add-new-page.php' ); $this->expectOutputRegex( '/Add New Page/' ); } public function test_papi_template() { $template = papi_template( PAPI_FIXTURE_DIR . '/properties/simple.php', [ 'lang' => 'se' ] ); $this->assertSame( 'Name', $template->title ); $this->assertSame( 'Name', $template->get_option( 'title' ) ); $this->assertSame( 'string', $template->type ); $this->assertSame( 'string', $template->get_option( 'type' ) ); $this->assertSame( 'se', $template->lang ); $this->assertSame( 'se', $template->get_option( 'lang' ) ); $this->assertEmpty( papi_template( '' ) ); $this->assertEmpty( papi_template( null ) ); $this->assertEmpty( papi_template( true ) ); $this->assertEmpty( papi_template( false ) ); $this->assertEmpty( papi_template( 1 ) ); $this->assertEmpty( papi_template( [] ) ); $this->assertEmpty( papi_template( new stdClass() ) ); $this->assertEmpty( papi_template( PAPI_FIXTURE_DIR ) ); $template = papi_template( PAPI_FIXTURE_DIR . '/properties/array.php', [], true ); $this->assertSame( 'Name', $template->title ); $this->assertSame( 'string', $template->type ); $this->assertEmpty( papi_template( 'hello' ) ); } public function test_papi_template_include() { global $post; $this->assertEmpty( apply_filters( 'template_include', '' ) ); $post = get_post( $this->post_id ); $this->go_to( get_permalink( $this->post_id ) ); $this->assertEmpty( apply_filters( 'template_include', '' ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); $this->assertEmpty( apply_filters( 'template_include', '' ) ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'twenty-page-type' ); $this->flush_cache(); $path = get_template_directory(); $path = trailingslashit( $path ); $path = apply_filters( 'template_include', '' ); $this->assertNotFalse( strpos( $path, 'functions.php' ) ); } public function test_filter_papi_template_include() { global $post; $this->assertEmpty( apply_filters( 'papi/template_include', '' ) ); $post = get_post( $this->post_id ); $this->go_to( get_permalink( $this->post_id ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); add_filter( 'papi/template_include', function () { return 'purus-risus-adipiscing-pharetramollis.php'; } ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); $this->assertEmpty( apply_filters( 'template_include', '' ) ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'twenty-page-type' ); $this->flush_cache(); $this->assertSame( 'purus-risus-adipiscing-pharetramollis.php', apply_filters( 'template_include', '' ) ); } public function test_filter_papi_pre_template_include() { global $post; $this->assertEmpty( apply_filters( 'papi/pre_template_include', '' ) ); $post = get_post( $this->post_id ); $this->go_to( get_permalink( $this->post_id ) ); add_filter( 'papi/settings/directories', function () { return [1, PAPI_FIXTURE_DIR . '/page-types']; } ); add_filter( 'papi/pre_template_include', function () { return 'pre-template.php'; } ); update_post_meta( $this->post_id, papi_get_page_type_key(), 'simple-page-type' ); $this->assertSame( 'pre-template.php', apply_filters( 'template_include', '' ) ); } } ================================================ FILE: tests/cases/lib/core/url-test.php ================================================ post_id = $this->factory->post->create(); } public function tearDown() { parent::tearDown(); unset( $this->post_id ); } public function test_papi_get_page_new_url() { $_SERVER['REQUEST_URI'] = ''; $url = papi_get_page_new_url( 'page', true, 'page' ); $this->assertNotFalse( strpos( $url, 'page_type=page&post_type=page' ) ); $url = papi_get_page_new_url( 'page', true, 'page', ['post_type'] ); $this->assertNotFalse( strpos( $url, 'page_type=page&post_type=page' ) ); } public function test_papi_append_post_type_query() { global $post; $url = papi_append_post_type_query( 'http://wordpress/?post_parent=1', 'post' ); $this->assertSame( 'http://wordpress/?post_parent=1&post_type=post', $url ); $post = get_post( $this->post_id ); $url = papi_append_post_type_query( 'http://wordpress/?post_parent=1' ); $this->assertSame( 'http://wordpress/?post_parent=1&post_type=post', $url ); $url = papi_append_post_type_query( 'http://wordpress/?post_parent=1&post_type=post' ); $this->assertSame( 'http://wordpress/?post_parent=1&post_type=post', $url ); $_GET['post_type'] = 'faq'; $url = papi_append_post_type_query( 'http://wordpress/?post_parent=1', 'post' ); $this->assertSame( 'http://wordpress/?post_parent=1&post_type=post', $url ); unset( $_GET['post_type'] ); } public function test_papi_append_post_type_query_fail() { $url = papi_append_post_type_query( 'http://wordpress/?post_parent=1' ); $this->assertSame( 'http://wordpress/?post_parent=1&post_type=post', $url ); } public function test_papi_include_query_strings() { $this->assertEmpty( papi_include_query_strings() ); $old_get = $_GET; $_GET = [ 'foo' => 'bar', 'baz' => 'boom', 'cow' => 'milk', 'php' => 'hypertext processor' ]; $this->assertEmpty( papi_include_query_strings( '?' ) ); $this->assertEmpty( papi_include_query_strings( '?', ['missing'] ) ); $this->assertSame( '?foo=bar', papi_include_query_strings( '?', ['foo'] ) ); $this->assertSame( '&baz=boom', papi_include_query_strings( '&', ['baz'] ) ); $this->assertSame( '?foo=bar&baz=boom', papi_include_query_strings( '?', ['foo', 'baz'] ) ); $this->assertSame( '?php=hypertext+processor', papi_include_query_strings( '?', ['php'] ) ); $_GET = $old_get; } } ================================================ FILE: tests/cases/lib/core/utilities-test.php ================================================ assertSame( 'fooBar', papi_camel_case( 'foo-bar' ) ); $this->assertSame( 'fooBar', papi_camel_case( 'foo bar' ) ); $this->assertSame( 'fooBar', papi_camel_case( 'foo_bar' ) ); $this->assertNull( papi_camel_case( null ) ); } public function test_papi_convert_to_string() { $this->assertSame( 'false', papi_convert_to_string( false ) ); $this->assertSame( 'true', papi_convert_to_string( true ) ); $this->assertSame( '0.1', papi_convert_to_string( 0.1 ) ); $this->assertSame( '1.1', papi_convert_to_string( 1.1 ) ); $this->assertSame( '0', papi_convert_to_string( 0 ) ); $this->assertEmpty( papi_convert_to_string( [] ) ); $this->assertEmpty( papi_convert_to_string( new stdClass() ) ); $this->assertNotEmpty( papi_convert_to_string( new ReflectionClass( 'ReflectionClass' ) ) ); $this->assertEmpty( papi_convert_to_string( Papi_Loader::instance() ) ); } public function test_papi_current_user_is_allowed() { $this->assertTrue( papi_current_user_is_allowed( null ) ); $this->assertTrue( papi_current_user_is_allowed( true ) ); $this->assertTrue( papi_current_user_is_allowed( false ) ); $this->assertTrue( papi_current_user_is_allowed( 1 ) ); $this->assertTrue( papi_current_user_is_allowed( new stdClass() ) ); $this->assertTrue( papi_current_user_is_allowed( [] ) ); $this->assertTrue( papi_current_user_is_allowed( '' ) ); $this->assertTrue( papi_current_user_is_allowed() ); $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); wp_set_current_user( $user_id ); $this->assertTrue( papi_current_user_is_allowed( 'administrator' ) ); $this->assertFalse( papi_current_user_is_allowed( 'administrator2' ) ); } public function test_papi_doing_ajax() { $out = papi_doing_ajax(); if ( $out ) { $this->assertTrue( $out ); } else { $this->assertFalse( $out ); } } public function test_papi_esc_html() { $this->assertSame( '<script>alert(1);</script>', papi_esc_html( '' ) ); $this->assertSame( [ '<script>alert(1);</script>' => 'hello world<script>alert(1);</script>' ], papi_esc_html( [ '' => 'hello world' ] ) ); $obj = new stdClass; $obj->title = ''; $obj2 = new stdClass; $obj2->title = '<script>alert(1);</script>'; $this->assertEquals( $obj2, papi_esc_html( $obj ) ); $obj = new stdClass; $obj->html = '
'; $obj->name = '

name

'; $obj2 = new stdClass; $obj2->html = '
'; $obj2->name = '<p>name</p>'; $this->assertEquals( $obj2, papi_esc_html( $obj, ['html'] ) ); $this->assertSame( [1], papi_esc_html( [1] ) ); } public function test_papi_f() { $this->assertSame( '_page', papi_f( 'page' ) ); $this->assertSame( '_page', papi_f( '_page' ) ); $this->assertEmpty( papi_f( null ) ); $this->assertEmpty( papi_f( true ) ); $this->assertEmpty( papi_f( false ) ); $this->assertEmpty( papi_f( 1 ) ); $this->assertEmpty( papi_f( [] ) ); $this->assertEmpty( papi_f( new stdClass() ) ); $this->assertSame( '__page', papi_f( 'page', 2 ) ); $this->assertSame( '__page', papi_f( '_page', 2 ) ); $this->assertSame( '__page', papi_f( '__page', 2 ) ); } public function test_papi_maybe_get_callable_value() { $this->assertSame( 'Hello', papi_maybe_get_callable_value( 'say_hello_stub' ) ); $this->assertSame( 'file', papi_maybe_get_callable_value( 'file' ) ); $this->assertSame( false, papi_maybe_get_callable_value( false ) ); $this->assertSame( 'Hello Fredrik', papi_maybe_get_callable_value( 'say_hello_name_stub', ['Fredrik'] ) ); $this->assertSame( 'Hello Fredrik', papi_maybe_get_callable_value( 'say_hello_name_stub', 'Fredrik' ) ); } public function test_papi_get_class_name() { $actual = papi_get_class_name( PAPI_FIXTURE_DIR . '/page-types/simple-page-type.php' ); $this->assertSame( 'Simple_Page_Type', $actual ); $this->assertEmpty( papi_get_class_name( null ) ); $this->assertEmpty( papi_get_class_name( true ) ); $this->assertEmpty( papi_get_class_name( false ) ); $this->assertEmpty( papi_get_class_name( 1 ) ); $this->assertEmpty( papi_get_class_name( [] ) ); $this->assertEmpty( papi_get_class_name( new stdClass() ) ); $actual = papi_get_class_name( PAPI_FIXTURE_DIR . '/page-types/namespace-page-type.php' ); $this->assertSame( '\Foo\Bar\Namespace_Page_Type', $actual ); } public function test_papi_get_lang() { $lang = papi_get_lang(); $this->assertEmpty( $lang ); $_GET['lang'] = 'sv'; $lang = papi_get_lang(); $this->assertSame( 'sv', $lang ); add_filter( 'papi/lang', function () { return 'en'; } ); $lang = papi_get_lang(); $this->assertSame( 'en', $lang ); unset( $_GET['lang'] ); } public function test_papi_get_only_objects() { $actual = true; $items = papi_get_only_objects( [ 1, 3, new stdClass, 'hej', [] ] ); foreach ( $items as $item ) { $actual = is_object( $item ); if ( ! $actual ) { break; } } $this->assertTrue( $actual ); } public function test_papi_get_or_post() { $_GET['world'] = 'hello'; $this->assertSame( 'hello', papi_get_or_post( 'world' ) ); unset( $_GET['world'] ); $_POST['world'] = 'hello'; $this->assertSame( 'hello', papi_get_or_post( 'world' ) ); unset( $_POST['world'] ); $this->assertEmpty( papi_get_or_post( null ) ); $this->assertEmpty( papi_get_or_post( true ) ); $this->assertEmpty( papi_get_or_post( false ) ); $this->assertEmpty( papi_get_or_post( 1 ) ); $this->assertEmpty( papi_get_or_post( [] ) ); $this->assertEmpty( papi_get_or_post( new stdClass() ) ); $this->assertEMpty( papi_get_or_post( 'trams' ) ); } public function test_papi_get_qs() { $_GET['page'] = 1; $this->assertSame( 1, papi_get_qs( 'page' ) ); unset( $_GET['page'] ); $_GET['page'] = 'papi/option/options/header-option-type'; $this->assertSame( 'options/header-option-type', papi_get_qs( 'page' ) ); unset( $_GET['page'] ); $this->assertEmpty( papi_get_qs( null ) ); $this->assertEmpty( papi_get_qs( true ) ); $this->assertEmpty( papi_get_qs( false ) ); $this->assertEmpty( papi_get_qs( 1 ) ); $this->assertEmpty( papi_get_qs( [] ) ); $this->assertEmpty( papi_get_qs( new stdClass() ) ); $this->assertEmpty( papi_get_qs( '' ) ); $_GET['good'] = 'true'; $_GET['bad'] = 'false'; $qs = papi_get_qs( [ 'good', 'bad' ], true ); $qs2 = [ 'good' => true, 'bad' => false ]; $this->assertSame( $qs, $qs2 ); } public function test_papi_get_sanitized_post() { $this->assertEmpty( papi_get_sanitized_post( 'hello' ) ); $_POST['hello'] = '<'; $this->assertSame( '<', papi_get_sanitized_post( 'hello' ) ); unset( $_POST['hello'] ); $_POST['tag'] = ''; $this->assertEmpty( papi_get_sanitized_post( 'tag' ) ); unset( $_POST['tag'] ); } public function test_papi_html_name() { $this->assertSame( 'papi_hello_world_aao', papi_html_name( 'hello world åäö' ) ); $this->assertSame( 'papi_hello', papi_html_name( 'papi_hello' ) ); $this->assertSame( '_papi_hello', papi_html_name( '_papi_hello' ) ); $this->assertSame( 'papi_hello[0][image]', papi_html_name( 'papi_hello[0][image]' ) ); $this->assertSame( 'papi_hello[image]', papi_html_name( 'papi_hello[image]' ) ); $this->assertEmpty( papi_html_name( null ) ); $this->assertEmpty( papi_html_name( true ) ); $this->assertEmpty( papi_html_name( false ) ); $this->assertEmpty( papi_html_name( 1 ) ); $this->assertEmpty( papi_html_name( [] ) ); $this->assertEmpty( papi_html_name( new stdClass() ) ); } public function test_papi_html_tag() { $this->assertSame( '', papi_html_tag( 'label', [ 'for' => 'test', 'hello' ] ) ); $this->assertSame( '', papi_html_tag( 'label', [ 'for' => (object) [], 'hello' ] ) ); $this->assertSame( '', papi_html_tag( 'label', [ 'for' => 'true', 'hello' ] ) ); $this->assertSame( '', papi_html_tag( 'label', [ 'for' => false, 'hello' ] ) ); $this->assertSame( '', papi_html_tag( 'label', [ 'for' => (object) [], ['hello', 'world'] ] ) ); $this->assertSame( '