├── .buildkite ├── pipeline.sh └── pipeline.yml ├── .distignore ├── .editorconfig ├── .gitignore ├── CONTRIBUTING.md ├── Gruntfile.js ├── README.md ├── bin ├── install-wp-tests.sh ├── run-tests-internal-only.sh └── run-tests-local.sh ├── composer.json ├── composer.lock ├── docker-compose-phpunit.yml ├── package.json ├── phpunit.xml ├── readme.txt ├── sugar-calendar-lite.php ├── sugar-calendar ├── includes │ ├── admin │ │ ├── assets.php │ │ ├── assets │ │ │ ├── css │ │ │ │ ├── ltr │ │ │ │ │ ├── chosen.css │ │ │ │ │ ├── sc-calendar.css │ │ │ │ │ ├── sc-chosen.css │ │ │ │ │ ├── sc-datepicker.css │ │ │ │ │ ├── sc-menu.css │ │ │ │ │ ├── sc-meta-box.css │ │ │ │ │ ├── sc-nav.css │ │ │ │ │ ├── sc-settings.css │ │ │ │ │ └── sc-taxonomy.css │ │ │ │ ├── min │ │ │ │ │ ├── ltr │ │ │ │ │ │ ├── chosen.css │ │ │ │ │ │ ├── sc-calendar.css │ │ │ │ │ │ ├── sc-chosen.css │ │ │ │ │ │ ├── sc-datepicker.css │ │ │ │ │ │ ├── sc-menu.css │ │ │ │ │ │ ├── sc-meta-box.css │ │ │ │ │ │ ├── sc-nav.css │ │ │ │ │ │ ├── sc-settings.css │ │ │ │ │ │ └── sc-taxonomy.css │ │ │ │ │ └── rtl │ │ │ │ │ │ ├── chosen.css │ │ │ │ │ │ ├── sc-calendar.css │ │ │ │ │ │ ├── sc-chosen.css │ │ │ │ │ │ ├── sc-datepicker.css │ │ │ │ │ │ ├── sc-menu.css │ │ │ │ │ │ ├── sc-meta-box.css │ │ │ │ │ │ ├── sc-nav.css │ │ │ │ │ │ ├── sc-settings.css │ │ │ │ │ │ └── sc-taxonomy.css │ │ │ │ └── rtl │ │ │ │ │ ├── chosen.css │ │ │ │ │ ├── sc-calendar.css │ │ │ │ │ ├── sc-chosen.css │ │ │ │ │ ├── sc-datepicker.css │ │ │ │ │ ├── sc-menu.css │ │ │ │ │ ├── sc-meta-box.css │ │ │ │ │ ├── sc-nav.css │ │ │ │ │ ├── sc-settings.css │ │ │ │ │ └── sc-taxonomy.css │ │ │ ├── images │ │ │ │ ├── bfcm-header.svg │ │ │ │ └── sugar-calendar-logo-light.svg │ │ │ └── js │ │ │ │ ├── chosen.js │ │ │ │ ├── sc-admin.js │ │ │ │ ├── sc-calendar.js │ │ │ │ ├── sc-meta-box.js │ │ │ │ ├── sc-settings.js │ │ │ │ ├── sc-taxonomy.js │ │ │ │ ├── term-color.js │ │ │ │ └── term-timezone.js │ │ ├── editor.php │ │ ├── general.php │ │ ├── help.php │ │ ├── hooks.php │ │ ├── list-tables │ │ │ ├── class-wp-list-table-base.php │ │ │ ├── class-wp-list-table-day.php │ │ │ ├── class-wp-list-table-list.php │ │ │ ├── class-wp-list-table-month.php │ │ │ └── class-wp-list-table-week.php │ │ ├── menu.php │ │ ├── meta-boxes.php │ │ ├── meta-boxes │ │ │ ├── class-wp-meta-box-section.php │ │ │ ├── class-wp-meta-box.php │ │ │ └── class-wp-walker-category-radio.php │ │ ├── nav.php │ │ ├── posts.php │ │ ├── screen-options.php │ │ ├── settings.php │ │ └── upgrades.php │ ├── classes │ │ ├── database │ │ │ ├── engine │ │ │ │ ├── Base.php │ │ │ │ ├── Column.php │ │ │ │ ├── Queries │ │ │ │ │ ├── Compare.php │ │ │ │ │ ├── Date.php │ │ │ │ │ └── Meta.php │ │ │ │ ├── Query.php │ │ │ │ ├── Row.php │ │ │ │ ├── Schema.php │ │ │ │ └── Table.php │ │ │ └── events │ │ │ │ ├── Query.php │ │ │ │ ├── Row.php │ │ │ │ ├── Schema.php │ │ │ │ ├── TableEventmeta.php │ │ │ │ └── TableEvents.php │ │ ├── terms │ │ │ ├── class-term-colors.php │ │ │ └── class-term-timezones.php │ │ └── utilities │ │ │ ├── class-term-meta-ui.php │ │ │ ├── ical-rrule-sequencer.php │ │ │ ├── ical-to-array.php │ │ │ └── trait-date-collider.php │ ├── common │ │ ├── assets.php │ │ ├── color.php │ │ ├── editor.php │ │ ├── general.php │ │ ├── hooks.php │ │ ├── preferences.php │ │ ├── settings.php │ │ ├── time-zones.php │ │ └── time.php │ ├── events │ │ ├── capabilities.php │ │ ├── functions.php │ │ ├── meta-data.php │ │ └── relationships.php │ ├── languages │ │ └── sugar-calendar.pot │ ├── post │ │ ├── cron.php │ │ ├── feed.php │ │ ├── functions.php │ │ ├── meta.php │ │ ├── query-filters.php │ │ ├── relationship.php │ │ ├── taxonomies.php │ │ └── types.php │ └── themes │ │ └── legacy │ │ ├── ajax.php │ │ ├── calendar.php │ │ ├── css │ │ └── sc-events.css │ │ ├── event-display.php │ │ ├── events-list.php │ │ ├── functions.php │ │ ├── hooks.php │ │ ├── js │ │ ├── sc-ajax.js │ │ └── sc-time-zones.js │ │ ├── scripts.php │ │ ├── shortcodes.php │ │ └── widgets.php ├── requirements-check.php └── sugar-calendar.php └── tests ├── README.md └── phpunit ├── bootstrap.php ├── listener-loader.php ├── phpunit7 └── speed-trap-listener.php ├── speed-trap-listener.php └── testcases ├── admin └── tests-meta-box.php ├── common └── tests-time-zones.php ├── legacy ├── tests-options.php └── tests-settings.php └── post └── tests-taxonomy.php /.buildkite/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # exit immediately on failure, or if an undefined variable is used 4 | set -eu 5 | 6 | # begin the pipeline.yml file 7 | echo "steps:" 8 | 9 | phpVersions=('7.0' '7.1' '7.2' '7.3' '7.4') 10 | wpVersions=('5.5.3' '5.6.3' '5.7.2' 'latest') 11 | 12 | # Exclude combinations with - 13 | exclusions=('7.4-5.2.7') 14 | 15 | # add a new command step to run the tests in each test directory 16 | for phpVersion in ${phpVersions[@]}; do 17 | for wpVersion in ${wpVersions[@]}; do 18 | 19 | if [[ " ${exclusions[@]} " =~ " ${phpVersion}-${wpVersion} " ]]; then 20 | continue 21 | fi 22 | 23 | echo " - env:" 24 | echo " TEST_INPLACE: \"0\"" 25 | echo " TEST_PHP_VERSION: \""$phpVersion"\"" 26 | echo " TEST_WP_VERSION: "$wpVersion"" 27 | echo " WP_MULTISITE: \"0\"" 28 | echo " label: 'PHP: "$phpVersion" | WP: "$wpVersion" | Multisite: No'" 29 | echo " agents:" 30 | echo " queue: \"sc\"" 31 | echo " plugins:" 32 | echo " - docker-compose#v3.7.0:" 33 | echo " config: docker-compose-phpunit.yml" 34 | echo " env:" 35 | echo " - WP_MULTISITE" 36 | echo " - TEST_INPLACE" 37 | echo " propagate-uid-gid: true" 38 | echo " pull-retries: 3" 39 | echo " run: wordpress" 40 | done 41 | done 42 | 43 | echo " - env:" 44 | echo " TEST_INPLACE: \"0\"" 45 | echo " TEST_PHP_VERSION: \""$phpVersion"\"" 46 | echo " TEST_WP_VERSION: "$wpVersion"" 47 | echo " WP_MULTISITE: \"1\"" 48 | echo " label: 'PHP: "$phpVersion" | WP: "$wpVersion" | Multisite: Yes'" 49 | echo " agents:" 50 | echo " queue: \"sc\"" 51 | echo " plugins:" 52 | echo " - docker-compose#v3.7.0:" 53 | echo " config: docker-compose-phpunit.yml" 54 | echo " env:" 55 | echo " - WP_MULTISITE" 56 | echo " - TEST_INPLACE" 57 | echo " propagate-uid-gid: true" 58 | echo " pull-retries: 3" 59 | echo " run: wordpress" -------------------------------------------------------------------------------- /.buildkite/pipeline.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | 3 | - label: "Pull PHP 7.0" 4 | command: "docker pull public.ecr.aws/q7y6e9n2/unit-test-images/php:7.0" 5 | retry: 6 | automatic: true 7 | agents: 8 | queue: "sc" 9 | 10 | - label: "Pull PHP 7.1" 11 | command: "docker pull public.ecr.aws/q7y6e9n2/unit-test-images/php:7.1" 12 | retry: 13 | automatic: true 14 | agents: 15 | queue: "sc" 16 | 17 | - wait 18 | 19 | - label: "Pull PHP 7.2" 20 | command: "docker pull public.ecr.aws/q7y6e9n2/unit-test-images/php:7.2" 21 | retry: 22 | automatic: true 23 | agents: 24 | queue: "sc" 25 | 26 | - label: "Pull PHP 7.3" 27 | command: "docker pull public.ecr.aws/q7y6e9n2/unit-test-images/php:7.3" 28 | retry: 29 | automatic: true 30 | agents: 31 | queue: "sc" 32 | 33 | - wait 34 | 35 | - label: "Pull PHP 7.4" 36 | command: "docker pull public.ecr.aws/q7y6e9n2/unit-test-images/php:7.4" 37 | retry: 38 | automatic: true 39 | agents: 40 | queue: "sc" 41 | 42 | - label: "Pull MariaDB" 43 | command: "docker pull mariadb:10.2" 44 | retry: 45 | automatic: true 46 | agents: 47 | queue: "sc" 48 | 49 | - wait 50 | 51 | - command: .buildkite/pipeline.sh | buildkite-agent pipeline upload 52 | label: ":pipeline: Upload" 53 | agents: 54 | queue: "sc" -------------------------------------------------------------------------------- /.distignore: -------------------------------------------------------------------------------- 1 | # A set of files you probably don't want in your WordPress.org distribution 2 | .babelrc 3 | .deployignore 4 | .distignore 5 | .editorconfig 6 | .eslintignore 7 | .eslintrc 8 | .git 9 | .gitignore 10 | .gitlab-ci.yml 11 | .travis.yml 12 | .DS_Store 13 | Thumbs.db 14 | behat.yml 15 | bitbucket-pipelines.yml 16 | bin 17 | .circleci/config.yml 18 | composer.json 19 | composer.lock 20 | dependencies.yml 21 | Gruntfile.js 22 | package.json 23 | package-lock.json 24 | phpunit.xml 25 | phpunit.xml.dist 26 | multisite.xml 27 | multisite.xml.dist 28 | .phpcs.xml 29 | phpcs.xml 30 | .phpcs.xml.dist 31 | phpcs.xml.dist 32 | README.md 33 | webpack.config.js 34 | wp-cli.local.yml 35 | yarn.lock 36 | tests 37 | vendor 38 | node_modules 39 | *.sql 40 | *.tar.gz 41 | *.zip 42 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | indent_size = 4 16 | 17 | [{.jshintrc,*.json,*.yml}] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | [{*.txt,wp-config-sample.php}] 22 | end_of_line = crlf 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Configuration files with possibly sensitive information 2 | .htaccess 3 | 4 | # Standard files 5 | /sugar-calendar.php 6 | /sugar-calendar/includes/standard 7 | 8 | # Files and folders related to build/test tools 9 | /phpunit.xml 10 | /tests/phpunit/build 11 | /node_modules 12 | /npm-debug.log 13 | 14 | # Output directory. 15 | /build 16 | 17 | # Operating system specific files 18 | .DS_Store 19 | Thumbs.db 20 | ehthumbs.db 21 | Desktop.ini 22 | $RECYCLE.BIN/ 23 | 24 | # Ignore other .gitignore files to allow for personal customizations 25 | .gitignore 26 | 27 | # Sublime 28 | *.sublime-project 29 | *.sublime-workspace 30 | 31 | # PhpStorm 32 | .idea 33 | Sugar-Calendar.iml 34 | 35 | # Eclipse 36 | *.pydevproject 37 | .project 38 | .metadata 39 | build/ 40 | tmp/ 41 | tests/clover.xml 42 | 43 | # Node 44 | node_modules 45 | pnpm-lock.yaml 46 | 47 | # Vendor 48 | /vendor 49 | 50 | # Temporary files 51 | *~ 52 | 53 | # File types that do not belong 54 | *.sql 55 | *.tar.gz 56 | *.zip 57 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contribute To Sugar Calendar 2 | 3 | Community made patches, localizations, bug reports and contributions are always welcome and are crucial to ensure Sugar Calendar remains the #1 event calendar for WordPress. 4 | 5 | When contributing, please ensure you follow the guidelines below so that we can keep on top of things. 6 | 7 | __Please Note:__ GitHub is for bug reports and contributions only - if you have a support question or a request for a customization don't post here; go to our [Support page](https://sugarcalendar.com/support/) instead. 8 | 9 | ## Getting Started 10 | 11 | * __Do not report potential security vulnerabilities here. Email them privately to our security team at [security@sugarcalendar.com](mailto:security@sugarcalendar.com)__ 12 | * Before submitting a ticket, please be sure to replicate the behavior with no other plugins active and on a base theme like Twenty Twenty. 13 | * Submit a ticket for your issue, assuming one does not already exist. 14 | * Raise it on our [Issue Tracker](https://github.com/sugarcalendar/core/issues) 15 | * Clearly describe the issue including steps to reproduce the bug. 16 | * Make sure you fill in the earliest version that you know has the issue as well as the version of WordPress you're using. 17 | 18 | ## Making Changes 19 | 20 | * Fork the repository on GitHub 21 | * Make the changes to your forked repository 22 | * Ensure you stick to the [WordPress Coding Standards](https://codex.wordpress.org/WordPress_Coding_Standards) 23 | * When committing, reference your issue (if present) and include a note about the fix 24 | * If possible, and if applicable, please also add/update unit tests for your changes 25 | * Push the changes to your fork and submit a pull request to the proper branch of the repository (likely master, but maybe a `release/` branch) 26 | 27 | ## Code Documentation 28 | 29 | * We ensure that every function is documented well and follows the standards set by phpDoc 30 | * An example function can be found [here](https://github.com/sugarcalendar/core/blob/master/sugar-calendar/includes/events/functions.php#L138) 31 | * Please make sure that every function is documented so that when we update our API Documentation things don't go awry! 32 | * If you're adding/editing a function in a class, make sure to add `@access {private|public|protected}` 33 | * Finally, please use tabs and not spaces. The tab indent size should be 4 for all languages: PHP, JavaScript, and CSS. 34 | 35 | At this point you're waiting on us to merge your pull request. We'll review every pull request and make suggestions or changes if necessary. 36 | 37 | ## Developer Certificate of Origin 38 | By contributing to Sugar Calendar, you agree to the Developer Certificate of Origin. 39 | 40 | In its simplest form, the DCO states that you have permission to supply the code submitted to Sugar Calendar. Here is the DCO in detail: 41 | ``` 42 | Developer Certificate of Origin 43 | Version 1.1 44 | 45 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 46 | 1 Letterman Drive 47 | Suite D4700 48 | San Francisco, CA, 94129 49 | 50 | Everyone is permitted to copy and distribute verbatim copies of this 51 | license document, but changing it is not allowed. 52 | 53 | 54 | Developer's Certificate of Origin 1.1 55 | 56 | By making a contribution to this project, I certify that: 57 | 58 | (a) The contribution was created in whole or in part by me and I 59 | have the right to submit it under the open source license 60 | indicated in the file; or 61 | 62 | (b) The contribution is based upon previous work that, to the best 63 | of my knowledge, is covered under an appropriate open source 64 | license and I have the right under that license to submit that 65 | work with modifications, whether created in whole or in part 66 | by me, under the same open source license (unless I am 67 | permitted to submit under a different license), as indicated 68 | in the file; or 69 | 70 | (c) The contribution was provided directly to me by some other 71 | person who certified (a), (b) or (c) and I have not modified 72 | it. 73 | 74 | (d) I understand and agree that this project and the contribution 75 | are public and that a record of the contribution (including all 76 | personal information I submit with it, including my sign-off) is 77 | maintained indefinitely and may be redistributed consistent with 78 | this project or the open source license(s) involved. 79 | ``` 80 | 81 | # Additional Resources 82 | * [Developer's API](https://sugarcalendar.com/docs/developers/) 83 | * [General GitHub Documentation](https://help.github.com/) 84 | * [GitHub Pull Request documentation](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) 85 | * [PHPUnit Tests Guide](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html) 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Sugar Calendar](https://sugarcalendar.com) # 2 | 3 | [![Build status](https://badge.buildkite.com/80a91dff42e83fa09a0b68ed75b93c26920d619d46694d01c0.svg)](https://buildkite.com/sandhills-development-llc/sugar-calendar) 4 | 5 | Sugar Calendar is a commercial WordPress plugin by [Awesome Motive, Inc.](https://awesomemotive.com). It comes in two flavors: 6 | 7 | * Lite: free forever on WordPress.org 8 | * Standard: includes Recurring Events and access to Pro add-ons, for purchase at [SugarCalendar.com](https://sugarcalendar.com) 9 | 10 | Development happens here on GitHub to better facilitate contributions from our community of users, writers, developers, designers, and you. If you have an idea, suggestion, bug report, patch, or pull request, please feel free to submit it here. 11 | 12 | If you enjoy using Sugar Calendar, please consider purchasing a license key from the [Sugar Calendar website](https://sugarcalendar.com). 13 | -------------------------------------------------------------------------------- /bin/install-wp-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ $# -lt 3 ]]; then 4 | echo "usage: $0 [db-host] [wp-version] [force download]" 5 | exit 1 6 | fi 7 | 8 | DB_NAME="$1" 9 | DB_USER="$2" 10 | DB_PASS="$3" 11 | DB_HOST="$4" 12 | WP_VERSION="$5" 13 | FORCE="$6" 14 | 15 | # Account for these variables being empty not just missing 16 | if [[ -z "$4" ]]; then 17 | DB_HOST=localhost 18 | fi 19 | if [[ -z "$5" ]]; then 20 | WP_VERSION=latest 21 | fi 22 | if [[ -z "$6" ]]; then 23 | FORCE=false 24 | fi 25 | 26 | WP_TESTS_DIR="${WP_TESTS_DIR-/tmp/wordpress-tests-lib}" 27 | WP_CORE_DIR="${WP_CORE_DIR-/tmp/wordpress/}" 28 | 29 | echo "WP_TESTS_DIR: ${WP_TESTS_DIR}"; 30 | echo "WP_CORE_DIR: ${WP_CORE_DIR}"; 31 | 32 | download() { 33 | curl -s "$1" > "$2"; 34 | } 35 | 36 | if [[ "$WP_VERSION" =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then 37 | WP_TESTS_TAG="tags/$WP_VERSION" 38 | else 39 | # http serves a single offer, whereas https serves multiple. we only want one 40 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json 41 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json 42 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') 43 | if [[ -z "$LATEST_VERSION" ]]; then 44 | echo "Latest WordPress version could not be found" 45 | exit 1 46 | fi 47 | WP_TESTS_TAG="tags/$LATEST_VERSION" 48 | fi 49 | 50 | if [[ "$WP_TESTS_TAG" == *"beta"* ]] 51 | then 52 | WP_TESTS_TAG="trunk" 53 | fi 54 | 55 | set -ex 56 | 57 | install_wp() { 58 | if [[ "$FORCE" == 'true' ]]; then 59 | rm -Rf "$WP_CORE_DIR" 60 | fi 61 | 62 | if [[ -d "$WP_CORE_DIR" ]]; then 63 | return; 64 | fi 65 | 66 | mkdir -p "$WP_CORE_DIR" 67 | 68 | if [[ "$WP_VERSION" == 'latest' ]]; then 69 | local ARCHIVE_NAME='latest' 70 | else 71 | local ARCHIVE_NAME="wordpress-$WP_VERSION" 72 | fi 73 | 74 | download "https://wordpress.org/${ARCHIVE_NAME}.tar.gz" /tmp/wordpress.tar.gz 75 | tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C "$WP_CORE_DIR" 76 | 77 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php "$WP_CORE_DIR/wp-content/db.php" 78 | } 79 | 80 | install_test_suite() { 81 | if [[ "$FORCE" == 'true' ]]; then 82 | rm -Rf "$WP_TESTS_DIR" 83 | fi 84 | 85 | # portable in-place argument for both GNU sed and Mac OSX sed 86 | if [[ "$(uname -s)" == 'Darwin' ]]; then 87 | local ioption='-i .bak' 88 | else 89 | local ioption='-i' 90 | fi 91 | 92 | # set up testing suite if it doesn't yet exist 93 | if [[ ! -d $WP_TESTS_DIR ]]; then 94 | # set up testing suite 95 | mkdir -p "$WP_TESTS_DIR" 96 | svn co --quiet "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/" "$WP_TESTS_DIR/includes" 97 | svn co --quiet "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/" "$WP_TESTS_DIR/data" 98 | fi 99 | 100 | cd $WP_TESTS_DIR 101 | 102 | if [[ ! -f wp-tests-config.php ]]; then 103 | download "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php" "$WP_TESTS_DIR"/wp-tests-config.php 104 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php 105 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php 106 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php 107 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php 108 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php 109 | fi 110 | 111 | } 112 | 113 | install_wp 114 | install_test_suite 115 | -------------------------------------------------------------------------------- /bin/run-tests-internal-only.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [[ $# -lt 3 ]]; then 6 | echo "usage: $0 [db-host] [wp-version] [force download]" 7 | exit 1 8 | fi 9 | 10 | DB_NAME="$1" 11 | DB_USER="$2" 12 | DB_PASS="$3" 13 | DB_HOST="${4-localhost}" 14 | WP_VERSION="${5-latest}" 15 | FORCE="${6-false}" 16 | 17 | bin/install-wp-tests.sh "${DB_NAME}" "${DB_USER}" "${DB_PASS}" "${DB_HOST}" "${WP_VERSION}" "${FORCE}" 18 | 19 | # Default to copying the repo elsewhere 20 | if [[ "${TEST_INPLACE:-x}" == "x" ]] || [[ "${TEST_INPLACE}" == "0" ]]; then 21 | REPO_DIR="/tmp/$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)" 22 | echo "Copying repo to ${REPO_DIR} to and deleting composer files..." 23 | mkdir "${REPO_DIR}" 24 | cp -R . "${REPO_DIR}" 25 | cd "${REPO_DIR}" 26 | if [[ -d vendor ]]; then 27 | rm -rf vendor 28 | fi 29 | if [[ -f composer.lock ]]; then 30 | rm composer.lock 31 | fi 32 | else 33 | echo "Running inplace..." 34 | fi 35 | 36 | composer --no-cache install 37 | vendor/bin/phpunit 38 | -------------------------------------------------------------------------------- /bin/run-tests-local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | OPTS=$(getopt -a --options w:p:imh --longoptions wp:,php:,multisite,in-place,help --name "$0" -- "$@") || exit 1 6 | eval set -- "$OPTS" 7 | 8 | show_help() { 9 | printf -- 'Usage: %s --php|-p PHP_VERSION --wp|-w WP_VERSION [OPTIONS]\n\n' "$0"; 10 | 11 | echo "Options:"; 12 | printf -- '-i, --in-place\t\tDoes tests in-place without copying the repo to another dir and nuking composer files. This is faster but will add composer.lock/vendor dirs to your checkout. (Default: no)\n'; 13 | printf -- '-m, --multisite\t\tRun tests as multisite?\n'; 14 | printf -- '-p, --php\t\tSets the PHP version to test with (Required)\n'; 15 | printf -- '-w, --wp\t\tSets WP version to test against (Required)\n'; 16 | printf -- '-h, --help\t\tShow help.\n'; 17 | } 18 | 19 | while true; do 20 | case "$1" in 21 | --in-place|-i ) 22 | TEST_INPLACE=1 23 | shift 24 | ;; 25 | --multisite|-m ) 26 | TEST_WP_MULTISITE="1" 27 | shift 28 | ;; 29 | --php|-p ) 30 | export TEST_PHP_VERSION="$2" 31 | shift 2 32 | ;; 33 | --wp|-w ) 34 | export TEST_WP_VERSION="$2" 35 | shift 2 36 | ;; 37 | --help|-h ) 38 | show_help 39 | exit 0 40 | shift 41 | ;; 42 | --) 43 | shift 44 | break 45 | ;; 46 | *) 47 | show_help 48 | exit 1 49 | ;; 50 | esac 51 | done 52 | 53 | if [[ -z "${TEST_PHP_VERSION}" ]] || [[ -z "${TEST_WP_VERSION}" ]]; then 54 | show_help; 55 | exit 1; 56 | fi 57 | 58 | # Default WP_MULTISITE to 0 59 | export WP_MULTISITE="${TEST_WP_MULTISITE:-0}" 60 | # Default TEST_INPLACE to 0 61 | export TEST_INPLACE="${TEST_INPLACE:-0}" 62 | 63 | # Create a random project name 64 | export COMPOSE_PROJECT_NAME="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)" 65 | 66 | # Do this to make sure we cleanup 67 | set +e 68 | docker-compose -f docker-compose-phpunit.yml run -e "TEST_INPLACE=${TEST_INPLACE}" --rm --user $(id -u):$(id -g) wordpress 69 | docker-compose -f docker-compose-phpunit.yml down --remove-orphans 70 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sugarcalendar/core", 3 | "type": "wordpress-plugin", 4 | "description": "Sugar Calendar Plugin for WordPress", 5 | "keywords": ["wordpress", "sugarcalendar", "calendar", "events"], 6 | "homepage": "https://sugarcalendar.com", 7 | "license": "GPL-2.0+", 8 | "require": { 9 | "php": ">=7.0.0", 10 | "composer/installers": "~1.0" 11 | }, 12 | "require-dev": { 13 | "phpunit/phpunit": "4.8.* || 5.7.*" 14 | }, 15 | "minimum-stability": "dev" 16 | } 17 | -------------------------------------------------------------------------------- /docker-compose-phpunit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.7" 3 | services: 4 | wordpress: 5 | image: public.ecr.aws/q7y6e9n2/unit-test-images/php:${TEST_PHP_VERSION} 6 | depends_on: 7 | - mysql 8 | volumes: 9 | - .:/app 10 | working_dir: /app 11 | command: [ "bin/run-tests-internal-only.sh", "wordpress_test", "root", "", "mysql", "${TEST_WP_VERSION}" ] 12 | mysql: 13 | image: mariadb:10.2 14 | environment: 15 | MYSQL_ALLOW_EMPTY_PASSWORD: "yes" 16 | MYSQL_DATABASE: "wordpress_test" 17 | MYSQL_ROOT_PASSWORD: "" 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sugar-calendar", 3 | "version": "2.2.4", 4 | "description": "A calendar with a sweet disposition.", 5 | "private": true, 6 | "license": "GPL-2.0-or-later", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/sugarcalendar/core/" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/sugarcalendar/core/issues" 13 | }, 14 | "homepage": "https://sugarcalendar.com", 15 | "engines": { 16 | "node": ">=8.0.0", 17 | "npm": ">=6.0.0" 18 | }, 19 | "babel": { 20 | "presets": [ 21 | "@wordpress/babel-preset-default" 22 | ] 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "plugin:@wordpress/eslint-plugin/recommended" 27 | ] 28 | }, 29 | "dependencies": { 30 | "chosen-js": "^1.8.7" 31 | }, 32 | "devDependencies": { 33 | "@babel/core": "^7.15.5", 34 | "@wordpress/babel-preset-default": "^4.20.0", 35 | "@wordpress/browserslist-config": "^2.7.0", 36 | "@wordpress/eslint-plugin": "^2.4.0", 37 | "babel-loader": "^8.2.2", 38 | "copy-webpack-plugin": "^6.4.1", 39 | "cross-env": "^5.2.1", 40 | "eslint": "^5.16.0", 41 | "grunt": "^1.4.1", 42 | "grunt-checktextdomain": "^1.0.1", 43 | "grunt-cli": "^1.4.3", 44 | "grunt-contrib-clean": "^1.1.0", 45 | "grunt-contrib-compress": "^1.6.0", 46 | "grunt-contrib-copy": "^1.0.0", 47 | "grunt-contrib-cssmin": "^2.2.1", 48 | "grunt-force-task": "^2.0.0", 49 | "grunt-git": "^1.1.1", 50 | "grunt-rtlcss": "^2.0.2", 51 | "grunt-text-replace": "^0.4.0", 52 | "grunt-wp-i18n": "^1.0.3", 53 | "grunt-wp-readme-to-markdown": "^1.0.0", 54 | "load-grunt-tasks": "^3.5.2", 55 | "makepot": "^0.3.0", 56 | "uglify-es": "3.3.9", 57 | "uglifyjs-webpack-plugin": "2.1.2", 58 | "webpack": "4.29.6", 59 | "webpack-cli": "^3.3.12" 60 | }, 61 | "scripts": { 62 | "build": "cross-env NODE_ENV=production webpack", 63 | "dev": "cross-env NODE_ENV=default webpack --watch", 64 | "lint": "./node_modules/.bin/eslint .; exit 0", 65 | "lint:fix": "./node_modules/.bin/eslint . --fix; exit 0", 66 | "package-plugin": "npm run build && grunt build" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | ./tests/phpunit/ 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 250 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sugar-calendar-lite.php: -------------------------------------------------------------------------------- 1 | admin_url( 'admin-ajax.php' ), 152 | 'license_nonce' => wp_create_nonce( 'sc_license_nonce' ), 153 | 'label_btn_clicked' => esc_html__( 'Verifying', 'sugar-calendar' ), 154 | 'label_btn_default' => esc_html__( 'Verify', 'sugar-calendar' ), 155 | 'label_feedback' => esc_html__( 'Verifying...', 'sugar-calendar' ), 156 | 'feedback_empty' => esc_html__( 'Please enter a valid license key.', 'sugar-calendar' ) 157 | ) ); 158 | 159 | // User preferences 160 | wp_localize_script( 'sugar_calendar_admin_meta_box', 'sc_vars', array( 161 | 'start_of_week' => sugar_calendar_get_user_preference( 'sc_start_of_week' ), 162 | 'date_format' => sugar_calendar_get_user_preference( 'sc_date_format' ), 163 | 'time_format' => sugar_calendar_get_user_preference( 'sc_time_format' ), 164 | 'timezone' => sugar_calendar_get_user_preference( 'sc_timezone' ) 165 | ) ); 166 | } 167 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/ltr/sc-menu.css: -------------------------------------------------------------------------------- 1 | /* Submenu Nav 2 | -------------------------------------------------------------- */ 3 | 4 | /* Secondary Separators */ 5 | #adminmenu ul > li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after, 6 | #adminmenu ul > li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after, 7 | #adminmenu ul > li:last-child a[href^="admin.php?page=sc-addons"]:before 8 | { 9 | display: block; 10 | margin: 13px -15px 8px -15px; 11 | content: ''; 12 | float: left; 13 | width: calc(100% + 27px); 14 | } 15 | 16 | /* Bottom Separators */ 17 | #adminmenu ul > li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after, 18 | #adminmenu ul > li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after 19 | { 20 | border-bottom: 1px solid rgba(192,192,192,0.3); 21 | } 22 | 23 | /* Top Separator */ 24 | #adminmenu ul > li:last-child a[href^="admin.php?page=sc-addons"]:before 25 | { 26 | border-top: 1px solid rgba(192,192,192,0.3); 27 | } 28 | 29 | /* WordPress 5.7 fix for left-shadow on hover */ 30 | #adminmenu li.toplevel_page_sugar-calendar ul.wp-submenu-wrap li 31 | { 32 | clear: both; 33 | } 34 | 35 | /* Hide Parent Arrow */ 36 | ul#adminmenu #toplevel_page_sugar-calendar a.wp-has-current-submenu:after 37 | { 38 | display: none; 39 | } 40 | 41 | /* Show Submenu Arrow */ 42 | ul#adminmenu #toplevel_page_sugar-calendar ul.wp-submenu li.current a:before 43 | { 44 | right: 0; 45 | border: solid 8px transparent; 46 | content: ''; 47 | height: 0; 48 | width: 0; 49 | position: absolute; 50 | pointer-events: none; 51 | border-right-color: #f1f1f1; 52 | margin-top: 2px; 53 | } 54 | 55 | @media screen and (max-width: 782px) { 56 | 57 | /* Small Screen Separator */ 58 | #adminmenu ul > li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after, 59 | #adminmenu ul > li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after, 60 | #adminmenu ul > li:last-child a[href^="admin.php?page=sc-addons"]:before 61 | { 62 | margin: 20px -20px 8px -20px; 63 | width: calc(100% + 40px); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/ltr/sc-nav.css: -------------------------------------------------------------------------------- 1 | /* Primary Nav 2 | -------------------------------------------------------------- */ 3 | 4 | body.calendar_page_sc-settings h2.nav-tab-wrapper.sc-tab-clear, 5 | body.sugar-calendar h2.nav-tab-wrapper.sc-tab-clear { 6 | margin: -19px 0 0 0; 7 | } 8 | 9 | .sc-tab-wrap { 10 | margin: 10px 20px 0 2px; 11 | } 12 | 13 | body.calendar_page_sc-settings .sc-tab-wrap h2.sc-nav-tab-wrapper + .notice, 14 | body.sugar-calendar .sc-tab-wrap h2.sc-nav-tab-wrapper + .notice { 15 | margin-top: 10px; 16 | } 17 | 18 | body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap > .wp-heading-inline, 19 | body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap > .subtitle, 20 | body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap > h1 { 21 | display: none; 22 | } 23 | 24 | body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action { 25 | top: 3px; 26 | margin-left: 10px; 27 | line-height: 24px; 28 | } 29 | 30 | @media only screen and ( max-width: 782px ) { 31 | h2.nav-tab-wrapper.sc-tab-clear { 32 | margin-top: 0px; 33 | } 34 | } 35 | 36 | @media only screen and ( max-width: 600px ) { 37 | body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action { 38 | float: right; 39 | } 40 | } 41 | 42 | /* Secondary Nav 43 | -------------------------------------------------------------- */ 44 | 45 | .sc-settings-sub-nav { 46 | margin: 0 0px 10px 0; 47 | width: 100%; 48 | border-bottom: 1px solid #ccc; 49 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); 50 | } 51 | 52 | .sc-settings-sub-nav a { 53 | padding: 13px; 54 | display: block; 55 | } 56 | 57 | .sc-settings-sub-nav a.current { 58 | border-bottom: 4px solid #000; 59 | padding-bottom: 9px; 60 | } 61 | 62 | /* Fresh */ 63 | .admin-color-fresh .sc-settings-sub-nav a.current { 64 | border-bottom-color: #0096dd; 65 | } 66 | 67 | /* Blue */ 68 | .admin-color-blue .sc-settings-sub-nav a.current { 69 | border-bottom-color: #096484; 70 | } 71 | 72 | /* Coffee */ 73 | .admin-color-coffee .sc-settings-sub-nav a.current { 74 | border-bottom-color: #c7a589; 75 | } 76 | 77 | /* Ectoplasm */ 78 | .admin-color-ectoplasm .sc-settings-sub-nav a.current { 79 | border-bottom-color: #a3b745; 80 | } 81 | 82 | /* Midnight */ 83 | .admin-color-midnight .sc-settings-sub-nav a.current { 84 | border-bottom-color: #26292c; 85 | } 86 | 87 | /* Modern */ 88 | .admin-color-modern .sc-settings-sub-nav a.current { 89 | border-bottom-color: #3858e9; 90 | } 91 | 92 | /* Ocean */ 93 | .admin-color-ocean .sc-settings-sub-nav a.current { 94 | border-bottom-color: #627c83; 95 | } 96 | 97 | /* Sunrise */ 98 | .admin-color-sunrise .sc-settings-sub-nav a.current { 99 | border-bottom-color: #be3631; 100 | } 101 | 102 | /* Light */ 103 | .admin-color-light .sc-settings-sub-nav a.current { 104 | border-bottom-color: #888; 105 | } 106 | 107 | /* bbPress Color Schemes */ 108 | 109 | /* Evergreen */ 110 | .admin-color-bbp-evergreen .sc-settings-sub-nav a.current { 111 | border-bottom-color: #56b274; 112 | } 113 | 114 | /* Mint */ 115 | .admin-color-bbp-mint .sc-settings-sub-nav a.current { 116 | border-bottom-color: #4f6d59; 117 | } 118 | 119 | /* Nav End (for notices) 120 | -------------------------------------------------------------- */ 121 | 122 | body.sugar-calendar .wp-header-end, 123 | body.calendar_page_sc-settings .wp-header-end { 124 | clear: both; 125 | } 126 | 127 | /* Bubbles 128 | -------------------------------------------------------------- */ 129 | 130 | .sc-nav-tab-wrapper a span.awaiting-mod, 131 | .sc-settings-sub-nav a span.awaiting-mod { 132 | display: inline-block; 133 | vertical-align: top; 134 | margin: 5px 0 0 1px; 135 | padding: 0 5px; 136 | min-width: 7px; 137 | height: 17px; 138 | border-radius: 11px; 139 | background-color: #ca4a1f; 140 | color: #fff; 141 | font-size: 9px; 142 | line-height: 17px; 143 | text-align: center; 144 | font-weight: 600; 145 | z-index: 26; 146 | } 147 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/ltr/sc-taxonomy.css: -------------------------------------------------------------------------------- 1 | /* WordPress Overrides */ 2 | body.js.sugar-calendar.edit-tags-php #wpbody { 3 | position: inherit; 4 | } 5 | 6 | body.js.sugar-calendar.edit-tags-php #col-left { 7 | float: none; 8 | width: auto; 9 | display: none; 10 | } 11 | 12 | body.js.sugar-calendar.edit-tags-php #col-left h2 { 13 | display: none; 14 | } 15 | 16 | body.js.sugar-calendar.edit-tags-php #col-right { 17 | float: none; 18 | width: auto; 19 | } 20 | 21 | body.js.sugar-calendar.edit-tags-php #col-right .col-wrap { 22 | padding: 0; 23 | } 24 | 25 | /* Search Form */ 26 | body.js.sugar-calendar.edit-tags-php .search-form { 27 | display: inline-block; 28 | position: relative; 29 | box-sizing: border-box; 30 | margin: 3px 0 33px; 31 | padding: 11px 10px; 32 | width: 100%; 33 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); 34 | border: 1px solid #c3c4c7; 35 | background: #fff; 36 | color: #50575e; 37 | font-size: 13px; 38 | } 39 | 40 | body.js.sugar-calendar.edit-tags-php .search-form input[type="search"] { 41 | float: none; 42 | margin: 0; 43 | width: 280px; 44 | max-width: 100%; 45 | } 46 | 47 | body.js.sugar-calendar.edit-tags-php .search-form #search-submit { 48 | display: none; 49 | } 50 | 51 | /* List Table Columns */ 52 | 53 | body.js.sugar-calendar.edit-tags-php .column-color { 54 | width: 74px; 55 | } 56 | 57 | body.js.sugar-calendar.edit-tags-php .column-slug { 58 | width: 10%; 59 | } 60 | 61 | body.js.sugar-calendar.edit-tags-php .column-description { 62 | width: 20%; 63 | } 64 | 65 | /* Small Screens */ 66 | @media screen and (max-width: 782px) { 67 | body.js.sugar-calendar.edit-tags-php.auto-fold #wpcontent { 68 | position: inherit; 69 | margin-left: 0; 70 | padding-left: 0; 71 | } 72 | 73 | body.js.sugar-calendar.edit-tags-php.auto-fold #wpbody { 74 | padding-left: 10px; 75 | } 76 | 77 | body.js.sugar-calendar.edit-tags-php.auto-fold #col-left { 78 | top: -45px; 79 | height: calc( 100% + 45px ); 80 | } 81 | 82 | body.js.sugar-calendar.edit-tags-php.auto-fold .search-form, 83 | body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box input[name="s"] { 84 | margin-bottom: 0; 85 | } 86 | 87 | body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box { 88 | float: none; 89 | position: initial; 90 | width: auto; 91 | height: auto; 92 | margin-bottom: 0; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/ltr/sc-datepicker.css: -------------------------------------------------------------------------------- 1 | .sc-datepicker{display:none;padding:0;margin:0;border-radius:0;background-color:#fff;border:1px solid #dcdcde;border-top:none;box-shadow:0 3px 6px rgba(0,0,0,.08);min-width:17em;width:auto!important;z-index:1000!important}.sc-datepicker *{padding:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;border-radius:0;-webkit-user-select:none;user-select:none}.sc-datepicker .ui-datepicker-group{float:left}.sc-datepicker table{font-size:13px;margin:0;border:none;border-collapse:collapse}.sc-datepicker .ui-datepicker-header,.sc-datepicker .ui-widget-header{background-image:none;border:none;color:#fff;font-weight:400}.sc-datepicker .ui-datepicker-header .ui-state-hover{background:0 0;border-color:transparent;cursor:pointer}.sc-datepicker .ui-datepicker-title{margin:0;padding:10px 0;color:#fff;font-size:14px;line-height:14px;text-align:center}.sc-datepicker .ui-datepicker-next,.sc-datepicker .ui-datepicker-prev{position:relative;top:0;height:34px;width:34px}.sc-datepicker .ui-state-hover.ui-datepicker-next,.sc-datepicker .ui-state-hover.ui-datepicker-prev{border:none}.sc-datepicker .ui-datepicker-prev,.sc-datepicker .ui-datepicker-prev-hover{left:0}.sc-datepicker .ui-datepicker-next,.sc-datepicker .ui-datepicker-next-hover{right:0}.sc-datepicker .ui-datepicker-prev{float:left}.sc-datepicker .ui-datepicker-prev:before{content:"\f341"}.sc-datepicker .ui-datepicker-next{float:right}.sc-datepicker .ui-datepicker-next:before{content:"\f345"}.sc-datepicker .ui-datepicker-next span,.sc-datepicker .ui-datepicker-prev span{display:none}.sc-datepicker .ui-datepicker-next.ui-state-disabled,.sc-datepicker .ui-datepicker-prev.ui-state-disabled{visibility:hidden}.sc-datepicker .ui-datepicker-next:not(.ui-state-disabled):before,.sc-datepicker .ui-datepicker-prev:not(.ui-state-disabled):before{font:normal 20px/34px dashicons;padding-left:7px;color:#fff;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:34px;height:34px}.sc-datepicker .ui-datepicker-next-hover:before,.sc-datepicker .ui-datepicker-prev-hover:before{opacity:.7}.sc-datepicker select.ui-datepicker-month,.sc-datepicker select.ui-datepicker-year{width:33%}.sc-datepicker thead{color:#fff;font-weight:600}.sc-datepicker th{padding:10px}.sc-datepicker td{padding:0;border:1px solid #f0f0f1}.sc-datepicker td.ui-datepicker-other-month{border:transparent}.sc-datepicker tr:first-of-type td{border-top:1px solid #f0f0f1}.sc-datepicker td.ui-datepicker-week-end{background-color:#f6f7f7}.sc-datepicker td.ui-datepicker-today{background-color:#f5e6ab}.sc-datepicker td.ui-datepicker-current-day{background:#b8e6bf}.sc-datepicker td.ui-state-disabled{cursor:default;opacity:.2}.sc-datepicker td.ui-state-disabled .ui-state-default{background:#dcdcde;cursor:default}.sc-datepicker td .ui-state-default{background:0 0;border:none;text-align:center;text-decoration:none;width:auto;display:block;padding:5px 10px;font-weight:400;color:#3c434a}.sc-datepicker td .ui-state-default.ui-priority-secondary{opacity:.3}.sc-datepicker td .ui-state-default.ui-priority-secondary.ui-state-hover{opacity:1}.sc-datepicker .ui-datepicker-header,.sc-datepicker .ui-widget-header{background:#2271b1}.sc-datepicker thead{background:#2c3338}.sc-datepicker td .ui-state-hover{background:#2271b1;color:#fff}body.admin-color-fresh .sc-datepicker .ui-datepicker-header,body.admin-color-fresh .sc-datepicker .ui-widget-header{background:#2271b1}body.admin-color-fresh .sc-datepicker thead{background:#2c3338}body.admin-color-fresh .sc-datepicker td .ui-state-hover{background:#2271b1}body.admin-color-blue .sc-datepicker .ui-datepicker-header,body.admin-color-blue .sc-datepicker .ui-widget-header{background:#096484}body.admin-color-blue .sc-datepicker thead{background:#4796b3}body.admin-color-blue .sc-datepicker td .ui-state-hover{background:#096484}body.admin-color-coffee .sc-datepicker .ui-datepicker-header,body.admin-color-coffee .sc-datepicker .ui-widget-header{background:#59524c}body.admin-color-coffee .sc-datepicker thead{background:#46403c}body.admin-color-coffee .sc-datepicker td .ui-state-hover{background:#c7a589}body.admin-color-ectoplasm .sc-datepicker .ui-datepicker-header,body.admin-color-ectoplasm .sc-datepicker .ui-widget-header{background:#523f6d}body.admin-color-ectoplasm .sc-datepicker thead{background:#413256}body.admin-color-ectoplasm .sc-datepicker td .ui-state-hover{background:#a3b745}body.admin-color-midnight .sc-datepicker .ui-datepicker-header,body.admin-color-midnight .sc-datepicker .ui-widget-header{background:#363b3f}body.admin-color-midnight .sc-datepicker thead{background:#26292c}body.admin-color-midnight .sc-datepicker td .ui-state-hover{background:#e14d43}body.admin-color-modern .sc-datepicker .ui-datepicker-header,body.admin-color-modern .sc-datepicker .ui-widget-header{background:#3858e9}body.admin-color-modern .sc-datepicker thead{background:#26292c}body.admin-color-modern .sc-datepicker td .ui-state-hover{background:#3858e9}body.admin-color-ocean .sc-datepicker .ui-datepicker-header,body.admin-color-ocean .sc-datepicker .ui-widget-header{background:#738e96}body.admin-color-ocean .sc-datepicker thead{background:#627c83}body.admin-color-ocean .sc-datepicker td .ui-state-hover{background:#9ebaa0}body.admin-color-sunrise .sc-datepicker .ui-datepicker-header,body.admin-color-sunrise .sc-datepicker .ui-widget-header{background:#e65054}body.admin-color-sunrise .sc-datepicker thead{background:#b32d2e}body.admin-color-sunrise .sc-datepicker td .ui-state-hover{background:#dd823b}body.admin-color-light .sc-datepicker .ui-datepicker-header,body.admin-color-light .sc-datepicker .ui-widget-header{background:#8c8f94}body.admin-color-light .sc-datepicker thead{background:#50575e}body.admin-color-light .sc-datepicker td .ui-state-hover{background:#04a4cc}body.admin-color-bbp-evergreen .sc-datepicker .ui-datepicker-header,body.admin-color-bbp-evergreen .sc-datepicker .ui-widget-header{background:#56b274}body.admin-color-bbp-evergreen .sc-datepicker thead{background:#36533f}body.admin-color-bbp-evergreen .sc-datepicker td .ui-state-hover{background:#446950}body.admin-color-bbp-mint .sc-datepicker .ui-datepicker-header,body.admin-color-bbp-mint .sc-datepicker .ui-widget-header{background:#4ca26a}body.admin-color-bbp-mint .sc-datepicker thead{background:#4f6d59}body.admin-color-bbp-mint .sc-datepicker td .ui-state-hover{background:#5fb37c}body.wp-admin:not(.rtl) .sc-datepicker{margin-left:-1px}body.wp-admin.rtl .sc-datepicker{margin-right:-1px} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/ltr/sc-menu.css: -------------------------------------------------------------------------------- 1 | #adminmenu ul>li:last-child a[href^="admin.php?page=sc-addons"]:before,#adminmenu ul>li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after,#adminmenu ul>li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after{display:block;margin:13px -15px 8px -15px;content:'';float:left;width:calc(100% + 27px)}#adminmenu ul>li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after,#adminmenu ul>li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after{border-bottom:1px solid rgba(192,192,192,.3)}#adminmenu ul>li:last-child a[href^="admin.php?page=sc-addons"]:before{border-top:1px solid rgba(192,192,192,.3)}#adminmenu li.toplevel_page_sugar-calendar ul.wp-submenu-wrap li{clear:both}ul#adminmenu #toplevel_page_sugar-calendar a.wp-has-current-submenu:after{display:none}ul#adminmenu #toplevel_page_sugar-calendar ul.wp-submenu li.current a:before{right:0;border:solid 8px transparent;content:'';height:0;width:0;position:absolute;pointer-events:none;border-right-color:#f1f1f1;margin-top:2px}@media screen and (max-width:782px){#adminmenu ul>li:last-child a[href^="admin.php?page=sc-addons"]:before,#adminmenu ul>li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after,#adminmenu ul>li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after{margin:20px -20px 8px -20px;width:calc(100% + 40px)}} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/ltr/sc-meta-box.css: -------------------------------------------------------------------------------- 1 | body.sugar-calendar.js div.sugar-calendar-wrap div.chosen-container{min-width:125px}body.sugar-calendar div.sc-select-chosen,body.sugar-calendar.js select.sc-select-chosen{min-width:58px;max-width:300px}body.sugar-calendar.js div.sugar-calendar-wrap div.chosen-container.sc-time{min-width:58px;max-width:58px}.sugar-calendar-wrap{margin:-6px -12px -12px -12px}.sugar-calendar-wrap .section-content h4{margin-bottom:0}.sugar-calendar-wrap .section-content #alert-methods h4{margin-top:0}.sugar-calendar-wrap .section-content{padding:10px}.sugar-calendar-wrap .section-content .form-table{width:100%;margin-top:0}.sugar-calendar-wrap .section-content .form-table td,.sugar-calendar-wrap .section-content .form-table th{font-size:13px}.sugar-calendar-wrap .section-content .form-table th{width:25%;padding:15px 10px 14px}.sugar-calendar-wrap .section-content .form-table td{width:75%;padding:10px 10px 9px}.sugar-calendar-wrap .section-content th label{padding:5px 10px;display:inline-block}tr.sugar-calendar-post-header th{font-weight:600}.sugar-calendar-wrap .section-content textarea{height:79px;width:60%}.sugar-calendar-wrap .section-content input[type=date],.sugar-calendar-wrap .section-content input[type=datetime-local],.sugar-calendar-wrap .section-content input[type=datetime],.sugar-calendar-wrap .section-content input[type=email],.sugar-calendar-wrap .section-content input[type=month],.sugar-calendar-wrap .section-content input[type=number],.sugar-calendar-wrap .section-content input[type=password],.sugar-calendar-wrap .section-content input[type=search],.sugar-calendar-wrap .section-content input[type=tel],.sugar-calendar-wrap .section-content input[type=text],.sugar-calendar-wrap .section-content input[type=time],.sugar-calendar-wrap .section-content input[type=url],.sugar-calendar-wrap .section-content input[type=week]{min-height:28px}@media only screen and (max-width:782px){.sugar-calendar-wrap .section-content .sugar_calendar_datepicker{max-width:120px;display:inline-block}.sugar-calendar-wrap .section-content th label{padding:0}body.sugar-calendar.js div.sugar-calendar-wrap div.chosen-container{min-width:140px}}.sugar-calendar-wrap .sc-vertical-sections{display:flex;flex-direction:row;flex-wrap:nowrap;width:100%;background:#eee}.sc-vertical-sections .section-nav,.sc-vertical-sections .section-wrap{margin:0;padding:0;flex:1 1 auto;vertical-align:top;text-overflow:ellipsis}.sc-vertical-sections .section-nav{position:relative;line-height:1em;flex-basis:20%;max-width:150px;min-width:90px;border-right:1px solid #ccd0d4;margin-bottom:-1px;z-index:1}.sc-vertical-sections .section-wrap{background:#fff;flex-basis:80%;z-index:2}.sc-vertical-sections .section-nav button{margin:0;padding:0;position:relative;white-space:nowrap;background-color:#f4f4f4;border:none;width:100%;text-align:left;outline:0}.sc-vertical-sections .section-nav button{display:block;margin:0;padding:9px;line-height:20px!important;box-shadow:inset 0 -1px 0 #ccd0d4;text-decoration:none;text-overflow:ellipsis;overflow:hidden;transition-property:border,background,color;transition-duration:.1s;transition-timing-function:ease-in-out;cursor:pointer}.sc-vertical-sections .section-nav button>.dashicons{color:#82878c}.sc-vertical-sections .section-nav button:focus,.sc-vertical-sections .section-nav button:hover{background-color:#fafafa}.sc-vertical-sections .section-nav button:focus,.sc-vertical-sections .section-nav button:focus>.dashicons,.sc-vertical-sections .section-nav button:focus>span,.sc-vertical-sections .section-nav button:hover,.sc-vertical-sections .section-nav button:hover>.dashicons,.sc-vertical-sections .section-nav button:hover>span{color:#0096dd}.sc-vertical-sections .section-nav button .dashicons{line-height:20px;margin-right:3px}.sc-vertical-sections .section-nav button[aria-selected=true]{position:relative;font-weight:700;background-color:#fff;border-right-color:#fff;width:calc(100% + 2px)}.sc-vertical-sections .section-nav button[aria-selected=true],.sc-vertical-sections .section-nav button[aria-selected=true] .dashicons,.sc-vertical-sections .section-nav button[aria-selected=true] span{color:#23282d}.sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #2271b1}body.admin-color-fresh .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #2271b1}body.admin-color-blue .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #4796b3}body.admin-color-coffee .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #c7a589}body.admin-color-ectoplasm .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #523f6d}body.admin-color-midnight .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #e14d43}body.admin-color-modern .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #3858e9}body.admin-color-ocean .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #9ebaa0}body.admin-color-sunrise .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #be3631}body.admin-color-light .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #888}body.admin-color-bbp-evergreen .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #56b274}body.admin-color-bbp-mint .sc-vertical-sections .section-nav button[aria-selected=true]{border-left:5px solid #4f6d59}.edit-post-layout__metaboxes #sugar_calendar_editor_event_details .postbox-header h2{border-bottom:none}.edit-post-layout__metaboxes #sugar_calendar_editor_event_details .sugar-calendar-wrap{margin:-6px -14px -14px -14px}@media only screen and (max-width:782px){.sc-vertical-sections .section-nav{width:48px;min-width:48px;max-width:48px}.sc-vertical-sections .section-nav button{text-align:center}.sc-vertical-sections .section-nav button .dashicons{width:24px;height:24px;font-size:24px;line-height:24px;margin:0}.section-nav button .dashicons::before{width:24px;height:24px}.section-nav button .label{overflow:hidden;position:absolute;top:-1000em;left:-1000em;width:1px;height:1px}} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/ltr/sc-nav.css: -------------------------------------------------------------------------------- 1 | body.calendar_page_sc-settings h2.nav-tab-wrapper.sc-tab-clear,body.sugar-calendar h2.nav-tab-wrapper.sc-tab-clear{margin:-19px 0 0 0}.sc-tab-wrap{margin:10px 20px 0 2px}body.calendar_page_sc-settings .sc-tab-wrap h2.sc-nav-tab-wrapper+.notice,body.sugar-calendar .sc-tab-wrap h2.sc-nav-tab-wrapper+.notice{margin-top:10px}body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap>.subtitle,body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap>.wp-heading-inline,body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap>h1{display:none}body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action{top:3px;margin-left:10px;line-height:24px}@media only screen and (max-width:782px){h2.nav-tab-wrapper.sc-tab-clear{margin-top:0}}@media only screen and (max-width:600px){body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action{float:right}}.sc-settings-sub-nav{margin:0 0 10px 0;width:100%;border-bottom:1px solid #ccc;box-shadow:0 1px 1px rgba(0,0,0,.04)}.sc-settings-sub-nav a{padding:13px;display:block}.sc-settings-sub-nav a.current{border-bottom:4px solid #000;padding-bottom:9px}.admin-color-fresh .sc-settings-sub-nav a.current{border-bottom-color:#0096dd}.admin-color-blue .sc-settings-sub-nav a.current{border-bottom-color:#096484}.admin-color-coffee .sc-settings-sub-nav a.current{border-bottom-color:#c7a589}.admin-color-ectoplasm .sc-settings-sub-nav a.current{border-bottom-color:#a3b745}.admin-color-midnight .sc-settings-sub-nav a.current{border-bottom-color:#26292c}.admin-color-modern .sc-settings-sub-nav a.current{border-bottom-color:#3858e9}.admin-color-ocean .sc-settings-sub-nav a.current{border-bottom-color:#627c83}.admin-color-sunrise .sc-settings-sub-nav a.current{border-bottom-color:#be3631}.admin-color-light .sc-settings-sub-nav a.current{border-bottom-color:#888}.admin-color-bbp-evergreen .sc-settings-sub-nav a.current{border-bottom-color:#56b274}.admin-color-bbp-mint .sc-settings-sub-nav a.current{border-bottom-color:#4f6d59}body.calendar_page_sc-settings .wp-header-end,body.sugar-calendar .wp-header-end{clear:both}.sc-nav-tab-wrapper a span.awaiting-mod,.sc-settings-sub-nav a span.awaiting-mod{display:inline-block;vertical-align:top;margin:5px 0 0 1px;padding:0 5px;min-width:7px;height:17px;border-radius:11px;background-color:#ca4a1f;color:#fff;font-size:9px;line-height:17px;text-align:center;font-weight:600;z-index:26} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/ltr/sc-taxonomy.css: -------------------------------------------------------------------------------- 1 | body.js.sugar-calendar.edit-tags-php #wpbody{position:inherit}body.js.sugar-calendar.edit-tags-php #col-left{float:none;width:auto;display:none}body.js.sugar-calendar.edit-tags-php #col-left h2{display:none}body.js.sugar-calendar.edit-tags-php #col-right{float:none;width:auto}body.js.sugar-calendar.edit-tags-php #col-right .col-wrap{padding:0}body.js.sugar-calendar.edit-tags-php .search-form{display:inline-block;position:relative;box-sizing:border-box;margin:3px 0 33px;padding:11px 10px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,.04);border:1px solid #c3c4c7;background:#fff;color:#50575e;font-size:13px}body.js.sugar-calendar.edit-tags-php .search-form input[type=search]{float:none;margin:0;width:280px;max-width:100%}body.js.sugar-calendar.edit-tags-php .search-form #search-submit{display:none}body.js.sugar-calendar.edit-tags-php .column-color{width:74px}body.js.sugar-calendar.edit-tags-php .column-slug{width:10%}body.js.sugar-calendar.edit-tags-php .column-description{width:20%}@media screen and (max-width:782px){body.js.sugar-calendar.edit-tags-php.auto-fold #wpcontent{position:inherit;margin-left:0;padding-left:0}body.js.sugar-calendar.edit-tags-php.auto-fold #wpbody{padding-left:10px}body.js.sugar-calendar.edit-tags-php.auto-fold #col-left{top:-45px;height:calc(100% + 45px)}body.js.sugar-calendar.edit-tags-php.auto-fold .search-form,body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box input[name="s"]{margin-bottom:0}body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box{float:none;position:initial;width:auto;height:auto;margin-bottom:0}} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/rtl/sc-datepicker.css: -------------------------------------------------------------------------------- 1 | .sc-datepicker{display:none;padding:0;margin:0;border-radius:0;background-color:#fff;border:1px solid #dcdcde;border-top:none;box-shadow:0 3px 6px rgba(0,0,0,.08);min-width:17em;width:auto!important;z-index:1000!important}.sc-datepicker *{padding:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;border-radius:0;-webkit-user-select:none;user-select:none}.sc-datepicker .ui-datepicker-group{float:right}.sc-datepicker table{font-size:13px;margin:0;border:none;border-collapse:collapse}.sc-datepicker .ui-datepicker-header,.sc-datepicker .ui-widget-header{background-image:none;border:none;color:#fff;font-weight:400}.sc-datepicker .ui-datepicker-header .ui-state-hover{background:0 0;border-color:transparent;cursor:pointer}.sc-datepicker .ui-datepicker-title{margin:0;padding:10px 0;color:#fff;font-size:14px;line-height:14px;text-align:center}.sc-datepicker .ui-datepicker-next,.sc-datepicker .ui-datepicker-prev{position:relative;top:0;height:34px;width:34px}.sc-datepicker .ui-state-hover.ui-datepicker-next,.sc-datepicker .ui-state-hover.ui-datepicker-prev{border:none}.sc-datepicker .ui-datepicker-prev,.sc-datepicker .ui-datepicker-prev-hover{right:0}.sc-datepicker .ui-datepicker-next,.sc-datepicker .ui-datepicker-next-hover{left:0}.sc-datepicker .ui-datepicker-prev{float:right}.sc-datepicker .ui-datepicker-prev:before{content:"\f341"}.sc-datepicker .ui-datepicker-next{float:left}.sc-datepicker .ui-datepicker-next:before{content:"\f345"}.sc-datepicker .ui-datepicker-next span,.sc-datepicker .ui-datepicker-prev span{display:none}.sc-datepicker .ui-datepicker-next.ui-state-disabled,.sc-datepicker .ui-datepicker-prev.ui-state-disabled{visibility:hidden}.sc-datepicker .ui-datepicker-next:not(.ui-state-disabled):before,.sc-datepicker .ui-datepicker-prev:not(.ui-state-disabled):before{font:normal 20px/34px dashicons;padding-right:7px;color:#fff;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:34px;height:34px}.sc-datepicker .ui-datepicker-next-hover:before,.sc-datepicker .ui-datepicker-prev-hover:before{opacity:.7}.sc-datepicker select.ui-datepicker-month,.sc-datepicker select.ui-datepicker-year{width:33%}.sc-datepicker thead{color:#fff;font-weight:600}.sc-datepicker th{padding:10px}.sc-datepicker td{padding:0;border:1px solid #f0f0f1}.sc-datepicker td.ui-datepicker-other-month{border:transparent}.sc-datepicker tr:first-of-type td{border-top:1px solid #f0f0f1}.sc-datepicker td.ui-datepicker-week-end{background-color:#f6f7f7}.sc-datepicker td.ui-datepicker-today{background-color:#f5e6ab}.sc-datepicker td.ui-datepicker-current-day{background:#b8e6bf}.sc-datepicker td.ui-state-disabled{cursor:default;opacity:.2}.sc-datepicker td.ui-state-disabled .ui-state-default{background:#dcdcde;cursor:default}.sc-datepicker td .ui-state-default{background:0 0;border:none;text-align:center;text-decoration:none;width:auto;display:block;padding:5px 10px;font-weight:400;color:#3c434a}.sc-datepicker td .ui-state-default.ui-priority-secondary{opacity:.3}.sc-datepicker td .ui-state-default.ui-priority-secondary.ui-state-hover{opacity:1}.sc-datepicker .ui-datepicker-header,.sc-datepicker .ui-widget-header{background:#2271b1}.sc-datepicker thead{background:#2c3338}.sc-datepicker td .ui-state-hover{background:#2271b1;color:#fff}body.admin-color-fresh .sc-datepicker .ui-datepicker-header,body.admin-color-fresh .sc-datepicker .ui-widget-header{background:#2271b1}body.admin-color-fresh .sc-datepicker thead{background:#2c3338}body.admin-color-fresh .sc-datepicker td .ui-state-hover{background:#2271b1}body.admin-color-blue .sc-datepicker .ui-datepicker-header,body.admin-color-blue .sc-datepicker .ui-widget-header{background:#096484}body.admin-color-blue .sc-datepicker thead{background:#4796b3}body.admin-color-blue .sc-datepicker td .ui-state-hover{background:#096484}body.admin-color-coffee .sc-datepicker .ui-datepicker-header,body.admin-color-coffee .sc-datepicker .ui-widget-header{background:#59524c}body.admin-color-coffee .sc-datepicker thead{background:#46403c}body.admin-color-coffee .sc-datepicker td .ui-state-hover{background:#c7a589}body.admin-color-ectoplasm .sc-datepicker .ui-datepicker-header,body.admin-color-ectoplasm .sc-datepicker .ui-widget-header{background:#523f6d}body.admin-color-ectoplasm .sc-datepicker thead{background:#413256}body.admin-color-ectoplasm .sc-datepicker td .ui-state-hover{background:#a3b745}body.admin-color-midnight .sc-datepicker .ui-datepicker-header,body.admin-color-midnight .sc-datepicker .ui-widget-header{background:#363b3f}body.admin-color-midnight .sc-datepicker thead{background:#26292c}body.admin-color-midnight .sc-datepicker td .ui-state-hover{background:#e14d43}body.admin-color-modern .sc-datepicker .ui-datepicker-header,body.admin-color-modern .sc-datepicker .ui-widget-header{background:#3858e9}body.admin-color-modern .sc-datepicker thead{background:#26292c}body.admin-color-modern .sc-datepicker td .ui-state-hover{background:#3858e9}body.admin-color-ocean .sc-datepicker .ui-datepicker-header,body.admin-color-ocean .sc-datepicker .ui-widget-header{background:#738e96}body.admin-color-ocean .sc-datepicker thead{background:#627c83}body.admin-color-ocean .sc-datepicker td .ui-state-hover{background:#9ebaa0}body.admin-color-sunrise .sc-datepicker .ui-datepicker-header,body.admin-color-sunrise .sc-datepicker .ui-widget-header{background:#e65054}body.admin-color-sunrise .sc-datepicker thead{background:#b32d2e}body.admin-color-sunrise .sc-datepicker td .ui-state-hover{background:#dd823b}body.admin-color-light .sc-datepicker .ui-datepicker-header,body.admin-color-light .sc-datepicker .ui-widget-header{background:#8c8f94}body.admin-color-light .sc-datepicker thead{background:#50575e}body.admin-color-light .sc-datepicker td .ui-state-hover{background:#04a4cc}body.admin-color-bbp-evergreen .sc-datepicker .ui-datepicker-header,body.admin-color-bbp-evergreen .sc-datepicker .ui-widget-header{background:#56b274}body.admin-color-bbp-evergreen .sc-datepicker thead{background:#36533f}body.admin-color-bbp-evergreen .sc-datepicker td .ui-state-hover{background:#446950}body.admin-color-bbp-mint .sc-datepicker .ui-datepicker-header,body.admin-color-bbp-mint .sc-datepicker .ui-widget-header{background:#4ca26a}body.admin-color-bbp-mint .sc-datepicker thead{background:#4f6d59}body.admin-color-bbp-mint .sc-datepicker td .ui-state-hover{background:#5fb37c}body.wp-admin:not(.rtl) .sc-datepicker{margin-right:-1px}body.wp-admin.rtl .sc-datepicker{margin-left:-1px} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/rtl/sc-menu.css: -------------------------------------------------------------------------------- 1 | #adminmenu ul>li:last-child a[href^="admin.php?page=sc-addons"]:before,#adminmenu ul>li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after,#adminmenu ul>li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after{display:block;margin:13px -15px 8px -15px;content:'';float:right;width:calc(100% + 27px)}#adminmenu ul>li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after,#adminmenu ul>li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after{border-bottom:1px solid rgba(192,192,192,.3)}#adminmenu ul>li:last-child a[href^="admin.php?page=sc-addons"]:before{border-top:1px solid rgba(192,192,192,.3)}#adminmenu li.toplevel_page_sugar-calendar ul.wp-submenu-wrap li{clear:both}ul#adminmenu #toplevel_page_sugar-calendar a.wp-has-current-submenu:after{display:none}ul#adminmenu #toplevel_page_sugar-calendar ul.wp-submenu li.current a:before{left:0;border:solid 8px transparent;content:'';height:0;width:0;position:absolute;pointer-events:none;border-left-color:#f1f1f1;margin-top:2px}@media screen and (max-width:782px){#adminmenu ul>li:last-child a[href^="admin.php?page=sc-addons"]:before,#adminmenu ul>li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after,#adminmenu ul>li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after{margin:20px -20px 8px -20px;width:calc(100% + 40px)}} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/rtl/sc-meta-box.css: -------------------------------------------------------------------------------- 1 | body.sugar-calendar.js div.sugar-calendar-wrap div.chosen-container{min-width:125px}body.sugar-calendar div.sc-select-chosen,body.sugar-calendar.js select.sc-select-chosen{min-width:58px;max-width:300px}body.sugar-calendar.js div.sugar-calendar-wrap div.chosen-container.sc-time{min-width:58px;max-width:58px}.sugar-calendar-wrap{margin:-6px -12px -12px -12px}.sugar-calendar-wrap .section-content h4{margin-bottom:0}.sugar-calendar-wrap .section-content #alert-methods h4{margin-top:0}.sugar-calendar-wrap .section-content{padding:10px}.sugar-calendar-wrap .section-content .form-table{width:100%;margin-top:0}.sugar-calendar-wrap .section-content .form-table td,.sugar-calendar-wrap .section-content .form-table th{font-size:13px}.sugar-calendar-wrap .section-content .form-table th{width:25%;padding:15px 10px 14px}.sugar-calendar-wrap .section-content .form-table td{width:75%;padding:10px 10px 9px}.sugar-calendar-wrap .section-content th label{padding:5px 10px;display:inline-block}tr.sugar-calendar-post-header th{font-weight:600}.sugar-calendar-wrap .section-content textarea{height:79px;width:60%}.sugar-calendar-wrap .section-content input[type=date],.sugar-calendar-wrap .section-content input[type=datetime-local],.sugar-calendar-wrap .section-content input[type=datetime],.sugar-calendar-wrap .section-content input[type=email],.sugar-calendar-wrap .section-content input[type=month],.sugar-calendar-wrap .section-content input[type=number],.sugar-calendar-wrap .section-content input[type=password],.sugar-calendar-wrap .section-content input[type=search],.sugar-calendar-wrap .section-content input[type=tel],.sugar-calendar-wrap .section-content input[type=text],.sugar-calendar-wrap .section-content input[type=time],.sugar-calendar-wrap .section-content input[type=url],.sugar-calendar-wrap .section-content input[type=week]{min-height:28px}@media only screen and (max-width:782px){.sugar-calendar-wrap .section-content .sugar_calendar_datepicker{max-width:120px;display:inline-block}.sugar-calendar-wrap .section-content th label{padding:0}body.sugar-calendar.js div.sugar-calendar-wrap div.chosen-container{min-width:140px}}.sugar-calendar-wrap .sc-vertical-sections{display:flex;flex-direction:row;flex-wrap:nowrap;width:100%;background:#eee}.sc-vertical-sections .section-nav,.sc-vertical-sections .section-wrap{margin:0;padding:0;flex:1 1 auto;vertical-align:top;text-overflow:ellipsis}.sc-vertical-sections .section-nav{position:relative;line-height:1em;flex-basis:20%;max-width:150px;min-width:90px;border-left:1px solid #ccd0d4;margin-bottom:-1px;z-index:1}.sc-vertical-sections .section-wrap{background:#fff;flex-basis:80%;z-index:2}.sc-vertical-sections .section-nav button{margin:0;padding:0;position:relative;white-space:nowrap;background-color:#f4f4f4;border:none;width:100%;text-align:right;outline:0}.sc-vertical-sections .section-nav button{display:block;margin:0;padding:9px;line-height:20px!important;box-shadow:inset 0 -1px 0 #ccd0d4;text-decoration:none;text-overflow:ellipsis;overflow:hidden;transition-property:border,background,color;transition-duration:.1s;transition-timing-function:ease-in-out;cursor:pointer}.sc-vertical-sections .section-nav button>.dashicons{color:#82878c}.sc-vertical-sections .section-nav button:focus,.sc-vertical-sections .section-nav button:hover{background-color:#fafafa}.sc-vertical-sections .section-nav button:focus,.sc-vertical-sections .section-nav button:focus>.dashicons,.sc-vertical-sections .section-nav button:focus>span,.sc-vertical-sections .section-nav button:hover,.sc-vertical-sections .section-nav button:hover>.dashicons,.sc-vertical-sections .section-nav button:hover>span{color:#0096dd}.sc-vertical-sections .section-nav button .dashicons{line-height:20px;margin-left:3px}.sc-vertical-sections .section-nav button[aria-selected=true]{position:relative;font-weight:700;background-color:#fff;border-left-color:#fff;width:calc(100% + 2px)}.sc-vertical-sections .section-nav button[aria-selected=true],.sc-vertical-sections .section-nav button[aria-selected=true] .dashicons,.sc-vertical-sections .section-nav button[aria-selected=true] span{color:#23282d}.sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #2271b1}body.admin-color-fresh .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #2271b1}body.admin-color-blue .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #4796b3}body.admin-color-coffee .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #c7a589}body.admin-color-ectoplasm .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #523f6d}body.admin-color-midnight .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #e14d43}body.admin-color-modern .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #3858e9}body.admin-color-ocean .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #9ebaa0}body.admin-color-sunrise .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #be3631}body.admin-color-light .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #888}body.admin-color-bbp-evergreen .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #56b274}body.admin-color-bbp-mint .sc-vertical-sections .section-nav button[aria-selected=true]{border-right:5px solid #4f6d59}.edit-post-layout__metaboxes #sugar_calendar_editor_event_details .postbox-header h2{border-bottom:none}.edit-post-layout__metaboxes #sugar_calendar_editor_event_details .sugar-calendar-wrap{margin:-6px -14px -14px -14px}@media only screen and (max-width:782px){.sc-vertical-sections .section-nav{width:48px;min-width:48px;max-width:48px}.sc-vertical-sections .section-nav button{text-align:center}.sc-vertical-sections .section-nav button .dashicons{width:24px;height:24px;font-size:24px;line-height:24px;margin:0}.section-nav button .dashicons::before{width:24px;height:24px}.section-nav button .label{overflow:hidden;position:absolute;top:-1000em;right:-1000em;width:1px;height:1px}} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/rtl/sc-nav.css: -------------------------------------------------------------------------------- 1 | body.calendar_page_sc-settings h2.nav-tab-wrapper.sc-tab-clear,body.sugar-calendar h2.nav-tab-wrapper.sc-tab-clear{margin:-19px 0 0 0}.sc-tab-wrap{margin:10px 2px 0 20px}body.calendar_page_sc-settings .sc-tab-wrap h2.sc-nav-tab-wrapper+.notice,body.sugar-calendar .sc-tab-wrap h2.sc-nav-tab-wrapper+.notice{margin-top:10px}body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap>.subtitle,body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap>.wp-heading-inline,body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap>h1{display:none}body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action{top:3px;margin-right:10px;line-height:24px}@media only screen and (max-width:782px){h2.nav-tab-wrapper.sc-tab-clear{margin-top:0}}@media only screen and (max-width:600px){body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action{float:left}}.sc-settings-sub-nav{margin:0 0 10px 0;width:100%;border-bottom:1px solid #ccc;box-shadow:0 1px 1px rgba(0,0,0,.04)}.sc-settings-sub-nav a{padding:13px;display:block}.sc-settings-sub-nav a.current{border-bottom:4px solid #000;padding-bottom:9px}.admin-color-fresh .sc-settings-sub-nav a.current{border-bottom-color:#0096dd}.admin-color-blue .sc-settings-sub-nav a.current{border-bottom-color:#096484}.admin-color-coffee .sc-settings-sub-nav a.current{border-bottom-color:#c7a589}.admin-color-ectoplasm .sc-settings-sub-nav a.current{border-bottom-color:#a3b745}.admin-color-midnight .sc-settings-sub-nav a.current{border-bottom-color:#26292c}.admin-color-modern .sc-settings-sub-nav a.current{border-bottom-color:#3858e9}.admin-color-ocean .sc-settings-sub-nav a.current{border-bottom-color:#627c83}.admin-color-sunrise .sc-settings-sub-nav a.current{border-bottom-color:#be3631}.admin-color-light .sc-settings-sub-nav a.current{border-bottom-color:#888}.admin-color-bbp-evergreen .sc-settings-sub-nav a.current{border-bottom-color:#56b274}.admin-color-bbp-mint .sc-settings-sub-nav a.current{border-bottom-color:#4f6d59}body.calendar_page_sc-settings .wp-header-end,body.sugar-calendar .wp-header-end{clear:both}.sc-nav-tab-wrapper a span.awaiting-mod,.sc-settings-sub-nav a span.awaiting-mod{display:inline-block;vertical-align:top;margin:5px 1px 0 0;padding:0 5px;min-width:7px;height:17px;border-radius:11px;background-color:#ca4a1f;color:#fff;font-size:9px;line-height:17px;text-align:center;font-weight:600;z-index:26} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/min/rtl/sc-taxonomy.css: -------------------------------------------------------------------------------- 1 | body.js.sugar-calendar.edit-tags-php #wpbody{position:inherit}body.js.sugar-calendar.edit-tags-php #col-left{float:none;width:auto;display:none}body.js.sugar-calendar.edit-tags-php #col-left h2{display:none}body.js.sugar-calendar.edit-tags-php #col-right{float:none;width:auto}body.js.sugar-calendar.edit-tags-php #col-right .col-wrap{padding:0}body.js.sugar-calendar.edit-tags-php .search-form{display:inline-block;position:relative;box-sizing:border-box;margin:3px 0 33px;padding:11px 10px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,.04);border:1px solid #c3c4c7;background:#fff;color:#50575e;font-size:13px}body.js.sugar-calendar.edit-tags-php .search-form input[type=search]{float:none;margin:0;width:280px;max-width:100%}body.js.sugar-calendar.edit-tags-php .search-form #search-submit{display:none}body.js.sugar-calendar.edit-tags-php .column-color{width:74px}body.js.sugar-calendar.edit-tags-php .column-slug{width:10%}body.js.sugar-calendar.edit-tags-php .column-description{width:20%}@media screen and (max-width:782px){body.js.sugar-calendar.edit-tags-php.auto-fold #wpcontent{position:inherit;margin-right:0;padding-right:0}body.js.sugar-calendar.edit-tags-php.auto-fold #wpbody{padding-right:10px}body.js.sugar-calendar.edit-tags-php.auto-fold #col-left{top:-45px;height:calc(100% + 45px)}body.js.sugar-calendar.edit-tags-php.auto-fold .search-form,body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box input[name="s"]{margin-bottom:0}body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box{float:none;position:initial;width:auto;height:auto;margin-bottom:0}} -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/rtl/sc-menu.css: -------------------------------------------------------------------------------- 1 | /* Submenu Nav 2 | -------------------------------------------------------------- */ 3 | 4 | /* Secondary Separators */ 5 | #adminmenu ul > li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after, 6 | #adminmenu ul > li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after, 7 | #adminmenu ul > li:last-child a[href^="admin.php?page=sc-addons"]:before 8 | { 9 | display: block; 10 | margin: 13px -15px 8px -15px; 11 | content: ''; 12 | float: right; 13 | width: calc(100% + 27px); 14 | } 15 | 16 | /* Bottom Separators */ 17 | #adminmenu ul > li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after, 18 | #adminmenu ul > li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after 19 | { 20 | border-bottom: 1px solid rgba(192,192,192,0.3); 21 | } 22 | 23 | /* Top Separator */ 24 | #adminmenu ul > li:last-child a[href^="admin.php?page=sc-addons"]:before 25 | { 26 | border-top: 1px solid rgba(192,192,192,0.3); 27 | } 28 | 29 | /* WordPress 5.7 fix for left-shadow on hover */ 30 | #adminmenu li.toplevel_page_sugar-calendar ul.wp-submenu-wrap li 31 | { 32 | clear: both; 33 | } 34 | 35 | /* Hide Parent Arrow */ 36 | ul#adminmenu #toplevel_page_sugar-calendar a.wp-has-current-submenu:after 37 | { 38 | display: none; 39 | } 40 | 41 | /* Show Submenu Arrow */ 42 | ul#adminmenu #toplevel_page_sugar-calendar ul.wp-submenu li.current a:before 43 | { 44 | left: 0; 45 | border: solid 8px transparent; 46 | content: ''; 47 | height: 0; 48 | width: 0; 49 | position: absolute; 50 | pointer-events: none; 51 | border-left-color: #f1f1f1; 52 | margin-top: 2px; 53 | } 54 | 55 | @media screen and (max-width: 782px) { 56 | 57 | /* Small Screen Separator */ 58 | #adminmenu ul > li:not(:last-child) a[href^="admin.php?page=sugar-calendar"]:after, 59 | #adminmenu ul > li:not(:last-child) a[href^="post-new.php?post_type=sc_event"]:after, 60 | #adminmenu ul > li:last-child a[href^="admin.php?page=sc-addons"]:before 61 | { 62 | margin: 20px -20px 8px -20px; 63 | width: calc(100% + 40px); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/rtl/sc-nav.css: -------------------------------------------------------------------------------- 1 | /* Primary Nav 2 | -------------------------------------------------------------- */ 3 | 4 | body.calendar_page_sc-settings h2.nav-tab-wrapper.sc-tab-clear, 5 | body.sugar-calendar h2.nav-tab-wrapper.sc-tab-clear { 6 | margin: -19px 0 0 0; 7 | } 8 | 9 | .sc-tab-wrap { 10 | margin: 10px 2px 0 20px; 11 | } 12 | 13 | body.calendar_page_sc-settings .sc-tab-wrap h2.sc-nav-tab-wrapper + .notice, 14 | body.sugar-calendar .sc-tab-wrap h2.sc-nav-tab-wrapper + .notice { 15 | margin-top: 10px; 16 | } 17 | 18 | body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap > .wp-heading-inline, 19 | body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap > .subtitle, 20 | body.sugar-calendar:not(.post-new-php):not(.post-php) .wrap > h1 { 21 | display: none; 22 | } 23 | 24 | body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action { 25 | top: 3px; 26 | margin-right: 10px; 27 | line-height: 24px; 28 | } 29 | 30 | @media only screen and ( max-width: 782px ) { 31 | h2.nav-tab-wrapper.sc-tab-clear { 32 | margin-top: 0px; 33 | } 34 | } 35 | 36 | @media only screen and ( max-width: 600px ) { 37 | body.sugar-calendar .wrap .nav-tab-wrapper .page-title-action { 38 | float: left; 39 | } 40 | } 41 | 42 | /* Secondary Nav 43 | -------------------------------------------------------------- */ 44 | 45 | .sc-settings-sub-nav { 46 | margin: 0 0 10px 0px; 47 | width: 100%; 48 | border-bottom: 1px solid #ccc; 49 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); 50 | } 51 | 52 | .sc-settings-sub-nav a { 53 | padding: 13px; 54 | display: block; 55 | } 56 | 57 | .sc-settings-sub-nav a.current { 58 | border-bottom: 4px solid #000; 59 | padding-bottom: 9px; 60 | } 61 | 62 | /* Fresh */ 63 | .admin-color-fresh .sc-settings-sub-nav a.current { 64 | border-bottom-color: #0096dd; 65 | } 66 | 67 | /* Blue */ 68 | .admin-color-blue .sc-settings-sub-nav a.current { 69 | border-bottom-color: #096484; 70 | } 71 | 72 | /* Coffee */ 73 | .admin-color-coffee .sc-settings-sub-nav a.current { 74 | border-bottom-color: #c7a589; 75 | } 76 | 77 | /* Ectoplasm */ 78 | .admin-color-ectoplasm .sc-settings-sub-nav a.current { 79 | border-bottom-color: #a3b745; 80 | } 81 | 82 | /* Midnight */ 83 | .admin-color-midnight .sc-settings-sub-nav a.current { 84 | border-bottom-color: #26292c; 85 | } 86 | 87 | /* Modern */ 88 | .admin-color-modern .sc-settings-sub-nav a.current { 89 | border-bottom-color: #3858e9; 90 | } 91 | 92 | /* Ocean */ 93 | .admin-color-ocean .sc-settings-sub-nav a.current { 94 | border-bottom-color: #627c83; 95 | } 96 | 97 | /* Sunrise */ 98 | .admin-color-sunrise .sc-settings-sub-nav a.current { 99 | border-bottom-color: #be3631; 100 | } 101 | 102 | /* Light */ 103 | .admin-color-light .sc-settings-sub-nav a.current { 104 | border-bottom-color: #888; 105 | } 106 | 107 | /* bbPress Color Schemes */ 108 | 109 | /* Evergreen */ 110 | .admin-color-bbp-evergreen .sc-settings-sub-nav a.current { 111 | border-bottom-color: #56b274; 112 | } 113 | 114 | /* Mint */ 115 | .admin-color-bbp-mint .sc-settings-sub-nav a.current { 116 | border-bottom-color: #4f6d59; 117 | } 118 | 119 | /* Nav End (for notices) 120 | -------------------------------------------------------------- */ 121 | 122 | body.sugar-calendar .wp-header-end, 123 | body.calendar_page_sc-settings .wp-header-end { 124 | clear: both; 125 | } 126 | 127 | /* Bubbles 128 | -------------------------------------------------------------- */ 129 | 130 | .sc-nav-tab-wrapper a span.awaiting-mod, 131 | .sc-settings-sub-nav a span.awaiting-mod { 132 | display: inline-block; 133 | vertical-align: top; 134 | margin: 5px 1px 0 0; 135 | padding: 0 5px; 136 | min-width: 7px; 137 | height: 17px; 138 | border-radius: 11px; 139 | background-color: #ca4a1f; 140 | color: #fff; 141 | font-size: 9px; 142 | line-height: 17px; 143 | text-align: center; 144 | font-weight: 600; 145 | z-index: 26; 146 | } 147 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/css/rtl/sc-taxonomy.css: -------------------------------------------------------------------------------- 1 | /* WordPress Overrides */ 2 | body.js.sugar-calendar.edit-tags-php #wpbody { 3 | position: inherit; 4 | } 5 | 6 | body.js.sugar-calendar.edit-tags-php #col-left { 7 | float: none; 8 | width: auto; 9 | display: none; 10 | } 11 | 12 | body.js.sugar-calendar.edit-tags-php #col-left h2 { 13 | display: none; 14 | } 15 | 16 | body.js.sugar-calendar.edit-tags-php #col-right { 17 | float: none; 18 | width: auto; 19 | } 20 | 21 | body.js.sugar-calendar.edit-tags-php #col-right .col-wrap { 22 | padding: 0; 23 | } 24 | 25 | /* Search Form */ 26 | body.js.sugar-calendar.edit-tags-php .search-form { 27 | display: inline-block; 28 | position: relative; 29 | box-sizing: border-box; 30 | margin: 3px 0 33px; 31 | padding: 11px 10px; 32 | width: 100%; 33 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); 34 | border: 1px solid #c3c4c7; 35 | background: #fff; 36 | color: #50575e; 37 | font-size: 13px; 38 | } 39 | 40 | body.js.sugar-calendar.edit-tags-php .search-form input[type="search"] { 41 | float: none; 42 | margin: 0; 43 | width: 280px; 44 | max-width: 100%; 45 | } 46 | 47 | body.js.sugar-calendar.edit-tags-php .search-form #search-submit { 48 | display: none; 49 | } 50 | 51 | /* List Table Columns */ 52 | 53 | body.js.sugar-calendar.edit-tags-php .column-color { 54 | width: 74px; 55 | } 56 | 57 | body.js.sugar-calendar.edit-tags-php .column-slug { 58 | width: 10%; 59 | } 60 | 61 | body.js.sugar-calendar.edit-tags-php .column-description { 62 | width: 20%; 63 | } 64 | 65 | /* Small Screens */ 66 | @media screen and (max-width: 782px) { 67 | body.js.sugar-calendar.edit-tags-php.auto-fold #wpcontent { 68 | position: inherit; 69 | margin-right: 0; 70 | padding-right: 0; 71 | } 72 | 73 | body.js.sugar-calendar.edit-tags-php.auto-fold #wpbody { 74 | padding-right: 10px; 75 | } 76 | 77 | body.js.sugar-calendar.edit-tags-php.auto-fold #col-left { 78 | top: -45px; 79 | height: calc( 100% + 45px ); 80 | } 81 | 82 | body.js.sugar-calendar.edit-tags-php.auto-fold .search-form, 83 | body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box input[name="s"] { 84 | margin-bottom: 0; 85 | } 86 | 87 | body.js.sugar-calendar.edit-tags-php.auto-fold p.search-box { 88 | float: none; 89 | position: initial; 90 | width: auto; 91 | height: auto; 92 | margin-bottom: 0; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /sugar-calendar/includes/admin/assets/js/sc-admin.js: -------------------------------------------------------------------------------- 1 | jQuery( document ).ready( function( $ ) { 2 | 3 | var chosenVars = { 4 | disable_search_threshold: 13, 5 | search_contains: true, 6 | inherit_select_classes: true, 7 | single_backstroke_delete: false, 8 | placeholder_text_single: '', 9 | placeholder_text_multiple: '', 10 | no_results_text: '' 11 | }; 12 | 13 | /** 14 | * Determine the variables used to initialie Chosen on an element. 15 | * 16 | * @param {Object} el select element. 17 | * @return {Object} Variables for Chosen. 18 | */ 19 | var getChosenVars = ( el ) => { 20 | let inputVars = chosenVars; 21 | 22 | // Ensure /> 85 | 86 | post_type ) { 26 | $title = esc_html__( 'Name this event', 'sugar-calendar' ); 27 | } 28 | 29 | // Return possibly modified title 30 | return $title; 31 | } 32 | 33 | /** 34 | * Filter the messages array and add custom messages for the built-in Post Type. 35 | * 36 | * @since 2.0.0 37 | * 38 | * @global WP_Post $post 39 | * @param array $messages 40 | * 41 | * @return array 42 | */ 43 | function updated_messages( $messages = array() ) { 44 | global $post; 45 | 46 | // Permalink 47 | $permalink = get_permalink( $post->ID ); 48 | if ( empty( $permalink ) ) { 49 | $permalink = ''; 50 | } 51 | 52 | // Preview URL 53 | $preview_url = get_preview_post_link( $post ); 54 | 55 | // Preview post link 56 | $preview_post_link_html = sprintf( ' %2$s', 57 | esc_url( $preview_url ), 58 | esc_html__( 'Preview event', 'sugar-calendar' ) 59 | ); 60 | 61 | // Scheduled post preview link 62 | $scheduled_post_link_html = sprintf( ' %2$s', 63 | esc_url( $permalink ), 64 | esc_html__( 'Preview event', 'sugar-calendar' ) 65 | ); 66 | 67 | // View post link 68 | $view_post_link_html = sprintf( ' %2$s', 69 | esc_url( $permalink ), 70 | esc_html__( 'View event', 'sugar-calendar' ) 71 | ); 72 | 73 | // Scheduled (uses WordPress site locale & timezone) 74 | $format = esc_html_x( 'M j, Y @ H:i', 'Date formatting', 'sugar-calendar' ); 75 | $timestamp = strtotime( $post->post_date ); 76 | $scheduled_date = date_i18n( $format, $timestamp ); 77 | 78 | // Add post type to messages array 79 | $messages[ sugar_calendar_get_event_post_type_id() ] = array( 80 | 0 => '', // Unused. Messages start at index 1. 81 | 1 => esc_html__( 'Event updated.', 'sugar-calendar' ) . $view_post_link_html, 82 | 4 => esc_html__( 'Event updated.', 'sugar-calendar' ), 83 | 5 => isset( $_GET['revision'] ) 84 | ? sprintf( esc_html__( 'Event restored to revision from %s.', 'sugar-calendar' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) 85 | : false, 86 | 6 => esc_html__( 'Event created.', 'sugar-calendar' ) . $view_post_link_html, 87 | 7 => esc_html__( 'Event saved.', 'sugar-calendar' ), 88 | 8 => esc_html__( 'Event submitted.', 'sugar-calendar' ) . $preview_post_link_html, 89 | 9 => sprintf( esc_html__( 'Event scheduled for: %s.', 'sugar-calendar' ), '' . $scheduled_date . '' ) . $scheduled_post_link_html, 90 | 10 => esc_html__( 'Event draft updated.', 'sugar-calendar' ) . $preview_post_link_html, 91 | ); 92 | 93 | // Return 94 | return $messages; 95 | } 96 | 97 | /** 98 | * Hides the inline-edit-group from the admin form 99 | * 100 | * @since 2.0.0 101 | */ 102 | function hide_quick_bulk_edit() { 103 | 104 | // Bail if not an event post type 105 | if ( ! post_type_supports( get_current_screen()->post_type, 'events' ) ) { 106 | return; 107 | } 108 | 109 | ?> 110 | 118 | ', 32 | '>=', 33 | '<', 34 | '<=', 35 | 'LIKE', 36 | 'NOT LIKE', 37 | 'IN', 38 | 'NOT IN', 39 | 'BETWEEN', 40 | 'NOT BETWEEN', 41 | 'EXISTS', 42 | 'NOT EXISTS', 43 | 'REGEXP', 44 | 'NOT REGEXP', 45 | 'RLIKE', 46 | ); 47 | 48 | // IN and BETWEEN 49 | const IN_BETWEEN_COMPARES = array( 50 | 'IN', 51 | 'NOT IN', 52 | 'BETWEEN', 53 | 'NOT BETWEEN' 54 | ); 55 | 56 | /** 57 | * Generate SQL WHERE clauses for a first-order query clause. 58 | * 59 | * "First-order" means that it's an array with a 'key' or 'value'. 60 | * 61 | * @since 1.0.0 62 | * 63 | * @param array $clause Query clause (passed by reference). 64 | * @param array $parent_query Parent query array. 65 | * @param string $clause_key Optional. The array key used to name the clause in the original `$meta_query` 66 | * parameters. If not provided, a key will be generated automatically. 67 | * @return array { 68 | * Array containing WHERE SQL clauses to append to a first-order query. 69 | * 70 | * @type string $where SQL fragment to append to the main WHERE clause. 71 | * } 72 | */ 73 | public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) { 74 | global $wpdb; 75 | 76 | // Default chunks 77 | $sql_chunks = array( 78 | 'where' => array(), 79 | 'join' => array(), 80 | ); 81 | 82 | // Maybe format compare clause 83 | if ( isset( $clause['compare'] ) ) { 84 | $clause['compare'] = strtoupper( $clause['compare'] ); 85 | 86 | // Or set compare clause based on value 87 | } else { 88 | $clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) 89 | ? 'IN' 90 | : '='; 91 | } 92 | 93 | // Fallback to equals 94 | if ( ! in_array( $clause['compare'], self::ALL_COMPARES, true ) ) { 95 | $clause['compare'] = '='; 96 | } 97 | 98 | // Uppercase or equals 99 | if ( isset( $clause['compare_key'] ) && ( 'LIKE' === strtoupper( $clause['compare_key'] ) ) ) { 100 | $clause['compare_key'] = strtoupper( $clause['compare_key'] ); 101 | } else { 102 | $clause['compare_key'] = '='; 103 | } 104 | 105 | // Get comparison from clause 106 | $compare = $clause['compare']; 107 | 108 | /** Build the WHERE clause ********************************************/ 109 | 110 | // Column name and value. 111 | if ( array_key_exists( 'key', $clause ) && array_key_exists( 'value', $clause ) ) { 112 | $column = sanitize_key( $clause['key'] ); 113 | $value = $clause['value']; 114 | 115 | // IN or BETWEEN 116 | if ( in_array( $compare, self::IN_BETWEEN_COMPARES, true ) ) { 117 | if ( ! is_array( $value ) ) { 118 | $value = preg_split( '/[,\s]+/', $value ); 119 | } 120 | 121 | // Anything else 122 | } else { 123 | $value = trim( $value ); 124 | } 125 | 126 | // Format WHERE from compare value(s) 127 | switch ( $compare ) { 128 | case 'IN': 129 | case 'NOT IN': 130 | $compare_string = '(' . substr( str_repeat( ',%s', count( $value ) ), 1 ) . ')'; 131 | $where = $wpdb->prepare( $compare_string, $value ); 132 | break; 133 | 134 | case 'BETWEEN': 135 | case 'NOT BETWEEN': 136 | $value = array_slice( $value, 0, 2 ); 137 | $where = $wpdb->prepare( '%s AND %s', $value ); 138 | break; 139 | 140 | case 'LIKE': 141 | case 'NOT LIKE': 142 | $value = '%' . $wpdb->esc_like( $value ) . '%'; 143 | $where = $wpdb->prepare( '%s', $value ); 144 | break; 145 | 146 | // EXISTS with a value is interpreted as '='. 147 | case 'EXISTS': 148 | $compare = '='; 149 | $where = $wpdb->prepare( '%s', $value ); 150 | break; 151 | 152 | // 'value' is ignored for NOT EXISTS. 153 | case 'NOT EXISTS': 154 | $where = ''; 155 | break; 156 | 157 | default: 158 | $where = $wpdb->prepare( '%s', $value ); 159 | break; 160 | 161 | } 162 | 163 | // Maybe add column, compare, & where to chunks 164 | if ( ! empty( $where ) ) { 165 | $sql_chunks['where'][] = "{$column} {$compare} {$where}"; 166 | } 167 | } 168 | 169 | /* 170 | * Multiple WHERE clauses (for meta_key and meta_value) should 171 | * be joined in parentheses. 172 | */ 173 | if ( 1 < count( $sql_chunks['where'] ) ) { 174 | $sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' ); 175 | } 176 | 177 | // Return 178 | return $sql_chunks; 179 | } 180 | } -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/database/engine/Queries/Meta.php: -------------------------------------------------------------------------------- 1 | init( $item ); 41 | } 42 | } 43 | 44 | /** 45 | * Initialize class properties based on data array. 46 | * 47 | * @since 1.0.0 48 | * 49 | * @param array $data 50 | */ 51 | private function init( $data = array() ) { 52 | $this->set_vars( $data ); 53 | } 54 | 55 | /** 56 | * Determines whether the current row exists. 57 | * 58 | * @since 1.0.0 59 | * 60 | * @return bool 61 | */ 62 | public function exists() { 63 | return ! empty( $this->id ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/database/engine/Schema.php: -------------------------------------------------------------------------------- 1 | columns ) || ! is_array( $this->columns ) ) { 44 | return; 45 | } 46 | 47 | // Juggle original columns array 48 | $columns = $this->columns; 49 | $this->columns = array(); 50 | 51 | // Loop through columns and create objects from them 52 | foreach ( $columns as $column ) { 53 | if ( is_array( $column ) ) { 54 | $this->columns[] = new Column( $column ); 55 | } elseif ( $column instanceof Column ) { 56 | $this->columns[] = $column; 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * Return the schema in string form. 63 | * 64 | * @since 1.0.0 65 | * 66 | * @return string Calls get_create_string() on every column. 67 | */ 68 | protected function to_string() { 69 | 70 | // Default return value 71 | $retval = ''; 72 | 73 | // Bail if no columns to convert 74 | if ( empty( $this->columns ) ) { 75 | return $retval; 76 | } 77 | 78 | // Loop through columns... 79 | foreach ( $this->columns as $column_info ) { 80 | if ( method_exists( $column_info, 'get_create_string' ) ) { 81 | $retval .= '\n' . $column_info->get_create_string() . ', '; 82 | } 83 | } 84 | 85 | // Return the string 86 | return $retval; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/database/events/Schema.php: -------------------------------------------------------------------------------- 1 | 'id', 35 | 'type' => 'bigint', 36 | 'length' => '20', 37 | 'unsigned' => true, 38 | 'extra' => 'auto_increment', 39 | 'primary' => true, 40 | 'sortable' => true 41 | ), 42 | 43 | // object_id 44 | array( 45 | 'name' => 'object_id', 46 | 'type' => 'bigint', 47 | 'length' => '20', 48 | 'unsigned' => true, 49 | 'default' => '0', 50 | 'sortable' => true 51 | ), 52 | 53 | // object_type 54 | array( 55 | 'name' => 'object_type', 56 | 'type' => 'varchar', 57 | 'length' => '20', 58 | 'default' => '', 59 | 'sortable' => true 60 | ), 61 | 62 | // object_subtype 63 | array( 64 | 'name' => 'object_subtype', 65 | 'type' => 'varchar', 66 | 'length' => '20', 67 | 'default' => '', 68 | 'sortable' => true 69 | ), 70 | 71 | // title 72 | array( 73 | 'name' => 'title', 74 | 'type' => 'text', 75 | 'default' => '', 76 | 'sortable' => true, 77 | 'searchable' => true 78 | ), 79 | 80 | // content 81 | array( 82 | 'name' => 'content', 83 | 'type' => 'longtext', 84 | 'default' => '', 85 | 'sortable' => false, 86 | 'searchable' => true 87 | ), 88 | 89 | // status 90 | array( 91 | 'name' => 'status', 92 | 'type' => 'varchar', 93 | 'length' => '20', 94 | 'default' => '', 95 | 'sortable' => true 96 | ), 97 | 98 | // start 99 | array( 100 | 'name' => 'start', 101 | 'type' => 'datetime', 102 | 'default' => '0000-00-00 00:00:00', 103 | 'date_query' => true, 104 | 'sortable' => true 105 | ), 106 | 107 | // start_tz 108 | array( 109 | 'name' => 'start_tz', 110 | 'type' => 'varchar', 111 | 'length' => '20', 112 | 'default' => '' 113 | ), 114 | 115 | // end 116 | array( 117 | 'name' => 'end', 118 | 'type' => 'datetime', 119 | 'default' => '0000-00-00 00:00:00', 120 | 'date_query' => true, 121 | 'sortable' => true 122 | ), 123 | 124 | // end_tz 125 | array( 126 | 'name' => 'end_tz', 127 | 'type' => 'varchar', 128 | 'length' => '20', 129 | 'default' => '' 130 | ), 131 | 132 | // all_day 133 | array( 134 | 'name' => 'all_day', 135 | 'type' => 'tinyint', 136 | 'length' => '1', 137 | 'default' => '' 138 | ), 139 | 140 | // recurrence 141 | array( 142 | 'name' => 'recurrence', 143 | 'type' => 'varchar', 144 | 'length' => '20', 145 | 'default' => '', 146 | 'sortable' => true 147 | ), 148 | 149 | // recurrence_interval 150 | array( 151 | 'name' => 'recurrence_interval', 152 | 'type' => 'bigint', 153 | 'length' => '20', 154 | 'unsigned' => true, 155 | 'default' => '0', 156 | 'sortable' => true 157 | ), 158 | 159 | // recurrence_count 160 | array( 161 | 'name' => 'recurrence_count', 162 | 'type' => 'bigint', 163 | 'length' => '20', 164 | 'unsigned' => true, 165 | 'default' => '0', 166 | 'sortable' => true 167 | ), 168 | 169 | // recurrence_end 170 | array( 171 | 'name' => 'recurrence_end', 172 | 'type' => 'datetime', 173 | 'default' => '0000-00-00 00:00:00', 174 | 'date_query' => true, 175 | 'sortable' => true 176 | ), 177 | 178 | // recurrence_end_tz 179 | array( 180 | 'name' => 'recurrence_end_tz', 181 | 'type' => 'varchar', 182 | 'length' => '20', 183 | 'default' => '' 184 | ), 185 | 186 | // date_created 187 | array( 188 | 'name' => 'date_created', 189 | 'type' => 'datetime', 190 | 'default' => '0000-00-00 00:00:00', 191 | 'created' => true, 192 | 'date_query' => true, 193 | 'sortable' => true 194 | ), 195 | 196 | // date_modified 197 | array( 198 | 'name' => 'date_modified', 199 | 'type' => 'datetime', 200 | 'default' => '0000-00-00 00:00:00', 201 | 'modified' => true, 202 | 'date_query' => true, 203 | 'sortable' => true 204 | ), 205 | 206 | // uuid 207 | array( 208 | 'uuid' => true, 209 | ) 210 | ); 211 | } 212 | -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/database/events/TableEventmeta.php: -------------------------------------------------------------------------------- 1 | schema = "meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, 39 | sc_event_id bigint(20) unsigned NOT NULL default 0, 40 | meta_key varchar(255) DEFAULT NULL, 41 | meta_value longtext DEFAULT NULL, 42 | KEY sc_event_id (sc_event_id), 43 | KEY meta_key (meta_key({$max_index_length}))"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/database/events/TableEvents.php: -------------------------------------------------------------------------------- 1 | 201901090003, 45 | '201901220001' => 201901220001, 46 | '201902040004' => 201902040004, 47 | '201902040005' => 201902040005, 48 | ); 49 | 50 | /** 51 | * Setup the database schema 52 | * 53 | * Note: title & content columns exist here mostly for easier searching, but 54 | * 55 | * 56 | * @since 2.0.0 57 | */ 58 | protected function set_schema() { 59 | $this->schema = "id bigint(20) unsigned NOT NULL auto_increment, 60 | object_id bigint(20) unsigned NOT NULL default '0', 61 | object_type varchar(20) NOT NULL default '', 62 | object_subtype varchar(20) NOT NULL default '', 63 | title text NOT NULL, 64 | content longtext NOT NULL, 65 | status varchar(20) NOT NULL default '', 66 | start datetime NOT NULL default '0000-00-00 00:00:00', 67 | start_tz varchar(20) NOT NULL default '', 68 | end datetime NOT NULL default '0000-00-00 00:00:00', 69 | end_tz varchar(20) NOT NULL default '', 70 | all_day tinyint(1) NOT NULL default '0', 71 | recurrence varchar(20) NOT NULL default '', 72 | recurrence_interval bigint(20) unsigned NOT NULL default '0', 73 | recurrence_count bigint(20) unsigned NOT NULL default '0', 74 | recurrence_end datetime NOT NULL default '0000-00-00 00:00:00', 75 | recurrence_end_tz varchar(20) NOT NULL default '', 76 | date_created datetime NOT NULL default '0000-00-00 00:00:00', 77 | date_modified datetime NOT NULL default '0000-00-00 00:00:00', 78 | uuid varchar(100) NOT NULL default '', 79 | PRIMARY KEY (id), 80 | KEY `object` (object_id,object_type,object_subtype), 81 | KEY `event_status` (status), 82 | KEY `event_times` (start,end,start_tz,end_tz), 83 | KEY `event_recur` (recurrence), 84 | KEY `event_recur_times` (recurrence_end,recurrence_end_tz)"; 85 | } 86 | 87 | /** 88 | * Upgrade to version 201901090002 89 | * - Add index for the `status` column. 90 | * 91 | * @since 2.0.0 92 | * 93 | * @return bool True if upgrade was successful, false otherwise. 94 | */ 95 | protected function __201901090003() { 96 | 97 | // Look for column 98 | $result = $this->column_exists( 'status' ); 99 | 100 | // Maybe add column 101 | if ( false === $result ) { 102 | $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN `status` varchar(20) default '' AFTER `content`;" ); 103 | $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX status (status(20));" ); 104 | } 105 | 106 | // Return success/fail 107 | return $this->is_success( true ); 108 | } 109 | 110 | /** 111 | * Upgrade to version 201901090002 112 | * - Add `object_subtype` column 113 | * 114 | * @since 2.0.0 115 | * 116 | * @return bool True if upgrade was successful, false otherwise. 117 | */ 118 | protected function __201901220001() { 119 | 120 | // Look for column 121 | $result = $this->column_exists( 'object_subtype' ); 122 | 123 | // Maybe add column 124 | if ( false === $result ) { 125 | $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN `object_subtype` varchar(20) default '' AFTER `object_type`;" ); 126 | } 127 | 128 | // Return success/fail 129 | return $this->is_success( true ); 130 | } 131 | 132 | /** 133 | * Upgrade to version 201902040003 134 | * - Remove `recurrence_start` column that was added temporarily 135 | * - Remove `recurrence_start_tz` column that was added temporarily 136 | * 137 | * @since 2.0.0 138 | * 139 | * @return bool True if upgrade was successful, false otherwise. 140 | */ 141 | protected function __201902040004() { 142 | 143 | // Look for column 144 | $result = $this->column_exists( 'recurrence_start' ); 145 | 146 | // Maybe add column 147 | if ( true === $result ) { 148 | $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP COLUMN `recurrence_start`;" ); 149 | } 150 | 151 | // Look for column 152 | $result = $this->column_exists( 'recurrence_start_tz' ); 153 | 154 | // Maybe add column 155 | if ( true === $result ) { 156 | $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP COLUMN `recurrence_start_tz`;" ); 157 | } 158 | 159 | // Return success/fail 160 | return $this->is_success( true ); 161 | } 162 | 163 | /** 164 | * Upgrade to version 201901090005 165 | * - Add `recurrence_count` column for future use 166 | * - Add `recurrence_interval` column for future use 167 | * 168 | * @since 2.0.0 169 | * 170 | * @return bool True if upgrade was successful, false otherwise. 171 | */ 172 | protected function __201902040005() { 173 | 174 | // Look for column 175 | $result = $this->column_exists( 'recurrence_interval' ); 176 | 177 | // Maybe add column 178 | if ( false === $result ) { 179 | $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN `recurrence_interval` bigint(20) unsigned NOT NULL default '0' after `recurrence`;" ); 180 | } 181 | 182 | // Look for column 183 | $result = $this->column_exists( 'recurrence_count' ); 184 | 185 | // Maybe add column 186 | if ( false === $result ) { 187 | $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN `recurrence_count` bigint(20) unsigned NOT NULL default '0' after `recurrence_interval`;" ); 188 | } 189 | 190 | // Return success/fail 191 | return $this->is_success( true ); 192 | } 193 | } -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/terms/class-term-colors.php: -------------------------------------------------------------------------------- 1 | url = SC_PLUGIN_URL . 'includes/admin/assets/'; 58 | } 59 | 60 | /** Taxonomy **************************************************************/ 61 | 62 | /** 63 | * Setup the labels. 64 | * 65 | * @since 2.0.0 66 | * 67 | * @param array $args 68 | * @return array 69 | */ 70 | public function setup_labels() { 71 | 72 | // Setup the labels 73 | $this->labels = array( 74 | 'singular' => esc_html__( 'Color', 'sugar-calendar' ), 75 | 'plural' => esc_html__( 'Colors', 'sugar-calendar' ), 76 | 'description' => esc_html__( 'Assign calendars a custom color to visually separate them from each-other.', 'sugar-calendar' ) 77 | ); 78 | } 79 | 80 | /** 81 | * Only add colors to taxonomies that support them. 82 | * 83 | * @since 2.0.0 84 | * 85 | * @param array $args 86 | * @return array 87 | */ 88 | public function filter_taxonomies( $args = array() ) { 89 | $args['colors'] = true; 90 | 91 | return $args; 92 | } 93 | 94 | /** Assets ****************************************************************/ 95 | 96 | /** 97 | * Enqueue quick-edit JS 98 | * 99 | * @since 2.0.0 100 | */ 101 | public function enqueue_scripts() { 102 | 103 | // Enqueue the color picker 104 | wp_enqueue_script( 'wp-color-picker' ); 105 | wp_enqueue_style( 'wp-color-picker' ); 106 | 107 | // Enqueue fancy coloring; includes quick-edit 108 | wp_enqueue_script( 'term-color', $this->url . 'js/term-color.js', array( 'wp-color-picker' ), $this->db_version, true ); 109 | } 110 | 111 | /** 112 | * Sanitizing the hex color 113 | * 114 | * @since 2.0.0 115 | * 116 | * @param string $data 117 | * @return string 118 | */ 119 | public function sanitize_callback( $data = '' ) { 120 | return sugar_calendar_sanitize_hex_color( $data ); 121 | } 122 | 123 | /** 124 | * Add help tabs for `color` column 125 | * 126 | * @since 2.0.0 127 | */ 128 | public function help_tabs() { 129 | get_current_screen()->add_help_tab( array( 130 | 'id' => 'wp_term_color_help_tab', 131 | 'title' => esc_html__( 'Color', 'sugar-calendar' ), 132 | 'content' => '

' . esc_html__( 'Calendars can have unique colors to help separate them from each other.', 'sugar-calendar' ) . '

', 133 | ) ); 134 | } 135 | 136 | /** 137 | * Align custom `color` column 138 | * 139 | * @since 2.0.0 140 | */ 141 | public function admin_head() { 142 | ?> 143 | 144 | 171 | 172 | '; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /sugar-calendar/includes/classes/terms/class-term-timezones.php: -------------------------------------------------------------------------------- 1 | url = SC_PLUGIN_URL . 'includes/admin/assets/'; 63 | } 64 | 65 | /** Taxonomy **************************************************************/ 66 | 67 | /** 68 | * Setup the labels. 69 | * 70 | * @since 2.1.0 71 | * 72 | * @param array $args 73 | * @return array 74 | */ 75 | public function setup_labels() { 76 | 77 | // Setup the labels 78 | $this->labels = array( 79 | 'singular' => esc_html__( 'Time Zone', 'sugar-calendar' ), 80 | 'plural' => esc_html__( 'Time Zones', 'sugar-calendar' ), 81 | 'description' => esc_html__( 'Assign calendars a time zone for events to inherit their settings from.', 'sugar-calendar' ) 82 | ); 83 | } 84 | 85 | /** 86 | * Only add time zones to taxonomies that support them. 87 | * 88 | * @since 2.1.0 89 | * 90 | * @param array $args 91 | * @return array 92 | */ 93 | public function filter_taxonomies( $args = array() ) { 94 | $args['timezones'] = true; 95 | 96 | return $args; 97 | } 98 | 99 | /** Assets ****************************************************************/ 100 | 101 | /** 102 | * Enqueue quick-edit JS 103 | * 104 | * @since 2.1.0 105 | */ 106 | public function enqueue_scripts() { 107 | 108 | // Version 109 | $ver = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG 110 | ? time() 111 | : $this->db_version; 112 | 113 | // Enqueue fancy time zone; includes quick-edit 114 | wp_enqueue_script( 'term-timezone', $this->url . 'js/term-timezone.js', array(), $ver, true ); 115 | } 116 | 117 | /** 118 | * Sanitizing the hex time zone 119 | * 120 | * @since 2.1.0 121 | * 122 | * @param string $data 123 | * @return string 124 | */ 125 | public function sanitize_callback( $data = '' ) { 126 | return sugar_calendar_sanitize_timezone( $data ); 127 | } 128 | 129 | /** 130 | * Add help tabs for `timezone` column 131 | * 132 | * @since 2.1.0 133 | */ 134 | public function help_tabs() { 135 | get_current_screen()->add_help_tab( array( 136 | 'id' => 'wp_term_timezone_help_tab', 137 | 'title' => esc_html__( 'Time Zone', 'sugar-calendar' ), 138 | 'content' => '

' . esc_html__( 'Time zones.', 'sugar-calendar' ) . '

', 139 | ) ); 140 | } 141 | 142 | /** 143 | * Align custom `timezone` column 144 | * 145 | * @since 2.1.0 146 | */ 147 | public function admin_head() { 148 | ?> 149 | 150 | 177 | 178 | term_id ) 194 | ? $this->get_meta( $term->term_id ) 195 | : ''; 196 | 197 | sugar_calendar_timezone_dropdown( array( 198 | 'id' => 'term-' . $this->meta_key, 199 | 'name' => 'term-' . $this->meta_key, 200 | 'class' => 'sc-select-chosen', 201 | 'current' => $value, 202 | 203 | // What time zones to allow 204 | 'allow_empty' => true, 205 | 'allow_utc' => true, 206 | 'allow_manual' => false, 207 | ) ); 208 | } 209 | 210 | /** 211 | * Output the form field 212 | * 213 | * @since 2.0.0 214 | * 215 | * @param $term 216 | */ 217 | protected function quick_edit_form_field() { 218 | sugar_calendar_timezone_dropdown( array( 219 | 'id' => 'term-' . $this->meta_key, 220 | 'name' => 'term-' . $this->meta_key, 221 | 'class' => 'ptitle', 222 | 'current' => '', 223 | 224 | // What time zones to allow 225 | 'allow_empty' => true, 226 | 'allow_utc' => true, 227 | 'allow_manual' => false, 228 | ) ); 229 | } 230 | 231 | /** 232 | * Return the formatted output for the column row 233 | * 234 | * @since 2.1.0 235 | * 236 | * @param string $meta 237 | */ 238 | protected function format_output( $meta = '' ) { 239 | 240 | // Replace underscores with spaces 241 | $tz = str_replace( '_', ' ', $meta ); 242 | 243 | // Get offset 244 | $offset = sugar_calendar_human_diff_timezone( $meta ); 245 | 246 | // Escape & return 247 | return '' . esc_html( $tz ) . ''; 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /sugar-calendar/includes/common/assets.php: -------------------------------------------------------------------------------- 1 | prefix ) . '_PLUGIN_URL' ); 34 | } 35 | 36 | /** 37 | * Get the asset version. 38 | * 39 | * @since 2.0.20 40 | * 41 | * @return string 42 | */ 43 | function get_version() { 44 | return doing_debug() 45 | ? sugar_calendar_get_request_time() 46 | : constant( strtoupper( Plugin::instance()->prefix ) . '_PLUGIN_VERSION' ); 47 | } 48 | 49 | /** 50 | * Get the CSS path. 51 | * 52 | * Use this function in conjunction with Grunt CSS tooling to automate the 53 | * generation and enqueueing of minified and right-to-left styling. 54 | * 55 | * Can be used for Admin or Front-end CSS. 56 | * 57 | * @since 2.0.20 58 | * 59 | * @return string 60 | */ 61 | function get_css_path() { 62 | 63 | // Default CSS path 64 | $css_path = ''; 65 | 66 | // Minify? 67 | if ( ! doing_debug() ) { 68 | $css_path = trailingslashit( 'min' ); 69 | } 70 | 71 | // Right-to-Left? 72 | if ( is_rtl() ) { 73 | $css_path .= 'rtl'; 74 | } else { 75 | $css_path .= 'ltr'; 76 | } 77 | 78 | // Maybe add a trailing slash 79 | if ( ! empty( $css_path ) ) { 80 | $css_path = trailingslashit( $css_path ); 81 | } 82 | 83 | // Return the CSS path 84 | return $css_path; 85 | } 86 | -------------------------------------------------------------------------------- /sugar-calendar/includes/common/editor.php: -------------------------------------------------------------------------------- 1 | 'block', 60 | 'label' => esc_html__( 'Block Editor', 'sugar-calendar' ), 61 | 'disabled' => ! function_exists( 'register_block_type' ) 62 | ), 63 | 64 | // Classic Editor 65 | array( 66 | 'id' => 'classic', 67 | 'label' => esc_html__( 'Classic Editor', 'sugar-calendar' ), 68 | 'disabled' => false 69 | ), 70 | ) ); 71 | } 72 | 73 | /** 74 | * Get the currently selected Editor custom fields setting. 75 | * 76 | * @since 2.1.0 77 | * 78 | * @return bool 79 | */ 80 | function custom_fields() { 81 | $retval = get_option( 'sc_custom_fields', false ); 82 | 83 | // Filter & return 84 | return apply_filters( 'sugar_calendar_get_custom_fields', $retval, false ); 85 | } 86 | -------------------------------------------------------------------------------- /sugar-calendar/includes/common/hooks.php: -------------------------------------------------------------------------------- 1 | $key, 148 | 'site' => $key, 149 | 'network' => $key 150 | ); 151 | 152 | break; 153 | } 154 | 155 | // Filter & return 156 | return (array) apply_filters( 'sugar_calendar_map_user_preference_key', $retval, $key ); 157 | } 158 | -------------------------------------------------------------------------------- /sugar-calendar/includes/common/settings.php: -------------------------------------------------------------------------------- 1 | 30 21 | ) ); 22 | register_setting( 'sc_main_display', 'sc_start_of_week', array( 23 | 'default' => get_option( 'start_of_week' ) 24 | ) ); 25 | register_setting( 'sc_main_display', 'sc_date_format', array( 26 | 'default' => get_option( 'date_format' ) 27 | ) ); 28 | register_setting( 'sc_main_display', 'sc_time_format', array( 29 | 'default' => get_option( 'time_format' ) 30 | ) ); 31 | register_setting( 'sc_main_display', 'sc_day_color_style', array( 32 | 'default' => 'none' 33 | ) ); 34 | 35 | // Time Zones 36 | register_setting( 'sc_main_timezones', 'sc_timezone_convert' ); 37 | register_setting( 'sc_main_timezones', 'sc_timezone_type' ); 38 | register_setting( 'sc_main_timezones', 'sc_timezone', array( 39 | 'default' => get_option( 'timezone_string' ) 40 | ) ); 41 | 42 | // Editor 43 | register_setting( 'sc_main_editing', 'sc_editor_type' ); 44 | register_setting( 'sc_main_editing', 'sc_custom_fields' ); 45 | register_setting( 'sc_main_editing', sugar_calendar_get_default_calendar_option_name() ); 46 | 47 | do_action( 'sugar_calendar_register_settings' ); 48 | } 49 | -------------------------------------------------------------------------------- /sugar-calendar/includes/events/relationships.php: -------------------------------------------------------------------------------- 1 | 'Events', 29 | 'type' => 'post', 30 | 'subtype' => sugar_calendar_get_event_post_type_id() 31 | ) 32 | ) ); 33 | } 34 | -------------------------------------------------------------------------------- /sugar-calendar/includes/post/cron.php: -------------------------------------------------------------------------------- 1 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ID, 'post' ); 26 | 27 | // Default return value 28 | $retval = '—'; 29 | 30 | if ( ! empty( $event->start ) ) { 31 | 32 | // Date 33 | $retval = $event->start_date( get_option( 'sc_date_format' ) ); 34 | 35 | // Time 36 | if ( empty( $event->all_day ) ) { 37 | $retval .= '
' . $event->start_date( get_option( 'sc_time_format' ) ); 38 | } 39 | } 40 | 41 | // Filter & return 42 | return apply_filters( 'sugar_calendar_get_event_start_date_time', $retval, $post, $event->start ); 43 | } 44 | 45 | /** 46 | * Return the end date & time of an event 47 | * 48 | * @since 2.0.0 49 | * 50 | * @param mixed $post 51 | * 52 | * @return string 53 | */ 54 | function sugar_calendar_get_event_end_date_time( $post = false ) { 55 | 56 | // Get the post object & start date 57 | $post = get_post( $post ); 58 | $event = sugar_calendar_get_event_by_object( $post->ID ); 59 | 60 | // Default return value 61 | $retval = '—'; 62 | 63 | if ( ! empty( $event->end ) ) { 64 | 65 | // Date 66 | $retval = $event->end_date( get_option( 'sc_date_format' ) ); 67 | 68 | // Time 69 | if ( empty( $event->all_day ) ) { 70 | $retval .= '
' . $event->end_date( get_option( 'sc_time_format' ) ); 71 | } 72 | } 73 | 74 | // Filter & return 75 | return apply_filters( 'sugar_calendar_get_event_end_date_time', $retval, $post, $event->end ); 76 | } 77 | 78 | /** 79 | * Return the end date & time of an event 80 | * 81 | * @since 2.0.0 82 | * 83 | * @param mixed $post 84 | * 85 | * @return string 86 | */ 87 | function sugar_calendar_get_event_recurrence( $post = false ) { 88 | 89 | // Get the post object & start date 90 | $post = get_post( $post ); 91 | $event = sugar_calendar_get_event_by_object( $post->ID ); 92 | $recurrence = $event->recurrence; 93 | $intervals = sugar_calendar_get_recurrence_types(); 94 | 95 | // Default return value 96 | $retval = '—'; 97 | 98 | if ( ! empty( $recurrence ) && isset( $intervals[ $recurrence ] ) ) { 99 | $retval = $intervals[ $recurrence ]; 100 | } 101 | 102 | // Filter & return 103 | return apply_filters( 'sugar_calendar_get_event_recurrence', $retval, $post, $recurrence ); 104 | } 105 | 106 | /** 107 | * Return the duration of an event 108 | * 109 | * @since 2.0.0 110 | * 111 | * @param mixed $post 112 | * 113 | * @return string 114 | */ 115 | function sugar_calendar_get_event_duration( $post = false ) { 116 | 117 | // Get the post object & start date 118 | $post = get_post( $post ); 119 | $event = sugar_calendar_get_event_by_object( $post->ID ); 120 | $all_day = $event->is_all_day(); 121 | $start_date = $event->start; 122 | $end_date = $event->end; 123 | 124 | // Default return value 125 | $retval = ''; 126 | 127 | // All day event 128 | if ( true === $all_day ) { 129 | 130 | // 1 day 131 | if ( $event->start_date( 'd' ) === $event->end_date( 'd' ) ) { 132 | $retval .= esc_html__( 'All Day', 'sugar-calendar' ); 133 | 134 | // More than 1 day 135 | } else { 136 | $retval .= sugar_calendar_human_diff_time( 137 | strtotime( 'midnight', $start_date ), 138 | strtotime( 'midnight', $end_date ) 139 | ); 140 | } 141 | 142 | // Specific times 143 | } else { 144 | $retval .= sugar_calendar_human_diff_time( $start_date, $end_date ); 145 | } 146 | 147 | // Filter & return 148 | return apply_filters( 'sugar_calendar_get_event_duration', $retval, $post, $all_day, $start_date, $end_date ); 149 | } 150 | 151 | /** 152 | * Copy a post, its taxonomy terms, and all meta data 153 | * 154 | * @since 2.1.7 155 | * 156 | * @param int $original_id 157 | * @param array $data 158 | * 159 | * @return int Zero on failure. ID of new post on success. 160 | */ 161 | function sugar_calendar_copy_post( $original_id = 0, $data = array() ) { 162 | 163 | // Get the post 164 | $post = get_post( $original_id, 'ARRAY_A' ); 165 | 166 | // Bail if no original post 167 | if ( empty( $post ) ) { 168 | return 0; 169 | } 170 | 171 | // Set post date timestamp 172 | $post['post_date'] = date( 'Y-m-d H:i:s' ); 173 | 174 | // Unset some keys, to allow them to be set to their defaults 175 | unset( 176 | $post['guid'], 177 | $post['comment_count'], 178 | $post['post_date_gmt'] 179 | ); 180 | 181 | // Allow custom data overrides 182 | $save = array_merge( $post, $data ); 183 | 184 | // Unset the ID column, so an update does not occur 185 | unset( $save['ID'] ); 186 | 187 | // Insert the post into the database 188 | $new_id = wp_insert_post( $save, false, false ); 189 | 190 | // Bail if insert failed 191 | if ( empty( $new_id ) ) { 192 | return 0; 193 | } 194 | 195 | // Get taxonomies for post 196 | $taxonomies = get_object_taxonomies( $post['post_type'] ); 197 | 198 | // Skip if no taxonomies 199 | if ( ! empty( $taxonomies ) ) { 200 | 201 | // Loop through all taxonomies 202 | foreach ( $taxonomies as $taxonomy ) { 203 | 204 | // Get the terms for this taxonomy 205 | $terms = wp_get_post_terms( $original_id, $taxonomy, array( 206 | 'fields' => 'names' 207 | ) ); 208 | 209 | // Maybe set terms for this taxonomy 210 | if ( ! empty( $terms ) ) { 211 | wp_set_object_terms( $new_id, $terms, $taxonomy ); 212 | } 213 | } 214 | } 215 | 216 | // Get meta data for post 217 | $custom_fields = get_post_custom( $original_id ); 218 | 219 | // Skip if no post meta 220 | if ( ! empty( $custom_fields ) ) { 221 | 222 | // Loop through all post meta 223 | foreach ( $custom_fields as $key => $value ) { 224 | 225 | // Unserialize, to be serialized again when added 226 | $value = maybe_unserialize( $value[0] ); 227 | 228 | // Add the meta 229 | add_post_meta( $new_id, $key, $value ); 230 | } 231 | } 232 | 233 | // Return the ID of the new post ID 234 | return $new_id; 235 | } 236 | -------------------------------------------------------------------------------- /sugar-calendar/includes/post/query-filters.php: -------------------------------------------------------------------------------- 1 | is_main_query() ) { 28 | return $query; 29 | } 30 | 31 | // Get post types and taxonomies 32 | $pts = sugar_calendar_allowed_post_types(); 33 | $tax = sugar_calendar_get_object_taxonomies( $pts ); 34 | 35 | // Only proceed if an Event post type or Calendar taxonomy 36 | if ( is_post_type_archive( $pts ) || is_tax( $tax ) ) { 37 | 38 | // Get the current post type 39 | $post_type = $query->get( 'post_type' ); 40 | 41 | // Fallback to default post type 42 | if ( empty( $post_type ) ) { 43 | $post_type = sugar_calendar_get_event_post_type_id(); 44 | } 45 | 46 | // Events table alias 47 | $alias = 'sce'; 48 | 49 | // Get timezone 50 | $timezone = sugar_calendar_get_timezone_object( sc_get_timezone() ); 51 | 52 | // Get time, to query before/after/in-progress 53 | $time = ! empty( $_GET['event-time'] ) 54 | ? absint( urldecode( $_GET['event-time'] ) ) 55 | : gmdate( 'Y-m-d H:i:s' ); 56 | 57 | // Get datetime 58 | $datetime = sugar_calendar_get_datetime_object( $time, 'UTC', $timezone ); 59 | 60 | // Display argument 61 | $display_arg = ! empty( $_GET[ 'event-display' ] ) 62 | ? strtolower( sanitize_key( urldecode( $_GET[ 'event-display' ] ) ) ) 63 | : ''; 64 | 65 | // Order argument 66 | $order_arg = ! empty( $_GET[ 'event-order' ] ) 67 | ? strtoupper( sanitize_key( urldecode( $_GET[ 'event-order' ] ) ) ) 68 | : ''; 69 | 70 | // Default order, based on display arg 71 | $default_order = ( 'upcoming' === $display_arg ) 72 | ? 'ASC' 73 | : 'DESC'; 74 | 75 | // Maybe force a default 76 | if ( ! in_array( $order_arg, array( 'ASC', 'DESC' ), true ) ) { 77 | $order_arg = $default_order; 78 | } 79 | 80 | // Force the post type 81 | $query->set( 'post_type', $post_type ); 82 | 83 | // Custom query args 84 | $query->set( '_sc_datetime', $datetime ); 85 | $query->set( '_sc_alias', $alias ); 86 | $query->set( '_sc_object', $post_type ); 87 | $query->set( '_sc_order', $order_arg ); 88 | $query->set( '_sc_display', $display_arg ); 89 | 90 | // Add query filters 91 | add_filter( 'posts_where', 'sc_modify_events_archive_where', 10, 2 ); 92 | add_filter( 'posts_join', 'sc_modify_events_archive_join', 10, 2 ); 93 | add_filter( 'posts_orderby', 'sc_modify_events_archive_orderby', 10, 2 ); 94 | 95 | // Return the modified query 96 | return $query; 97 | } 98 | } 99 | 100 | /** 101 | * Filter Events archive WHERE query clause. 102 | * 103 | * Appends before or after today. 104 | * 105 | * @since 2.0.2 106 | * 107 | * @param string $where 108 | * @param object $query 109 | * 110 | * @return string 111 | */ 112 | function sc_modify_events_archive_where( $where = '', $query = false ) { 113 | 114 | // Get the alias 115 | $alias = $query->get( '_sc_alias' ); 116 | 117 | // Bail if no alias 118 | if ( empty( $alias ) ) { 119 | return $where; 120 | } 121 | 122 | // Get the other args 123 | $datetime = $query->get( '_sc_datetime' ); 124 | $display = $query->get( '_sc_display' ); 125 | 126 | // Get the time 127 | $time = $datetime->format( 'Y-m-d H:i:s' ); 128 | 129 | // In-Progress 130 | if ( 'in-progress' === $display ) { 131 | $where .= " AND ( {$alias}.start <= '{$time}' AND {$alias}.end >= '{$time}' )"; 132 | 133 | // Upcoming (includes in-progress) 134 | } elseif ( 'upcoming' === $display ) { 135 | $where .= " AND {$alias}.end >= '{$time}'"; 136 | 137 | // Past (excludes in-progress) 138 | } elseif ( 'past' === $display ) { 139 | $where .= " AND {$alias}.end <= '{$time}'"; 140 | } 141 | 142 | // Return new where 143 | return $where; 144 | } 145 | 146 | /** 147 | * Filter Events archive JOIN query clause. 148 | * 149 | * Appends right join on Events table of the current type & subtype. 150 | * 151 | * @since 2.0.2 152 | * 153 | * @param string $join 154 | * @param object $query 155 | * 156 | * @return string 157 | */ 158 | function sc_modify_events_archive_join( $join = '', $query = false ) { 159 | global $wpdb; 160 | 161 | // Get the alias arg 162 | $alias = $query->get( '_sc_alias' ); 163 | 164 | // Bail if no var 165 | if ( empty( $alias ) ) { 166 | return $join; 167 | } 168 | 169 | // Get the object type 170 | $pt = $query->get( '_sc_object' ); 171 | 172 | // Add a right join 173 | $join .= " RIGHT JOIN {$wpdb->sc_events} AS {$alias} ON ({$wpdb->posts}.ID = {$alias}.object_id AND {$alias}.object_type = 'post' AND {$alias}.object_subtype = '{$pt}')"; 174 | 175 | // Return new join 176 | return $join; 177 | } 178 | 179 | /** 180 | * Filter Events archive ORDERBY query clause. 181 | * 182 | * Overrides orderby to use Events start. 183 | * 184 | * @since 2.0.2 185 | * 186 | * @param string $orderby 187 | * @param object $query 188 | * 189 | * @return string 190 | */ 191 | function sc_modify_events_archive_orderby( $orderby = '', $query = false ) { 192 | 193 | // Get the alias arg 194 | $alias = $query->get( '_sc_alias' ); 195 | 196 | // Bail if no var 197 | if ( empty( $alias ) ) { 198 | return $orderby; 199 | } 200 | 201 | // Get the order arg 202 | $order = $query->get( '_sc_order' ); 203 | 204 | // Replace orderby 205 | $orderby = "{$alias}.start {$order}"; 206 | 207 | // Return new orderby 208 | return $orderby; 209 | } 210 | -------------------------------------------------------------------------------- /sugar-calendar/includes/post/relationship.php: -------------------------------------------------------------------------------- 1 | ID, 'post' ); 35 | 36 | // Bail if no event 37 | if ( empty( $event ) || ! $event->exists() ) { 38 | return; 39 | } 40 | 41 | // Update the event status to match 42 | sugar_calendar_update_event( $event->id, array( 43 | 'status' => $post->post_status 44 | ) ); 45 | } 46 | 47 | /** 48 | * Delete events for a given post ID. 49 | * 50 | * This is hooked to the `deleted_posts` action to ensure that all events 51 | * related to a post ID are deleted when the post is also deleted. 52 | * 53 | * @since 2.0.0 54 | * 55 | * @param int $post_id 56 | * @return array 57 | */ 58 | function sugar_calendar_delete_post_events( $post_id = 0 ) { 59 | return sugar_calendar_delete_events( array( 60 | 'object_id' => $post_id, 61 | 'object_type' => 'post' 62 | ) ); 63 | } 64 | 65 | /** Taxonomies ****************************************************************/ 66 | 67 | /** 68 | * Get which taxonomy term is being queried. 69 | * 70 | * First this checks the global $_REQUEST, then it checks the $query. 71 | * 72 | * @since 2.0.6 73 | * 74 | * @param string $taxonomy 75 | * @param object|Query $query 76 | * 77 | * @return mixed False if no term, String(slug) if term 78 | */ 79 | function sugar_calendar_get_taxonomy_term_for_query( $taxonomy = '', $query = false ) { 80 | 81 | // Default return value 82 | $retval = false; 83 | 84 | // Sanitize the requested term 85 | if ( ! empty( $_REQUEST[ $taxonomy ] ) ) { 86 | $retval = sanitize_text_field( $_REQUEST[ $taxonomy ] ); 87 | 88 | // Sanitize the queried term 89 | } elseif ( ! empty( $query->query_vars[ $taxonomy ] ) ) { 90 | $retval = sanitize_key( $query->query_vars[ $taxonomy ] ); 91 | } 92 | 93 | // Return the term, or false 94 | return $retval; 95 | } 96 | 97 | /** 98 | * Get all of the requested terms being queried for. 99 | * 100 | * Eventually gets fed into WP_Tax_Query. 101 | * 102 | * @since 2.0.19 103 | * 104 | * @param object $query 105 | * @return array 106 | */ 107 | function sugar_calendar_get_requested_terms( $query = false ) { 108 | 109 | // Default return value 110 | $retval = array(); 111 | 112 | // Get the taxonomies 113 | $taxos = sugar_calendar_get_object_taxonomies( '', 'names' ); 114 | 115 | // Bail if no taxonomies 116 | if ( empty( $taxos ) ) { 117 | return $retval; 118 | } 119 | 120 | // Get the term slug 121 | foreach ( $taxos as $tax ) { 122 | 123 | // Look for requested term in query 124 | $term = sugar_calendar_get_taxonomy_term_for_query( $tax, $query ); 125 | 126 | // Break out of loop if term found for query 127 | if ( ! empty( $term ) ) { 128 | array_push( $retval, array( 129 | 'tax' => $tax, 130 | 'term' => $term 131 | ) ); 132 | } 133 | } 134 | 135 | // Filter & return 136 | return (array) apply_filters( 'sugar_calendar_get_requested_terms', $retval, $query ); 137 | } 138 | 139 | /** 140 | * Filter events query variables and maybe add the taxonomy and term. 141 | * 142 | * This filter is necessary to ensure events queries are cached using the 143 | * taxonomy and term they are queried by. 144 | * 145 | * @since 2.0.0 146 | * 147 | * @param object|Query $query 148 | */ 149 | function sugar_calendar_pre_get_events_by_taxonomy( $query ) { 150 | 151 | // Get the requested term 152 | $terms = sugar_calendar_get_requested_terms( $query ); 153 | 154 | // Bail if terms are empty 155 | if ( empty( $terms ) ) { 156 | return; 157 | } 158 | 159 | // Loop through terms and add them to primary query vars 160 | foreach ( $terms as $term ) { 161 | 162 | // Add the taxonomy & term to query vars 163 | $query->set_query_var( $term['tax'], $term['term'] ); 164 | } 165 | } 166 | 167 | /** 168 | * Filter events queries and maybe JOIN by taxonomy term relationships 169 | * 170 | * @since 2.0.0 171 | * 172 | * @param array $clauses 173 | * @param object|Query $query 174 | * 175 | * @return array 176 | */ 177 | function sugar_calendar_join_by_taxonomy_term( $clauses = array(), $query = false ) { 178 | 179 | // Get the requested terms 180 | $terms = sugar_calendar_get_requested_terms( $query ); 181 | 182 | // Bail if terms are empty 183 | if ( empty( $terms ) ) { 184 | return $clauses; 185 | } 186 | 187 | // Default arguments 188 | $args = array(); 189 | 190 | // Loop through terms 191 | foreach ( $terms as $term ) { 192 | 193 | // No term (NOT EXISTS) 194 | if ( in_array( $term['term'], array( '-1', '__sc_none__' ), true ) ) { 195 | array_push( $args, array( 196 | 'taxonomy' => $term['tax'], 197 | 'operator' => 'NOT EXISTS' 198 | ) ); 199 | 200 | // Specific term 201 | } elseif ( ! empty( $term['tax'] ) && ! empty( $term['term'] ) ) { 202 | array_push( $args, array( 203 | 'taxonomy' => $term['tax'], 204 | 'terms' => $term['term'], 205 | 'field' => 'slug' 206 | ) ); 207 | } 208 | } 209 | 210 | // Bail if no arguments 211 | if ( empty( $args ) ) { 212 | return; 213 | } 214 | 215 | // Get a taxonomy query object 216 | $tax_query = new WP_Tax_Query( $args ); 217 | 218 | // Get clauses 219 | $sql_clauses = $tax_query->get_sql( 'sc_e', 'object_id' ); 220 | $join_clauses = array( $clauses['join'], $sql_clauses['join'] ); 221 | $where_clauses = array( $clauses['where'], $sql_clauses['where'] ); 222 | 223 | // Join clauses 224 | $clauses['join'] = implode( '', array_filter( $join_clauses ) ); 225 | $clauses['where'] = implode( '', array_filter( $where_clauses ) ); 226 | 227 | // Return new clauses 228 | return $clauses; 229 | } 230 | -------------------------------------------------------------------------------- /sugar-calendar/includes/themes/legacy/ajax.php: -------------------------------------------------------------------------------- 1 | 'post', 49 | 'status' => 'publish', 50 | 'orderby' => 'start', 51 | 'order' => $order, 52 | 'number' => $number, 53 | 'start_query' => array( 54 | 'inclusive' => true, 55 | 'after' => $now 56 | ), 57 | 'end_query' => array( 58 | 'inclusive' => true, 59 | 'before' => $now 60 | ) 61 | ); 62 | 63 | // Upcoming 64 | } elseif ( 'upcoming' === $display ) { 65 | $args = array( 66 | 'object_type' => 'post', 67 | 'status' => 'publish', 68 | 'orderby' => 'start', 69 | 'order' => $order, 70 | 'number' => $number, 71 | 'end_query' => array( 72 | 'inclusive' => true, 73 | 'after' => $now 74 | ) 75 | ); 76 | 77 | // Past 78 | } elseif ( 'past' === $display ) { 79 | $args = array( 80 | 'object_type' => 'post', 81 | 'status' => 'publish', 82 | 'orderby' => 'start', 83 | 'order' => $order, 84 | 'number' => $number, 85 | 'end_query' => array( 86 | 'inclusive' => true, 87 | 'before' => $now 88 | ) 89 | ); 90 | 91 | // All events 92 | } else { 93 | $args = array( 94 | 'object_type' => 'post', 95 | 'status' => 'publish', 96 | 'orderby' => 'start', 97 | 'order' => $order, 98 | 'number' => $number 99 | ); 100 | } 101 | 102 | // Get the IDs 103 | $pt = sugar_calendar_get_event_post_type_id(); 104 | $tax = sugar_calendar_get_calendar_taxonomy_id(); 105 | 106 | // Maybe filter by taxonomy term 107 | if ( ! empty( $category ) ) { 108 | $args[ $tax ] = $category; 109 | } 110 | 111 | // Do not query for all found rows 112 | $r = array_merge( $args, array( 113 | 'no_found_rows' => true 114 | ) ); 115 | 116 | // Query for events 117 | $events = sugar_calendar_get_events( $r ); 118 | 119 | // Bail if no events 120 | if ( empty( $events ) ) { 121 | return ''; 122 | } 123 | 124 | // Start an output buffer to store these result 125 | ob_start(); 126 | 127 | do_action( 'sc_before_events_list' ); 128 | 129 | // Start an unordered list 130 | echo '
    '; 131 | 132 | // Loop through all events 133 | foreach ( $events as $event ) { 134 | 135 | // Get the object ID and use it for the event ID (for back compat) 136 | $event_id = $event->object_id; 137 | 138 | echo '
  • '; 139 | 140 | do_action( 'sc_before_event_list_item', $event_id ); 141 | 142 | echo ''; 143 | echo '' . get_the_title( $event_id ) . ''; 144 | 145 | if ( ! empty( $show['date'] ) ) { 146 | $date_tag = sugar_calendar_get_time_tag( array( 147 | 'time' => $event->start, 148 | 'timezone' => $event->start_tz, 149 | 'format' => sc_get_date_format(), 150 | 'dtformat' => 'Y-m-dO' 151 | ) ); 152 | 153 | echo '' . $date_tag . ''; 154 | } 155 | 156 | if ( ! empty( $show['time'] ) ) { 157 | $start_time = sc_get_event_start_time( $event_id ); 158 | $end_time = sc_get_event_end_time( $event_id ); 159 | $tf = sc_get_time_format(); 160 | 161 | // Output all day 162 | if ( $event->is_all_day() ) { 163 | echo '' . esc_html__( 'All-day', 'sugar-calendar' ) . ''; 164 | 165 | // Output both 166 | } elseif ( $end_time !== $start_time ) { 167 | 168 | $start_tag = sugar_calendar_get_time_tag( array( 169 | 'time' => $event->start, 170 | 'timezone' => $event->start_tz, 171 | 'format' => $tf 172 | ) ); 173 | 174 | $end_tag = sugar_calendar_get_time_tag( array( 175 | 'time' => $event->end, 176 | 'timezone' => $event->end_tz, 177 | 'format' => $tf 178 | ) ); 179 | 180 | echo '' . $start_tag . ' – ' . $end_tag . ''; 181 | 182 | // Output only start 183 | } elseif ( ! empty( $start_time ) ) { 184 | 185 | $start_tag = sugar_calendar_get_time_tag( array( 186 | 'time' => $event->start, 187 | 'timezone' => $event->start_tz, 188 | 'format' => $tf 189 | ) ); 190 | 191 | echo '' . $start_tag . ''; 192 | } 193 | } 194 | 195 | if ( ! empty( $show['categories'] ) ) { 196 | $event_categories = get_the_terms( $event_id, $tax ); 197 | 198 | if ( $event_categories ) { 199 | $categories = wp_list_pluck( $event_categories, 'name' ); 200 | echo '' . implode( ', ', $categories ) . ''; 201 | } 202 | } 203 | 204 | if ( ! empty( $show['link'] ) ) { 205 | echo ''; 206 | echo esc_html__( 'Read More', 'sugar-calendar' ); 207 | echo ''; 208 | } 209 | 210 | do_action( 'sc_after_event_list_item', $event_id ); 211 | 212 | echo '
  • '; 213 | } 214 | 215 | // Close the list 216 | echo '
'; 217 | 218 | // Reset post data - we'll be looping through our own 219 | wp_reset_postdata(); 220 | 221 | do_action( 'sc_after_events_list' ); 222 | 223 | // Return the current buffer and delete it 224 | return ob_get_clean(); 225 | } 226 | -------------------------------------------------------------------------------- /sugar-calendar/includes/themes/legacy/hooks.php: -------------------------------------------------------------------------------- 1 | post_content ) 86 | ? $post->post_content 87 | : ''; 88 | 89 | // Bail if content is empty 90 | if ( empty( $content ) ) { 91 | return false; 92 | } 93 | } 94 | 95 | // Get shortcode IDs 96 | $shortcode_ids = sc_get_shortcode_ids(); 97 | 98 | // Look for Sugar Calendar shortcodes 99 | if ( ! empty( $shortcode_ids ) ) { 100 | foreach ( $shortcode_ids as $id ) { 101 | if ( has_shortcode( $content, $id ) ) { 102 | return true; 103 | } 104 | } 105 | } 106 | 107 | // No shortcodes found 108 | return false; 109 | } 110 | 111 | /** 112 | * Peek into block content and check it for shortcode usage. 113 | * 114 | * @since 2.0.8 115 | * 116 | * @param string $content The block content 117 | * 118 | * @return string $content The block content 119 | */ 120 | function sc_enqueue_if_block_has_shortcodes( $content = '' ) { 121 | 122 | // Bail if content is empty 123 | if ( empty( $content ) ) { 124 | return $content; 125 | } 126 | 127 | // Check the block content for a shortcode 128 | if ( sc_content_has_shortcodes( $content ) ) { 129 | sc_enqueue_scripts(); 130 | sc_enqueue_styles(); 131 | } 132 | 133 | // Return the content, unchanged 134 | return $content; 135 | } 136 | 137 | /** 138 | * Enqueue scripts callback 139 | * 140 | * @since 1.0.0 141 | */ 142 | function sc_enqueue_scripts() { 143 | 144 | // Front-end AJAX 145 | wp_enqueue_script( 'sc-ajax' ); 146 | 147 | // Front-end Time Zones 148 | if ( get_option( 'sc_timezone_convert' ) ) { 149 | wp_enqueue_script( 'sc-time-zones' ); 150 | } 151 | 152 | // Front-end vars 153 | wp_localize_script( 'sc-ajax', 'sc_vars', array( 154 | 155 | // AJAX 156 | 'ajaxurl' => admin_url( 'admin-ajax.php' ), 157 | 158 | // Formatting values 159 | 'date_format' => sc_get_date_format(), 160 | 'time_format' => sc_get_time_format(), 161 | 'start_of_week' => sc_get_week_start_day(), 162 | 'timezone' => sc_get_timezone() 163 | ) ); 164 | } 165 | 166 | /** 167 | * Enqueue styles callback 168 | * 169 | * @since 1.0.0 170 | */ 171 | function sc_enqueue_styles() { 172 | 173 | // Front-end styling 174 | wp_enqueue_style( 'sc-events' ); 175 | } 176 | -------------------------------------------------------------------------------- /sugar-calendar/includes/themes/legacy/shortcodes.php: -------------------------------------------------------------------------------- 1 | 'large', 42 | 'category' => null, 43 | 'type' => 'month', 44 | 'month' => null, 45 | 'year' => null, 46 | 'sow' => null 47 | ), $atts ); 48 | 49 | // Defaults 50 | $size = isset( $atts['size'] ) ? $atts['size'] : 'large'; 51 | $category = isset( $atts['category'] ) ? $atts['category'] : null; 52 | $type = isset( $atts['type'] ) ? $atts['type'] : 'month'; 53 | $month = isset( $atts['month'] ) ? $atts['month'] : null; 54 | $year = isset( $atts['year'] ) ? $atts['year'] : null; 55 | $sow = isset( $atts['sow'] ) ? $atts['sow'] : null; 56 | 57 | // Get valid types 58 | $valid_types = sc_get_valid_calendar_types(); 59 | 60 | // Fallback to "month" if invalid 61 | if ( ! in_array( $type, $valid_types, true ) ) { 62 | $type = 'month'; 63 | } 64 | 65 | // Get the calendar HTML 66 | $calendar = sc_get_events_calendar( $size, $category, $type, $year, $month, $sow ); 67 | 68 | // Wrap it in a div (@todo remove ID) 69 | return '
' . $calendar . '
'; 70 | } 71 | 72 | /** 73 | * Event list shortcode callback 74 | * 75 | * @since 1.0.0 76 | * 77 | * @param $atts 78 | * @param null $content 79 | * 80 | * @return string 81 | */ 82 | function sc_events_list_shortcode( $atts = array(), $content = null ) { 83 | 84 | // Parse 85 | $atts = shortcode_atts( array( 86 | 'display' => 'upcoming', 87 | 'order' => '', 88 | 'number' => '5', 89 | 'category' => null, 90 | 'show_date' => null, 91 | 'show_time' => null, 92 | 'show_categories' => null, 93 | 'show_link' => null, 94 | ), $atts ); 95 | 96 | // Escape all values 97 | $display = esc_attr( $atts['display'] ); 98 | $order = esc_attr( $atts['order'] ); 99 | $category = esc_attr( $atts['category'] ); 100 | $number = esc_attr( $atts['number'] ); 101 | $show_date = esc_attr( $atts['show_date'] ); 102 | $show_time = esc_attr( $atts['show_time'] ); 103 | $show_categories = esc_attr( $atts['show_categories'] ); 104 | $show_link = esc_attr( $atts['show_link'] ); 105 | 106 | // Return arguments 107 | $args = array( 108 | 'date' => $show_date, 109 | 'time' => $show_time, 110 | 'categories' => $show_categories, 111 | 'link' => $show_link 112 | ); 113 | 114 | return sc_get_events_list( $display, $category, $number, $args, $order ); 115 | } 116 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Sugar Calendar Unit Tests [![Build status](https://badge.buildkite.com/80a91dff42e83fa09a0b68ed75b93c26920d619d46694d01c0.svg)](https://buildkite.com/sandhills-development-llc/sugar-calendar) 2 | 3 | 4 | This folder contains all the tests for Sugar Calendar. 5 | 6 | ## Running Tests 7 | ### How to run the tests locally 8 | The ideal way to run the unit tests locally is by using the included Docker Compose files for the stack and for PHPUnit. 9 | 10 | Requirements: 11 | - Docker (19.03.13 or newer) 12 | - Docker Compose (1.25.5 or newer) 13 | 14 | To run the tests, use the following command: 15 | ``` 16 | bin/run-tests-local.sh -p 7.4 -w latest 17 | ``` 18 | 19 | The flags `-p` and `-w` control the PHP and WordPress versions for the tests, respectively. 20 | 21 | This command sends the `phpunit` command to the `wordpress_phpunit` container. 22 | 23 | ## Writing Tests 24 | For more information on how to write PHPUnit Tests, see [PHPUnit's Website](http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html). 25 | -------------------------------------------------------------------------------- /tests/phpunit/bootstrap.php: -------------------------------------------------------------------------------- 1 | =' ) ) { 4 | require __DIR__ . '/phpunit7/speed-trap-listener.php'; 5 | } else { 6 | require __DIR__ . '/speed-trap-listener.php'; 7 | } 8 | -------------------------------------------------------------------------------- /tests/phpunit/testcases/legacy/tests-options.php: -------------------------------------------------------------------------------- 1 | assertSame( '17th June, 1979', $retval ); 43 | } 44 | 45 | /** 46 | * Time format 47 | * 48 | * @group options 49 | * @group time-format 50 | */ 51 | public function test_time_format() { 52 | 53 | // Set start-of-week to Wednesday 54 | update_option( 'sc_time_format', 'H:i' ); 55 | 56 | // Get the date format 57 | $format = sc_get_time_format(); 58 | 59 | $date = '1979-06-17 03:33:00'; 60 | $retval = gmdate( $format, strtotime( $date ) ); 61 | 62 | $this->assertSame( '03:33', $retval ); 63 | } 64 | 65 | /** 66 | * Start of week 67 | * 68 | * @group options 69 | * @group start-of-week 70 | */ 71 | public function test_start_of_week() { 72 | 73 | // Set start-of-week to Wednesday 74 | update_option( 'sc_start_of_week', 4 ); 75 | 76 | // Get the number 77 | $start = sc_get_week_start_day(); 78 | 79 | $date = '1979-06-21 03:33:00'; 80 | $retval = (int) gmdate( 'w', strtotime( $date ) ); 81 | 82 | $this->assertSame( $start, $retval ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/phpunit/testcases/legacy/tests-settings.php: -------------------------------------------------------------------------------- 1 | max; $x++ ) { 24 | 25 | // Post 26 | $post_ids[] = $post_id = (int) wp_insert_post( array( 27 | 'post_author' => 1, 28 | 'post_title' => 'A birthday', 29 | 'post_type' => $pt, 30 | 'post_status' => 'publish' 31 | ) ); 32 | 33 | // Event 34 | sugar_calendar_add_event( array( 35 | 'object_id' => $post_id, 36 | 'object_type' => 'post', 37 | 'object_subtype' => $pt, 38 | 'title' => 'A birthday', 39 | 'status' => 'publish', 40 | 'start' => '1979-06-' . $x . ' 03:33:00', 41 | 'end' => '1979-06-' . $x . ' 03:33:00', 42 | 'all_day' => true, 43 | 'recurrence' => 'yearly' 44 | ) ); 45 | } 46 | } 47 | 48 | /** 49 | * Tear down 50 | */ 51 | public function tearDown() { 52 | 53 | // Get all events 54 | $events = sugar_calendar_get_events( array( 55 | 'number' => 0 56 | ) ); 57 | 58 | // Loop through events and delete them all 59 | foreach ( $events as $event ) { 60 | sugar_calendar_delete_event( $event->id ); 61 | wp_delete_post( $event->object_id ); 62 | } 63 | 64 | // Delete the number-of-events option 65 | delete_option( 'sc_number_of_events' ); 66 | } 67 | 68 | /** 69 | * Five events 70 | * 71 | * @group settings 72 | * @group slow 73 | * @group get-events 74 | */ 75 | public function test_number_of_events_5() { 76 | 77 | // Set number to 5 78 | update_option( 'sc_number_of_events', 5 ); 79 | 80 | // Get the number 81 | $number = sc_get_number_of_events(); 82 | 83 | // Get all events before today by the term 84 | $events = sugar_calendar_get_events( array( 85 | 'no_found_rows' => true, 86 | 'number' => $number, 87 | 'object_type' => 'post', 88 | 'object_subtype' => sugar_calendar_get_event_post_type_id(), 89 | 'status' => 'publish', 90 | 'orderby' => 'start', 91 | 'order' => 'ASC', 92 | 'start_query' => array( 93 | 'before' => '1979-07-01', 94 | 'inclusive' => true, 95 | ) 96 | ) ); 97 | 98 | $this->assertSame( count( $events ), $number ); 99 | } 100 | 101 | /** 102 | * Ten events 103 | * 104 | * @group settings 105 | * @group slow 106 | * @group get-events 107 | */ 108 | public function test_number_of_events_10() { 109 | 110 | // Set number to 5 111 | update_option( 'sc_number_of_events', 10 ); 112 | 113 | // Get the number 114 | $number = sc_get_number_of_events(); 115 | 116 | // Get all events before today by the term 117 | $events = sugar_calendar_get_events( array( 118 | 'no_found_rows' => true, 119 | 'number' => $number, 120 | 'object_type' => 'post', 121 | 'object_subtype' => sugar_calendar_get_event_post_type_id(), 122 | 'status' => 'publish', 123 | 'orderby' => 'start', 124 | 'order' => 'ASC', 125 | 'start_query' => array( 126 | 'before' => '1979-07-01', 127 | 'inclusive' => true, 128 | ) 129 | ) ); 130 | 131 | $this->assertSame( count( $events ), $number ); 132 | } 133 | 134 | /** 135 | * All events 136 | * 137 | * @group settings 138 | * @group slow 139 | * @group get-events 140 | */ 141 | public function test_number_of_events_0() { 142 | 143 | // Set number to 0 144 | update_option( 'sc_number_of_events', 0 ); 145 | 146 | // Get the number 147 | $number = sc_get_number_of_events(); 148 | 149 | // Get all events before today by the term 150 | $events = sugar_calendar_get_events( array( 151 | 'no_found_rows' => true, 152 | 'number' => $number, 153 | 'object_type' => 'post', 154 | 'object_subtype' => sugar_calendar_get_event_post_type_id(), 155 | 'status' => 'publish', 156 | 'orderby' => 'start', 157 | 'order' => 'ASC', 158 | 'start_query' => array( 159 | 'before' => '1979-07-01', 160 | 'inclusive' => true, 161 | ) 162 | ) ); 163 | 164 | $this->assertSame( count( $events ), $this->max ); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /tests/phpunit/testcases/post/tests-taxonomy.php: -------------------------------------------------------------------------------- 1 | pt = sugar_calendar_get_event_post_type_id(); 25 | $this->tax = sugar_calendar_get_calendar_taxonomy_id(); 26 | 27 | // Post 28 | $this->post_id = (int) wp_insert_post( array( 29 | 'post_author' => 1, 30 | 'post_title' => 'A birthday', 31 | 'post_type' => $this->pt, 32 | 'post_status' => 'publish' 33 | ) ); 34 | 35 | // Event 36 | $this->event_id = (int) sugar_calendar_add_event( array( 37 | 'object_id' => $this->post_id, 38 | 'object_type' => 'post', 39 | 'object_subtype' => $this->pt, 40 | 'title' => 'A birthday', 41 | 'status' => 'publish', 42 | 'start' => '1979-06-17 03:33:00', 43 | 'end' => '1979-06-17 03:33:00', 44 | 'all_day' => true, 45 | 'recurrence' => 'yearly' 46 | ) ); 47 | 48 | // Create the term 49 | $term = wp_insert_term( 'birthday', $this->tax ); 50 | 51 | // Set TermID 52 | $this->term_id = (int) $term['term_id']; 53 | 54 | // Add post ID to term 55 | wp_set_object_terms( $this->post_id, $this->term_id, $this->tax ); 56 | } 57 | 58 | /** 59 | * Tear down 60 | */ 61 | public function tearDown() { 62 | sugar_calendar_delete_event( $this->event_id ); 63 | wp_delete_object_term_relationships( $this->post_id, $this->tax ); 64 | wp_delete_post( $this->post_id ); 65 | wp_delete_term( 'birthday', $this->tax ); 66 | } 67 | 68 | /** 69 | * @group get-events 70 | */ 71 | public function test_get_past_events_in_calendar() { 72 | 73 | // Get the term 74 | $term = get_term( $this->term_id, $this->tax ); 75 | 76 | // Get all events before today by the term 77 | $events = sugar_calendar_get_events( array( 78 | 'object_id' => $this->post_id, 79 | 'object_type' => 'post', 80 | 'object_subtype' => $this->pt, 81 | 'status' => 'publish', 82 | 'orderby' => 'start', 83 | 'order' => 'ASC', 84 | 'start_query' => array( 85 | 'before' => date( 'Y-m-d' ), 86 | 'inclusive' => true, 87 | ), 88 | $this->tax => $term->slug 89 | ) ); 90 | 91 | // Get the first event ID 92 | $event_id = (int) $events[0]->id; 93 | 94 | $this->assertSame( $this->event_id, $event_id ); 95 | } 96 | } 97 | --------------------------------------------------------------------------------