├── .gitignore
├── .travis.yml
├── LICENSE
├── bin
├── dev
├── release
├── splitsh-lite
├── subtree-split
└── test
├── composer.json
├── docker-compose.yml
├── docker
├── Dockerfile
├── cli.ini
├── entrypoiny.sh
└── xdebug.ini
├── phpunit.xml.dist
└── pkg
├── app
├── .env.dist
├── .gitignore
├── .travis.yml
├── LICENSE
├── Makefile
├── bin
│ └── console
├── composer.json
├── docker-compose.yml
├── etc
│ ├── bundles.php
│ ├── container.yaml
│ └── packages
│ │ ├── app.yaml
│ │ ├── enqueue.yaml
│ │ ├── framework.yaml
│ │ ├── quartz.yaml
│ │ └── test
│ │ └── framework.yaml
├── phpunit.xml.dist
└── src
│ └── Kernel.php
├── bridge
├── .travis.yml
├── DI
│ ├── QuartzConfiguration.php
│ ├── QuartzExtension.php
│ ├── QuartzJobCompilerPass.php
│ └── RemoteSchedulerExtension.php
├── Enqueue
│ ├── EnqueueRemoteTransport.php
│ ├── EnqueueRemoteTransportProcessor.php
│ └── EnqueueResponseJob.php
├── LICENSE
├── LoggerSubscriber.php
├── Scheduler
│ ├── EnqueueJobRunShell.php
│ ├── JobRunShellProcessor.php
│ ├── RemoteScheduler.php
│ ├── RemoteTransport.php
│ ├── RpcProtocol.php
│ └── SchedulerFactory.php
├── SignalSubscriber.php
├── Swoole
│ └── CheckMasterProcessSubscriber.php
├── Tests
│ ├── DI
│ │ └── QuartzConfigurationTest.php
│ ├── Enqueue
│ │ ├── EnqueueRemoteTransportProcessorTest.php
│ │ ├── EnqueueRemoteTransportTest.php
│ │ └── EnqueueResponseJobTest.php
│ ├── Scheduler
│ │ ├── JobRunShellProcessorTest.php
│ │ ├── RemoteSchedulerTest.php
│ │ └── RpcProtocolTest.php
│ ├── Swoole
│ │ └── CheckMasterProcessSubscriberTest.php
│ └── Yadm
│ │ └── YadmStoreTest.php
├── Yadm
│ ├── BundleStoreResource.php
│ ├── CalendarStorage.php
│ ├── FiredTriggerStorage.php
│ ├── JobStorage.php
│ ├── ModelHydrator.php
│ ├── PausedTriggerStorage.php
│ ├── SimpleStoreResource.php
│ ├── StoreResource.php
│ ├── TriggerStorage.php
│ └── YadmStore.php
├── composer.json
└── phpunit.xml.dist
├── bundle
├── .gitignore
├── .travis.yml
├── Command
│ ├── ManagementCommand.php
│ └── SchedulerCommand.php
├── DependencyInjection
│ ├── Configuration.php
│ └── QuartzExtension.php
├── LICENSE
├── QuartzBundle.php
├── Tests
│ ├── Command
│ │ ├── ManagementCommandTest.php
│ │ └── SchedulerCommandTest.php
│ ├── DependencyInjection
│ │ ├── ConfigurationTest.php
│ │ └── QuartzExtensionTest.php
│ ├── Functional
│ │ ├── App
│ │ │ ├── AppKernel.php
│ │ │ ├── config
│ │ │ │ ├── config.yml
│ │ │ │ └── routing.yml
│ │ │ └── console.php
│ │ ├── ManagementCommandTest.php
│ │ ├── RemoteSchedulerTest.php
│ │ ├── SchedulerCommandTest.php
│ │ ├── SchedulerTest.php
│ │ └── WebTestCase.php
│ └── QuartzBundleTest.php
├── composer.json
└── phpunit.xml.dist
└── quartz
├── .gitignore
├── Calendar
├── BaseCalendar.php
├── CronCalendar.php
├── DailyCalendar.php
├── HolidayCalendar.php
├── MonthlyCalendar.php
└── WeeklyCalendar.php
├── Core
├── Calendar.php
├── CalendarIntervalScheduleBuilder.php
├── CompletedExecutionInstruction.php
├── CronScheduleBuilder.php
├── DailyTimeIntervalScheduleBuilder.php
├── DateBuilder.php
├── IntervalUnit.php
├── Job.php
├── JobBuilder.php
├── JobDetail.php
├── JobExecutionContext.php
├── JobFactory.php
├── JobPersistenceException.php
├── Key.php
├── Model.php
├── ObjectAlreadyExistsException.php
├── ScheduleBuilder.php
├── Scheduler.php
├── SchedulerException.php
├── SchedulerFactory.php
├── SimpleJobFactory.php
├── SimpleScheduleBuilder.php
├── Trigger.php
└── TriggerBuilder.php
├── Events
├── ErrorEvent.php
├── Event.php
├── GroupsEvent.php
├── JobDetailEvent.php
├── JobExecutionContextEvent.php
├── KeyEvent.php
├── TickEvent.php
└── TriggerEvent.php
├── JobDetail
└── JobDetail.php
├── LICENSE
├── ModelClassFactory.php
├── Scheduler
├── JobRunShell.php
├── JobRunShellFactory.php
├── JobStore.php
├── StdJobRunShell.php
├── StdJobRunShellFactory.php
└── StdScheduler.php
├── Tests
├── Calendar
│ ├── BaseCalendarTest.php
│ ├── CronCalendarTest.php
│ ├── DailyCalendarTest.php
│ ├── HolidayCalendarTest.php
│ ├── MonthlyCalendarTest.php
│ └── WeeklyCalendarTest.php
├── Core
│ ├── DateBuilderTest.php
│ ├── JobExecutionContextTest.php
│ ├── KeyTest.php
│ └── SimpleJobFactoryTest.php
├── JobDetail
│ └── JobDetailTest.php
└── Triggers
│ ├── AbstractTriggerTest.php
│ └── SimpleTriggerTest.php
├── Triggers
├── AbstractTrigger.php
├── CalendarIntervalTrigger.php
├── CronTrigger.php
├── DailyTimeIntervalTrigger.php
└── SimpleTrigger.php
├── composer.json
├── examples
├── calendar-interval-trigger.php
├── cron-trigger.php
├── daily-interval-trigger.php
├── scheduler.php
└── simple-trigger.php
└── phpunit.xml.dist
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | vendor
3 | composer.lock
4 | bin/phpunit
5 | bin/console
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | git:
2 | depth: 10
3 |
4 | language: php
5 |
6 | env:
7 | DOCKER_VERSION: '17.05.0~ce-0~ubuntu-trusty'
8 | DOCKER_COMPOSE_VERSION: '1.13.0'
9 |
10 | matrix:
11 | include:
12 | - php: 7.2
13 | sudo: required
14 | services: docker
15 |
16 | cache:
17 | directories:
18 | - $HOME/.composer/cache
19 |
20 | install:
21 | - sudo apt-get update
22 | # list docker-engine versions
23 | - apt-cache madison docker-ce
24 | # upgrade docker-engine to specific version
25 | - sudo apt-get -o Dpkg::Options::="--force-confnew" install -y docker-ce=${DOCKER_VERSION}
26 |
27 | # reinstall docker-compose at specific version
28 | - sudo rm -f /usr/local/bin/docker-compose
29 | - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
30 | - chmod +x docker-compose
31 | - sudo mv docker-compose /usr/local/bin
32 |
33 | - docker --version
34 | - docker-compose --version
35 |
36 | - rm $HOME/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini;
37 | - echo "memory_limit=2048M" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
38 | - composer install --ignore-platform-reqs
39 | - bin/dev -b
40 |
41 | script:
42 | - bin/dev -t
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2017 Forma-Pro
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is furnished
9 | to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/bin/dev:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -x
4 | set -e
5 |
6 | while getopts "busdtef" OPTION; do
7 | case $OPTION in
8 | b)
9 | COMPOSE_PROJECT_NAME=quartz docker-compose build
10 | ;;
11 | u)
12 | COMPOSE_PROJECT_NAME=quartz docker-compose up
13 | ;;
14 | s)
15 | COMPOSE_PROJECT_NAME=quartz docker-compose stop
16 | ;;
17 | d)
18 | COMPOSE_PROJECT_NAME=quartz docker-compose down
19 | ;;
20 | e)
21 | docker exec -it quartz_app_1 /bin/bash
22 | ;;
23 | f)
24 | ./bin/php-cs-fixer fix
25 | ;;
26 | t)
27 | COMPOSE_PROJECT_NAME=quartz docker-compose run --workdir="/app" --rm app ./bin/test "$2"
28 | ;;
29 | c)
30 | COMPOSE_PROJECT_NAME=quartz docker-compose run -e CHANGELOG_GITHUB_TOKEN=${CHANGELOG_GITHUB_TOKEN:-""} --workdir="/app" --rm generate-changelog github_changelog_generator --future-release "$2" --simple-list
31 | ;;
32 | \?)
33 | echo "Invalid option: -$OPTARG" >&2
34 | exit 1
35 | ;;
36 | :)
37 | echo "Option -$OPTARG requires an argument." >&2
38 | exit 1
39 | ;;
40 | esac
41 | done
42 |
--------------------------------------------------------------------------------
/bin/release:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | if (( "$#" != 1 ))
6 | then
7 | echo "Tag has to be provided"
8 | exit 1
9 | fi
10 |
11 | ./bin/dev -c $1 && git add CHANGELOG.md && git commit -m "Release $1" -S && git push origin master
12 |
13 | ./bin/subtree-split
14 |
15 | CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
16 |
17 | for REMOTE in origin quartz bridge bundle app
18 | do
19 | echo ""
20 | echo ""
21 | echo "Releasing $REMOTE";
22 |
23 | TMP_DIR="/tmp/quartz-repo"
24 | REMOTE_URL=`git remote get-url $REMOTE`
25 |
26 | rm -rf $TMP_DIR;
27 | mkdir $TMP_DIR;
28 |
29 | (
30 | cd $TMP_DIR;
31 | git clone $REMOTE_URL . --depth=200
32 | git checkout $CURRENT_BRANCH;
33 | # gsort comes with coreutils packages. brew install coreutils
34 | LAST_RELEASE=$(git tag -l [0-9].* | gsort -V | tail -n1 )
35 |
36 | echo "Last release $LAST_RELEASE";
37 |
38 | CHANGES_SINCE_LAST_RELEASE=$(git log "$LAST_RELEASE"...master)
39 | CHANGES_SINCE_LAST_RELEASE="$CHANGES_SINCE_LAST_RELEASE" | xargs echo -n
40 | if [[ ! -z "$CHANGES_SINCE_LAST_RELEASE" ]]; then
41 | echo "There are changes since last release. Releasing $1";
42 |
43 | git tag $1 -s -m "Release $1"
44 | git push origin --tags
45 | else
46 | echo "No change since last release.";
47 | fi
48 | )
49 | done
50 |
--------------------------------------------------------------------------------
/bin/splitsh-lite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-quartz/quartz-dev/95824343fec03a867d52275d0894d7e8b1b62af3/bin/splitsh-lite
--------------------------------------------------------------------------------
/bin/subtree-split:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -x
5 |
6 | CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
7 |
8 | function split()
9 | {
10 | # split_new_repo $1 $2
11 |
12 |
13 | SHA1=`./bin/splitsh-lite --prefix=$1`
14 | git push $2 "$SHA1:$CURRENT_BRANCH"
15 | }
16 |
17 | function split_new_repo()
18 | {
19 | TMP_DIR="/tmp/quartz-repo"
20 | REMOTE_URL=`git remote get-url $2`
21 |
22 | rm -rf $TMP_DIR;
23 | mkdir $TMP_DIR;
24 |
25 | (
26 | cd $TMP_DIR;
27 | git clone $REMOTE_URL .;
28 | git checkout -b master;
29 | touch foo;
30 | git add foo;
31 | git commit -m "foo";
32 | git push origin master;
33 | );
34 |
35 | SHA1=`./bin/splitsh-lite --prefix=$1`
36 | git fetch $2
37 | git push $2 "$SHA1:$CURRENT_BRANCH" -f
38 | }
39 |
40 |
41 | function remote()
42 | {
43 | git remote add $1 $2 || true
44 | }
45 |
46 | remote quartz git@github.com:php-quartz/quartz.git
47 | remote bridge git@github.com:php-quartz/bridge.git
48 | remote bundle git@github.com:php-quartz/bundle.git
49 | remote app git@github.com:php-quartz/app.git
50 |
51 | split 'pkg/quartz' quartz
52 | split 'pkg/bridge' bridge
53 | split 'pkg/bundle' bundle
54 | split 'pkg/app' app
55 |
--------------------------------------------------------------------------------
/bin/test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | FORCE_EXIT=false
4 |
5 | function waitForService()
6 | {
7 | ATTEMPTS=0
8 | until nc -z $1 $2; do
9 | printf "wait for service %s:%s\n" $1 $2
10 | ((ATTEMPTS++))
11 | if [ $ATTEMPTS -ge $3 ]; then
12 | printf "service is not running %s:%s\n" $1 $2
13 | exit 1
14 | fi
15 | if [ "$FORCE_EXIT" = true ]; then
16 | exit;
17 | fi
18 |
19 | sleep 1
20 | done
21 |
22 | printf "service is online %s:%s\n" $1 $2
23 | }
24 |
25 | trap "FORCE_EXIT=true" SIGTERM SIGINT
26 |
27 | waitForService mongo 27017 50
28 |
29 | bin/phpunit "$@"
30 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "php-quartz/quartz-dev",
3 | "type": "project",
4 | "minimum-stability": "dev",
5 | "description": "PHP Job Time Scheduler Project",
6 | "keywords": ["job", "time", "task", "time scheduler", "quartz", "chrono"],
7 | "license": "MIT",
8 | "config": {
9 | "bin-dir": "bin",
10 | "platform": {
11 | "php": "7.2",
12 | "ext-mongodb": "1.4"
13 | },
14 | "preferred-install": {
15 | "*": "dist"
16 | },
17 | "sort-packages": true
18 | },
19 | "require": {
20 | "php": "^7.2",
21 | "php-quartz/quartz": "*@dev",
22 | "php-quartz/bridge": "*@dev",
23 | "php-quartz/bundle": "*@dev",
24 | "php-quartz/app": "*@dev",
25 | "symfony/dotenv": "^3.3|^4",
26 | "phpunit/phpunit": "^5.5",
27 | "symfony/browser-kit": "^3.4|^4"
28 | },
29 | "repositories": [
30 | {
31 | "type": "path",
32 | "url": "pkg/quartz"
33 | },
34 | {
35 | "type": "path",
36 | "url": "pkg/bridge"
37 | },
38 | {
39 | "type": "path",
40 | "url": "pkg/bundle"
41 | },
42 | {
43 | "type": "path",
44 | "url": "pkg/app"
45 | }
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | app:
4 | build: { context: docker, dockerfile: Dockerfile }
5 | working_dir: '/app'
6 | restart: 'no'
7 | depends_on:
8 | - 'mongo'
9 | volumes:
10 | - './:/app:cached'
11 | # - './docker/xdebug.ini:/etc/php/7.0/mods-available/xdebug.ini'
12 | environment:
13 | PHP_IDE_CONFIG: 'serverName=quartz.dev'
14 | XDEBUG_CONFIG: 'idekey=PHPSTORM'
15 | MONGODB_HOST: 'mongo'
16 | MONGODB_PORT: '27017'
17 | MONGODB_DB: 'quartz'
18 |
19 | mongo:
20 | image: 'mongo:3'
21 | restart: 'on-failure'
22 | ports:
23 | - '27017:27017'
24 |
25 | generate-changelog:
26 | image: enqueue/generate-changelog:latest
27 | volumes:
28 | - './:/app:cached'
29 |
--------------------------------------------------------------------------------
/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM formapro/nginx-php-fpm:7.3-latest-all-exts
2 |
3 | COPY ./cli.ini /etc/php/7.3/cli/conf.d/1-dev_cli.ini
4 | COPY ./entrypoiny.sh /usr/local/bin/entrypoint.sh
5 | RUN chmod u+x /usr/local/bin/entrypoint.sh
6 | RUN apt-get update && apt-get -y --no-install-recommends --no-install-suggests install netcat
7 |
8 | RUN mkdir -p /app
9 | WORKDIR /app
10 |
11 | CMD /usr/local/bin/entrypoint.sh
12 |
--------------------------------------------------------------------------------
/docker/cli.ini:
--------------------------------------------------------------------------------
1 | error_reporting=E_ALL
2 | display_errors=on
3 | memory_limit = 2G
4 | max_execution_time=0
5 | date.timezone=UTC
6 | variables_order="EGPCS"
7 |
--------------------------------------------------------------------------------
/docker/entrypoiny.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | while true; do sleep 1; done
4 |
--------------------------------------------------------------------------------
/docker/xdebug.ini:
--------------------------------------------------------------------------------
1 | zend_extension=xdebug.so
2 | xdebug.profiler_enable = Off
3 | xdebug.profiler_enable_trigger = Off
4 | xdebug.max_nesting_level = 5000
5 | xdebug.remote_enable = On
6 | xdebug.remote_host = 172.10.0.1
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 | Calendar
will be
99 | * resolved.
100 | *
101 | * @return \DateTimeZone This Calendar's timezone, null
if Calendar should use the default
102 | */
103 | public function getTimeZone()
104 | {
105 | if ($timezone = $this->getValue('timezone')) {
106 | return new \DateTimeZone($timezone);
107 | }
108 | }
109 |
110 | /**
111 | * Sets the time zone for which this Calendar
will be resolved.
112 | *
113 | * @param \DateTimeZone $timeZone The time zone to use for this Calendar, null if default should be used
114 | */
115 | public function setTimeZone(\DateTimeZone $timeZone = null)
116 | {
117 | if ($timeZone) {
118 | $value = $timeZone->getName();
119 | } else {
120 | $value = null;
121 | }
122 |
123 | $this->setValue('timezone', $value);
124 | }
125 |
126 | /**
127 | * @param int $timeStamp
128 | *
129 | * @return \DateTime
130 | */
131 | protected function createDateTime($timeStamp)
132 | {
133 | $date = \DateTime::createFromFormat('U', $timeStamp);
134 |
135 | if ($tz = $this->getTimeZone()) {
136 | $date->setTimezone($tz);
137 | }
138 |
139 | return $date;
140 | }
141 |
142 | /**
143 | * @param int $timeStamp
144 | *
145 | * @return \DateTime
146 | */
147 | protected function getStartOfDayDateTime($timeStamp)
148 | {
149 | $date = $this->createDateTime($timeStamp);
150 | $date->setTime(0, 0, 0);
151 |
152 | return $date;
153 | }
154 |
155 | /**
156 | * @param int $timeStamp
157 | *
158 | * @return \DateTime
159 | */
160 | protected function getEndOfDayDateTime($timeStamp)
161 | {
162 | $date = $this->createDateTime($timeStamp);
163 | $date->setTime(23, 59, 59);
164 |
165 | return $date;
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/pkg/quartz/Calendar/HolidayCalendar.php:
--------------------------------------------------------------------------------
1 |
8 | * This implementation of the Calendar stores a list of holidays (full days
9 | * that are excluded from scheduling).
10 | *
13 | * The implementation DOES take the year into consideration, so if you want to 14 | * exclude July 4th for the next 10 years, you need to add 10 entries to the 15 | * exclude list. 16 | *
17 | */ 18 | class HolidayCalendar extends BaseCalendar 19 | { 20 | const INSTANCE = 'holiday'; 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function __construct(Calendar $baseCalendar = null, \DateTimeZone $timeZone = null) 26 | { 27 | parent::__construct(self::INSTANCE, $baseCalendar, $timeZone); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function isTimeIncluded($timeStamp) 34 | { 35 | if (parent::isTimeIncluded($timeStamp) == false) { 36 | return false; 37 | } 38 | 39 | $lookFor = $this->getStartOfDayDateTime($timeStamp); 40 | 41 | $dates = $this->getValue('excludedDates'); 42 | 43 | return false == isset($dates[$lookFor->format('U')]); 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function getNextIncludedTime($timeStamp) 50 | { 51 | // Call base calendar implementation first 52 | $baseTime = parent::getNextIncludedTime($timeStamp); 53 | if ($baseTime > 0 && $baseTime > $timeStamp) { 54 | $timeStamp = $baseTime; 55 | } 56 | 57 | // Get timestamp for 00:00:00 58 | $day = $this->getStartOfDayDateTime($timeStamp); 59 | 60 | while (false == $this->isTimeIncluded((int) $day->format('U'))) { 61 | $day->add(new \DateInterval('P1D')); 62 | } 63 | 64 | return (int) $day->format('U'); 65 | } 66 | 67 | /** 68 | *69 | * Add the given Date to the list of excluded days. Only the month, day and 70 | * year of the returned dates are significant. 71 | *
72 | * 73 | * @param \DateTime $excludedDate 74 | */ 75 | public function addExcludedDate(\DateTime $excludedDate) 76 | { 77 | $date = $this->getStartOfDayDateTime($excludedDate->format('U')); 78 | 79 | $dates = $this->getValue('excludedDates'); 80 | $dates[$date->format('U')] = true; 81 | 82 | $this->setValue('excludedDates', $dates); 83 | } 84 | 85 | /** 86 | * @param \DateTime $dateToRemove 87 | */ 88 | public function removeExcludedDate(\DateTime $dateToRemove) 89 | { 90 | $date = $this->getStartOfDayDateTime($dateToRemove->format('U')); 91 | 92 | $dates = $this->getValue('excludedDates'); 93 | unset($dates[$date->format('U')]); 94 | 95 | $this->setValue('excludedDates', $dates); 96 | } 97 | 98 | /** 99 | *100 | * Returns a list of Dates representing the excluded 101 | * days. Only the month, day and year of the returned dates are 102 | * significant. 103 | *
104 | */ 105 | public function getExcludedDates() 106 | { 107 | $dates = []; 108 | foreach ($this->getValue('excludedDates') as $date => $v) { 109 | $d = \DateTime::createFromFormat('U', $date); 110 | 111 | if ($tz = $this->getTimeZone()) { 112 | $d->setTimezone($tz); 113 | } 114 | 115 | $dates[] = $d; 116 | } 117 | 118 | return $dates; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /pkg/quartz/Calendar/MonthlyCalendar.php: -------------------------------------------------------------------------------- 1 | 9 | * This implementation of the Calendar excludes a set of days of the month. You 10 | * may use it to exclude every first day of each month for example. But you may define 11 | * any day of a month. 12 | * 13 | */ 14 | class MonthlyCalendar extends BaseCalendar 15 | { 16 | const INSTANCE = 'monthly'; 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function __construct(Calendar $baseCalendar = null, \DateTimeZone $timeZone = null) 22 | { 23 | parent::__construct(self::INSTANCE, $baseCalendar, $timeZone); 24 | } 25 | 26 | /** 27 | *28 | * Get the array which defines the exclude-value of each day of month. 29 | * Only the first 31 elements of the array are relevant, with the 1 index 30 | * element representing the first day of the month. 31 | *
32 | */ 33 | public function getDaysExcluded() 34 | { 35 | return $this->getValue('excludeDays', []); 36 | } 37 | 38 | /** 39 | *40 | * Return true, if day is defined to be excluded. 41 | *
42 | * 43 | * @param int $day The day of the month (from 1 to 31) to check. 44 | * 45 | * @return bool 46 | */ 47 | public function isDayExcluded($day) 48 | { 49 | DateBuilder::validateDayOfMonth($day); 50 | 51 | $days = $this->getValue('excludeDays', []); 52 | 53 | return in_array($day, $days, true); 54 | } 55 | 56 | /** 57 | *58 | * Redefine the array of days excluded. The array must non-null and of size 59 | * greater or equal to 31. The 1 index element represents the first day of 60 | * the month. 61 | *
62 | * 63 | * @param array $days 64 | */ 65 | public function setDaysExcluded(array $days) 66 | { 67 | foreach ($days as $day) { 68 | DateBuilder::validateDayOfMonth($day); 69 | } 70 | 71 | $this->setValue('excludeDays', $days); 72 | } 73 | 74 | /** 75 | *76 | * Redefine a certain day of the month to be excluded (true) or included 77 | * (false). 78 | *
79 | * 80 | * @param int $day The day of the month (from 1 to 31) to set. 81 | * @param bool $exclude 82 | */ 83 | public function setDayExcluded($day, $exclude) 84 | { 85 | DateBuilder::validateDayOfMonth($day); 86 | 87 | $days = $this->getValue('excludeDays', []); 88 | 89 | if ($exclude) { 90 | if (false === array_search($day, $days, true)) { 91 | $days[] = $day; 92 | sort($days, SORT_NUMERIC); 93 | } 94 | } else { 95 | if (false !== $index = array_search($day, $days, true)) { 96 | unset($days[$index]); 97 | $days = array_values($days); 98 | } 99 | } 100 | 101 | $this->setValue('excludeDays', $days); 102 | } 103 | 104 | /** 105 | *106 | * Determine whether the given time (in milliseconds) is 'included' by the 107 | * Calendar. 108 | *
109 | * 110 | *111 | * Note that this Calendar is only has full-day precision. 112 | *
113 | * 114 | * @param $timeStamp 115 | * 116 | * @return bool 117 | */ 118 | public function isTimeIncluded($timeStamp) 119 | { 120 | // Test the base calendar first. Only if the base calendar not already 121 | // excludes the time/date, continue evaluating this calendar instance. 122 | if (false == parent::isTimeIncluded($timeStamp)) { 123 | return false; 124 | } 125 | 126 | $date = $this->createDateTime($timeStamp); 127 | $day = (int) $date->format('j'); 128 | 129 | return false == $this->isDayExcluded($day); 130 | } 131 | 132 | /** 133 | *134 | * Check if all days are excluded. That is no day is included. 135 | *
136 | */ 137 | public function areAllDaysExcluded() 138 | { 139 | return count($this->getValue('excludeDays', [])) >= 31; 140 | } 141 | 142 | /** 143 | *144 | * Determine the next time (in milliseconds) that is 'included' by the 145 | * Calendar after the given time. Return the original value if timeStamp is 146 | * included. Return 0 if all days are excluded. 147 | *
148 | * 149 | *150 | * Note that this Calendar is only has full-day precision. 151 | *
152 | * 153 | * @param int $timeStamp 154 | * 155 | * @return int 156 | */ 157 | public function getNextIncludedTime($timeStamp) 158 | { 159 | if ($this->areAllDaysExcluded()) { 160 | return 0; 161 | } 162 | 163 | $baseTime = parent::getNextIncludedTime($timeStamp); 164 | if ($baseTime > 0 && $baseTime > $timeStamp) { 165 | $timeStamp = $baseTime; 166 | } 167 | 168 | // Get timestamp for 00:00:00 169 | $date = $this->getStartOfDayDateTime($timeStamp); 170 | $day = (int) $date->format('j'); 171 | 172 | if (false == $this->isDayExcluded($day)) { 173 | return $timeStamp; // return the original value 174 | } 175 | 176 | while ($this->isDayExcluded($day)) { 177 | $date->add(new \DateInterval('P1D')); 178 | $day = (int) $date->format('j'); 179 | } 180 | 181 | return (int) $date->format('U'); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /pkg/quartz/Core/Calendar.php: -------------------------------------------------------------------------------- 1 | 8 | * Set a new base calendar or remove the existing one. 9 | * 10 | * 11 | * @param Calendar $baseCalendar 12 | */ 13 | public function setBaseCalendar(Calendar $baseCalendar); 14 | 15 | /** 16 | *17 | * Get the base calendar. Will be null, if not set. 18 | *
19 | * 20 | * @return Calendar 21 | */ 22 | public function getBaseCalendar(); 23 | 24 | /** 25 | *26 | * Determine whether the given time (in milliseconds) is 'included' by the 27 | * Calendar. 28 | *
29 | * 30 | * @param int $timeStamp 31 | * 32 | * @return bool 33 | */ 34 | public function isTimeIncluded($timeStamp); 35 | 36 | /** 37 | *38 | * Determine the next time (in milliseconds) that is 'included' by the 39 | * Calendar after the given time. 40 | *
41 | * 42 | * @param int $timeStamp 43 | * 44 | * @return int timestamp 45 | */ 46 | public function getNextIncludedTime($timeStamp); 47 | 48 | /** 49 | *
50 | * Return the description given to the Calendar
instance by
51 | * its creator (if any).
52 | *
60 | * Set a description for the Calendar
instance - may be
61 | * useful for remembering/displaying the purpose of the calendar, though
62 | * the description has no meaning to Quartz.
63 | *
java.util.Date
instances that meet particular criteria.
7 | *
8 | * Quartz provides a builder-style API for constructing scheduling-related
9 | * entities via a Domain-Specific Language (DSL). The DSL can best be
10 | * utilized through the usage of static imports of the methods on the classes
11 | * TriggerBuilder
, JobBuilder
,
12 | * DateBuilder
, JobKey
, TriggerKey
13 | * and the various ScheduleBuilder
implementations.
Client code can then use the DSL to write code such as this:
16 | *17 | * JobDetail job = newJob(MyJob.class) 18 | * .withIdentity("myJob") 19 | * .build(); 20 | * 21 | * Trigger trigger = newTrigger() 22 | * .withIdentity(triggerKey("myTrigger", "myTriggerGroup")) 23 | * .withSchedule(simpleSchedule() 24 | * .withIntervalInHours(1) 25 | * .repeatForever()) 26 | * .startAt(futureDate(10, MINUTES)) 27 | * .build(); 28 | * 29 | * scheduler.scheduleJob(job, trigger); 30 | *31 | */ 32 | class DateBuilder 33 | { 34 | // ISO-8601 35 | const MONDAY = 1; 36 | const TUESDAY = 2; 37 | const WEDNESDAY = 3; 38 | const THURSDAY = 4; 39 | const FRIDAY = 5; 40 | const SATURDAY = 6; 41 | const SUNDAY = 7; 42 | 43 | public static function MAX_YEAR() 44 | { 45 | static $maxYear; 46 | 47 | if (null == $maxYear) { 48 | $maxYear = ((int) date('Y')) + 100; 49 | } 50 | 51 | return $maxYear; 52 | } 53 | 54 | //////////////////////////////////////////////////////////////////////////////////////////////////// 55 | 56 | public static function validateDayOfWeek($dayOfWeek) 57 | { 58 | if ($dayOfWeek < self::MONDAY || $dayOfWeek > self::SUNDAY) { 59 | throw new \InvalidArgumentException(sprintf('Invalid day of week: "%s"', $dayOfWeek)); 60 | } 61 | } 62 | 63 | public static function validateHour($hour) 64 | { 65 | if ($hour < 0 || $hour > 23) { 66 | throw new \InvalidArgumentException('Invalid hour (must be >= 0 and <= 23).'); 67 | } 68 | } 69 | 70 | public static function validateMinute($minute) 71 | { 72 | if ($minute < 0 || $minute > 59) { 73 | throw new \InvalidArgumentException('Invalid minute (must be >= 0 and <= 59).'); 74 | } 75 | } 76 | 77 | public static function validateSecond($second) 78 | { 79 | if ($second < 0 || $second > 59) { 80 | throw new \InvalidArgumentException('Invalid second (must be >= 0 and <= 59).'); 81 | } 82 | } 83 | 84 | public static function validateDayOfMonth($day) 85 | { 86 | if ($day < 1 || $day > 31) { 87 | throw new \InvalidArgumentException('Invalid day of month (must be >= 1 and <= 31).'); 88 | } 89 | } 90 | 91 | public static function validateMonth($month) 92 | { 93 | if ($month < 1 || $month > 12) { 94 | throw new \InvalidArgumentException('Invalid month (must be >= 1 and <= 12.'); 95 | } 96 | } 97 | 98 | public static function validateYear($year) 99 | { 100 | if ($year < 0 || $year > self::MAX_YEAR()) { 101 | throw new \InvalidArgumentException('Invalid year (must be >= 0 and <= ' . self::MAX_YEAR()); 102 | } 103 | } 104 | 105 | public static function validateIntervalUnit($intervalUnit) 106 | { 107 | if ($intervalUnit < IntervalUnit::SECOND || $intervalUnit > IntervalUnit::YEAR) { 108 | throw new \InvalidArgumentException('Invalid interval unit.'); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /pkg/quartz/Core/IntervalUnit.php: -------------------------------------------------------------------------------- 1 | 8 | * Called by the{@link Scheduler}
when a{@link Trigger}
9 | * fires that is associated with theJob
. 10 | * 11 | * 12 | *13 | * The implementation may wish to set a 14 | * {@link JobExecutionContext#setResult(Object) result} object on the 15 | * {@link JobExecutionContext} before this method exits. The result itself 16 | * is meaningless to Quartz, but may be informative to 17 | *
21 | * 22 | * @param JobExecutionContext $context 23 | * 24 | */ 25 | public function execute(JobExecutionContext $context); 26 | } 27 | -------------------------------------------------------------------------------- /pkg/quartz/Core/JobDetail.php: -------------------------------------------------------------------------------- 1 | Job instance. JobDetails are 6 | * to be created/defined with {@link JobBuilder}. 7 | * 8 | *{@link JobListener}s
or 18 | *{@link TriggerListener}s
that are watching the job's 19 | * execution. 20 | *9 | * Quartz does not store an actual instance of a
12 | * 13 | *Job
class, but 10 | * instead allows you to define an instance of one, through the use of aJobDetail
. 11 | *14 | *
17 | * 18 | *Job
s have a name and group associated with them, which 15 | * should uniquely identify them within a single{@link Scheduler}
. 16 | *19 | *
23 | * 24 | * @see JobBuilder 25 | * @see Job 26 | * @see JobDataMap 27 | * @see Trigger 28 | */ 29 | interface JobDetail 30 | { 31 | /** 32 | * @return Key 33 | */ 34 | public function getKey(); 35 | 36 | /** 37 | *Trigger
s are the 'mechanism' by whichJob
s 20 | * are scheduled. ManyTrigger
s can point to the sameJob
, 21 | * but a singleTrigger
can only point to oneJob
. 22 | *38 | * Return the description given to the
41 | * 42 | * @return string|null if no description was set. 43 | */ 44 | public function getDescription(); 45 | 46 | /** 47 | *Job
instance by its 39 | * creator (if any). 40 | *48 | * Get the instance of
50 | * 51 | * @return string 52 | */ 53 | public function getJobClass(); 54 | 55 | /** 56 | *Job
that will be executed. 49 | *57 | * Get the
59 | * 60 | * @return array 61 | */ 62 | public function getJobDataMap(); 63 | 64 | /** 65 | *JobDataMap
that is associated with theJob
. 58 | *66 | * Whether or not the
69 | * 70 | *Job
should remain stored after it is 67 | * orphaned (no{@link Trigger}s
point to it). 68 | *71 | * If not explicitly set, the default value is
73 | * 74 | * @return booleanfalse
. 72 | *true
if the Job should remain persisted after being orphaned. 75 | */ 76 | public function isDurable(); 77 | 78 | /** 79 | *80 | * Instructs the
84 | * 85 | *Scheduler
whether or not theJob
81 | * should be re-executed if a 'recovery' or 'fail-over' situation is 82 | * encountered. 83 | *86 | * If not explicitly set, the default value is
88 | * 89 | * @see JobExecutionContext#isRecovering() 90 | * 91 | * @return bool 92 | */ 93 | public function requestsRecovery(); 94 | } 95 | -------------------------------------------------------------------------------- /pkg/quartz/Core/JobFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * A JobFactory is responsible for producing instances offalse
. 87 | *Job
7 | * classes. 8 | * 9 | * 10 | *11 | * This interface may be of use to those wishing to have their application 12 | * produce
15 | */ 16 | interface JobFactory 17 | { 18 | 19 | /** 20 | * Called by the scheduler at the time of the trigger firing, in order to 21 | * produce aJob
instances via some special mechanism, such as to 13 | * give the opportunity for dependency injection. 14 | *Job
instance on which to call execute. 22 | * 23 | *24 | * It should be extremely rare for this method to throw an exception - 25 | * basically only the case where there is no way at all to instantiate 26 | * and prepare the Job for execution. When the exception is thrown, the 27 | * Scheduler will move all triggers associated with the Job into the 28 | *
32 | * 33 | * @param JobDetail $jobDetail 34 | * 35 | * @return Job 36 | */ 37 | public function newJob(JobDetail $jobDetail); 38 | } 39 | -------------------------------------------------------------------------------- /pkg/quartz/Core/JobPersistenceException.php: -------------------------------------------------------------------------------- 1 | setInstance(self::INSTANCE); 27 | 28 | $this->setName($name); 29 | $this->setGroup(empty($group) ? self::DEFAULT_GROUP : $group); 30 | } 31 | 32 | /** 33 | * @param string $instance 34 | */ 35 | protected function setInstance($instance) 36 | { 37 | $this->setValue('instance', $instance); 38 | } 39 | 40 | /** 41 | * @return string 42 | */ 43 | public function getName() 44 | { 45 | return $this->getValue('name'); 46 | } 47 | 48 | /** 49 | * @param string $name 50 | */ 51 | private function setName($name) 52 | { 53 | $this->setValue('name', $name); 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getGroup() 60 | { 61 | return $this->getValue('group'); 62 | } 63 | 64 | /** 65 | * @param string $group 66 | */ 67 | private function setGroup($group) 68 | { 69 | $this->setValue('group', $group); 70 | } 71 | 72 | /** 73 | * @param string|null $group 74 | * 75 | * @return string 76 | */ 77 | public static function createUniqueName($group = null) 78 | { 79 | $group = empty($group) ? self::DEFAULT_GROUP : $group; 80 | $group = Uuid::uuid3(self::GROUP_NS, $group)->toString(); 81 | $name = Uuid::uuid4()->toString(); 82 | 83 | return $group.'-'.$name; 84 | } 85 | 86 | /** 87 | * @param Key $key 88 | * 89 | * @return bool 90 | */ 91 | public function equals(Key $key) 92 | { 93 | return ((string) $this) == ((string) $key); 94 | } 95 | 96 | /** 97 | * @return string 98 | */ 99 | function __toString() 100 | { 101 | return $this->getGroup().'.'.$this->getName(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pkg/quartz/Core/Model.php: -------------------------------------------------------------------------------- 1 | {@link JobDetail},Trigger.STATE_ERROR
state, which will require human 29 | * intervention (e.g. an application restart after fixing whatever 30 | * configuration problem led to the issue wih instantiating the Job. 31 | *{@link Trigger}
7 | * or{@link Calendar}
) in a{@link Scheduler}
8 | * failed, because one with the same name & group already exists. 9 | */ 10 | class ObjectAlreadyExistsException extends JobPersistenceException 11 | { 12 | /** 13 | * @param object $object 14 | * 15 | * @return ObjectAlreadyExistsException 16 | */ 17 | public static function create($object) 18 | { 19 | if ($object instanceof JobDetail) { 20 | $message = sprintf( 21 | 'Unable to store Job : "%s", because one already exists with this identification.', $object->getKey() 22 | ); 23 | } elseif ($object instanceof Trigger) { 24 | $message = sprintf( 25 | 'Unable to store Trigger with name: "%s" and group: "%s", because one already exists with this identification.' 26 | , $object->getKey()->getName(), $object->getKey()->getGroup() 27 | ); 28 | } else { 29 | $message = (string) $object; 30 | } 31 | 32 | return new static($message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pkg/quartz/Core/ScheduleBuilder.php: -------------------------------------------------------------------------------- 1 | {@link Scheduler}. 6 | */ 7 | class SchedulerException extends \Exception 8 | { 9 | } 10 | -------------------------------------------------------------------------------- /pkg/quartz/Core/SchedulerFactory.php: -------------------------------------------------------------------------------- 1 | 8 | * Returns a client-usable handle to aScheduler
. 9 | * 10 | * 11 | * @return Scheduler 12 | */ 13 | public function getScheduler(); 14 | } 15 | -------------------------------------------------------------------------------- /pkg/quartz/Core/SimpleJobFactory.php: -------------------------------------------------------------------------------- 1 | Job, 14 | * ] 15 | * 16 | * @param Job[] $jobs 17 | */ 18 | public function __construct(array $jobs = []) 19 | { 20 | $this->jobs = $jobs; 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function newJob(JobDetail $jobDetail) 27 | { 28 | $job = null; 29 | if (isset($this->jobs[$jobDetail->getJobClass()])) { 30 | $job = $this->jobs[$jobDetail->getJobClass()]; 31 | } elseif (class_exists($jobDetail->getJobClass())) { 32 | $class = $jobDetail->getJobClass(); 33 | $job = new $class; 34 | } 35 | 36 | if (false == $job instanceof Job) { 37 | throw new SchedulerException(sprintf('Required instance of "%s", but got: "%s"', 38 | Job::class, is_object($job) ? get_class($job) : gettype($job))); 39 | } 40 | 41 | return $job; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pkg/quartz/Events/ErrorEvent.php: -------------------------------------------------------------------------------- 1 | message = $message; 36 | $this->errorCount = $errorCount; 37 | $this->exception = $exception; 38 | $this->interrupted = false; 39 | } 40 | 41 | /** 42 | * @return string 43 | */ 44 | public function getMessage() 45 | { 46 | return $this->message; 47 | } 48 | 49 | /** 50 | * @return \Exception 51 | */ 52 | public function getException() 53 | { 54 | return $this->exception; 55 | } 56 | 57 | /** 58 | * @return int 59 | */ 60 | public function getErrorCount() 61 | { 62 | return $this->errorCount; 63 | } 64 | 65 | /** 66 | * @return boolean 67 | */ 68 | public function isInterrupted() 69 | { 70 | return $this->interrupted; 71 | } 72 | 73 | /** 74 | * @param boolean $interrupted 75 | */ 76 | public function setInterrupted($interrupted) 77 | { 78 | $this->interrupted = (bool) $interrupted; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /pkg/quartz/Events/GroupsEvent.php: -------------------------------------------------------------------------------- 1 | groups = $groups; 17 | } 18 | 19 | /** 20 | * @return string[]|null 21 | */ 22 | public function getGroups(): array 23 | { 24 | return $this->groups; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /pkg/quartz/Events/JobDetailEvent.php: -------------------------------------------------------------------------------- 1 | jobDetail = $jobDetail; 19 | } 20 | 21 | /** 22 | * @return JobDetail 23 | */ 24 | public function getJobDetail() 25 | { 26 | return $this->jobDetail; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/quartz/Events/JobExecutionContextEvent.php: -------------------------------------------------------------------------------- 1 | context = $context; 24 | $this->vetoed = false; 25 | } 26 | 27 | /** 28 | * @return JobExecutionContext 29 | */ 30 | public function getContext() 31 | { 32 | return $this->context; 33 | } 34 | 35 | /** 36 | * @return boolean 37 | */ 38 | public function isVetoed() 39 | { 40 | return $this->vetoed; 41 | } 42 | 43 | /** 44 | * @param boolean $vetoed 45 | */ 46 | public function setVetoed($vetoed) 47 | { 48 | $this->vetoed = (bool) $vetoed; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /pkg/quartz/Events/KeyEvent.php: -------------------------------------------------------------------------------- 1 | key = $key; 19 | } 20 | 21 | /** 22 | * @return Key 23 | */ 24 | public function getKey(): Key 25 | { 26 | return $this->key; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/quartz/Events/TickEvent.php: -------------------------------------------------------------------------------- 1 | interrupted = false; 14 | } 15 | 16 | /** 17 | * @return boolean 18 | */ 19 | public function isInterrupted() 20 | { 21 | return $this->interrupted; 22 | } 23 | 24 | /** 25 | * @param boolean $interrupt 26 | */ 27 | public function setInterrupted($interrupt) 28 | { 29 | $this->interrupted = (bool) $interrupt; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/quartz/Events/TriggerEvent.php: -------------------------------------------------------------------------------- 1 | trigger = $trigger; 19 | } 20 | 21 | /** 22 | * @return Trigger 23 | */ 24 | public function getTrigger() 25 | { 26 | return $this->trigger; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/quartz/JobDetail/JobDetail.php: -------------------------------------------------------------------------------- 1 | setInstance(self::INSTANCE); 23 | } 24 | 25 | /** 26 | * @param string $instance 27 | */ 28 | protected function setInstance($instance) 29 | { 30 | $this->setValue('instance', $instance); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getKey() 37 | { 38 | if (null == $this->key) { 39 | $this->key = new Key($this->getValue('name'), $this->getValue('group')); 40 | } 41 | 42 | return $this->key; 43 | } 44 | 45 | /** 46 | * @param Key $key 47 | */ 48 | public function setKey(Key $key) 49 | { 50 | $this->key = $key; 51 | 52 | $this->setValue('name', $key->getName()); 53 | $this->setValue('group', $key->getGroup()); 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function getDescription() 60 | { 61 | return $this->getValue('description'); 62 | } 63 | 64 | /** 65 | * @param string $description 66 | */ 67 | public function setDescription($description) 68 | { 69 | $this->setValue('description', $description); 70 | } 71 | 72 | /** 73 | * {@inheritdoc} 74 | */ 75 | public function isDurable() 76 | { 77 | return (bool) $this->getValue('durable'); 78 | } 79 | 80 | /** 81 | * @param bool $durable 82 | */ 83 | public function setDurable($durable) 84 | { 85 | $this->setValue('durable', (bool) $durable); 86 | } 87 | 88 | /** 89 | * {@inheritdoc} 90 | */ 91 | public function getJobClass() 92 | { 93 | return $this->getValue('jobClass'); 94 | } 95 | 96 | /** 97 | * @param string $class 98 | */ 99 | public function setJobClass($class) 100 | { 101 | $this->setValue('jobClass', $class); 102 | } 103 | 104 | /** 105 | * {@inheritdoc} 106 | */ 107 | public function getJobDataMap() 108 | { 109 | return $this->getValue('jobDataMap', []); 110 | } 111 | 112 | /** 113 | * @param array $jobDataMap 114 | */ 115 | public function setJobDataMap(array $jobDataMap) 116 | { 117 | $this->setValue('jobDataMap', $jobDataMap); 118 | } 119 | 120 | /** 121 | * TODO: is not implemented :( 122 | * 123 | * {@inheritdoc} 124 | */ 125 | public function requestsRecovery() 126 | { 127 | return $this->getValue('requestsRecovery'); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /pkg/quartz/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2017 Forma-Pro 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /pkg/quartz/ModelClassFactory.php: -------------------------------------------------------------------------------- 1 | 8 | * Responsible for creating the instances of{@link JobRunShell}
9 | * to be used within the{@link QuartzScheduler} instance. 10 | * 11 | */ 12 | interface JobRunShellFactory 13 | { 14 | /** 15 | * 16 | * Called by the
19 | * 20 | * @param Trigger $trigger 21 | * 22 | * @return JobRunShell 23 | */ 24 | public function createJobRunShell(Trigger $trigger); // orig TriggerFiredBundle 25 | } 26 | -------------------------------------------------------------------------------- /pkg/quartz/Scheduler/StdJobRunShell.php: -------------------------------------------------------------------------------- 1 | scheduler = $scheduler; 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function execute(Trigger $trigger) 27 | { 28 | if (false == $jobDetail = $this->scheduler->getJobDetail($trigger->getJobKey())) { 29 | $trigger->setErrorMessage(sprintf('Job was not found with key: "%s"', (string) $trigger->getJobKey())); 30 | $this->scheduler->notifyJobStoreJobComplete($trigger, null, CompletedExecutionInstruction::SET_ALL_JOB_TRIGGERS_ERROR); 31 | 32 | return; 33 | } 34 | 35 | $calendar = null; 36 | if ($trigger->getCalendarName()) { 37 | if (false == $calendar = $this->scheduler->getCalendar($trigger->getCalendarName())) { 38 | $trigger->setErrorMessage(sprintf('Calendar was not found with name: "%s"', (string) $trigger->getCalendarName())); 39 | $this->scheduler->notifyJobStoreJobComplete($trigger, $jobDetail, CompletedExecutionInstruction::SET_ALL_JOB_TRIGGERS_ERROR); 40 | 41 | return; 42 | } 43 | } 44 | 45 | try { 46 | $job = $this->scheduler->getJobFactory()->newJob($jobDetail); 47 | } catch (\Exception $e) { 48 | $trigger->setErrorMessage(sprintf('Job instance was not created: "%s"', (string) $jobDetail->getKey())); 49 | $this->scheduler->notifyJobStoreJobComplete($trigger, $jobDetail, CompletedExecutionInstruction::SET_ALL_JOB_TRIGGERS_ERROR); 50 | 51 | return; 52 | } 53 | 54 | $context = new JobExecutionContext($this->scheduler, $trigger, $jobDetail, $calendar); 55 | 56 | $now = time(); 57 | $scheduledFireTime = (int) $context->getTrigger()->getScheduledFireTime()->format('U'); 58 | 59 | // sleep until execution time is came up 60 | if ($scheduledFireTime > $now) { 61 | $sleepTime = $scheduledFireTime - $now; 62 | 63 | if ($sleepTime > 120) { // 2 min 64 | $trigger->setErrorMessage(sprintf('Sleep time is too long. "%d"', $sleepTime)); 65 | $this->scheduler->notifyJobStoreJobComplete($trigger, $jobDetail, CompletedExecutionInstruction::NOOP); 66 | } 67 | 68 | sleep($scheduledFireTime - $now); 69 | } 70 | 71 | $startTime = microtime(true); 72 | while (true) { 73 | if ($this->scheduler->notifyTriggerListenersFired($context)) { 74 | // trigger vetoed 75 | $this->scheduler->notifyJobListenersWasVetoed($context); 76 | 77 | $instructionCode = $trigger->executionComplete($context); 78 | $this->scheduler->notifyJobStoreJobComplete($trigger, $jobDetail, $instructionCode); 79 | 80 | if (null == $trigger->getNextFireTime()) { 81 | $this->scheduler->notifySchedulerListenersFinalized($trigger); 82 | } 83 | 84 | break; 85 | } 86 | 87 | $this->scheduler->notifyJobListenersToBeExecuted($context); 88 | 89 | try { 90 | $job->execute($context); 91 | } catch (\Exception $e) { 92 | $context->setException($e); 93 | } catch (\Error $e) { 94 | $context->setException($e); 95 | } 96 | 97 | $endTime = microtime(true); 98 | $context->setJobRunTime(($endTime - $startTime) * 1000); 99 | 100 | $this->scheduler->notifyJobListenersWasExecuted($context); 101 | 102 | $instructionCode = $trigger->executionComplete($context); 103 | 104 | $this->scheduler->notifyTriggerListenersComplete($context); 105 | 106 | if ($instructionCode === CompletedExecutionInstruction::RE_EXECUTE_JOB) { 107 | $context->incrementRefireCount(); 108 | 109 | continue; 110 | } 111 | 112 | $this->scheduler->notifyJobStoreJobComplete($trigger, $jobDetail, $instructionCode); 113 | 114 | break; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /pkg/quartz/Scheduler/StdJobRunShellFactory.php: -------------------------------------------------------------------------------- 1 | jobRunShell = $jobRunShell; 19 | } 20 | 21 | /** 22 | * {@inheritdoc} 23 | */ 24 | public function createJobRunShell(Trigger $trigger) 25 | { 26 | return $this->jobRunShell; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Calendar/BaseCalendarTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Calendar::class, new BaseCalendarImpl('')); 16 | } 17 | 18 | public function testShouldSetInstanceName() 19 | { 20 | $cal = new BaseCalendarImpl('base-calendar'); 21 | 22 | $this->assertSame('base-calendar', $cal->getInstance()); 23 | } 24 | 25 | public function testCouldSetGetBaseCalendar() 26 | { 27 | $baseCal = new HolidayCalendar(); // have to use real calendar 28 | $baseCal->setDescription('the description'); 29 | 30 | $cal = new BaseCalendarImpl(''); 31 | 32 | // set base calendar avoid object cache 33 | set_value($cal, 'baseCalendar', get_values($baseCal)); 34 | 35 | $this->assertNotNull($cal->getBaseCalendar()); 36 | $this->assertInstanceOf(HolidayCalendar::class, $cal->getBaseCalendar()); 37 | $this->assertSame('the description', $cal->getBaseCalendar()->getDescription()); 38 | } 39 | 40 | public function testCouldSetGetDescription() 41 | { 42 | $cal = new BaseCalendarImpl(''); 43 | $cal->setDescription('the description'); 44 | 45 | $this->assertSame('the description', $cal->getDescription()); 46 | } 47 | 48 | public function testOnIsTimeIncludedShouldReturnTrueIfBaseCalendarNotSet() 49 | { 50 | $cal = new BaseCalendarImpl(''); 51 | 52 | $this->assertTrue($cal->isTimeIncluded(1111)); 53 | } 54 | 55 | public function testOnIsTimeIncludedShouldThrowExceptionIfTimeIsLessThenZero() 56 | { 57 | $cal = new BaseCalendarImpl(''); 58 | 59 | $this->expectException(\InvalidArgumentException::class); 60 | $this->expectExceptionMessage('timeStamp must be greater 0'); 61 | 62 | $cal->isTimeIncluded(-1); 63 | } 64 | 65 | public function testOnIsTimeIncludedShouldCallBaseIsTimeIncludedMethod() 66 | { 67 | $cal = new BaseCalendarImpl(''); 68 | $cal->setBaseCalendar(new BaseCalendarImpl2('')); 69 | 70 | $this->assertSame(12345, $cal->isTimeIncluded(12345)); 71 | } 72 | 73 | public function testOnGetNextIncludedTimeShouldReturnTimeIfBaseCalendarNotSet() 74 | { 75 | $cal = new BaseCalendarImpl(''); 76 | 77 | $this->assertSame(1111, $cal->getNextIncludedTime(1111)); 78 | } 79 | 80 | public function testOnGetNextIncludedTimeShouldThrowExceptionIfTimeIsLessThenZero() 81 | { 82 | $cal = new BaseCalendarImpl(''); 83 | 84 | $this->expectException(\InvalidArgumentException::class); 85 | $this->expectExceptionMessage('timeStamp must be greater 0'); 86 | 87 | $cal->getNextIncludedTime(-1); 88 | } 89 | 90 | public function testOnGetNextIncludedTimeShouldCallBaseIsTimeIncludedMethod() 91 | { 92 | $cal = new BaseCalendarImpl(''); 93 | $cal->setBaseCalendar(new BaseCalendarImpl2('')); 94 | 95 | $this->assertSame(12345+1, $cal->getNextIncludedTime(12345)); 96 | } 97 | 98 | public function testCouldGetSetTimezone() 99 | { 100 | $cal = new BaseCalendarImpl(''); 101 | $cal->setTimeZone(new \DateTimeZone('Europe/Simferopol')); 102 | 103 | $this->assertNotNull($cal->getTimeZone()); 104 | $this->assertInstanceOf(\DateTimeZone::class, $cal->getTimeZone()); 105 | $this->assertSame('Europe/Simferopol', $cal->getTimeZone()->getName()); 106 | } 107 | } 108 | 109 | class BaseCalendarImpl extends BaseCalendar 110 | { 111 | public $isTimeIncludedReturnValue; 112 | 113 | public function getInstance() 114 | { 115 | return $this->getValue('instance'); 116 | } 117 | } 118 | 119 | class BaseCalendarImpl2 extends BaseCalendar 120 | { 121 | public function isTimeIncluded($timeStamp) 122 | { 123 | return $timeStamp; 124 | } 125 | 126 | public function getNextIncludedTime($timeStamp) 127 | { 128 | return $timeStamp + 1; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Calendar/CronCalendarTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Calendar::class, new CronCalendar()); 13 | } 14 | 15 | public function testShouldReturnTrueFalseIfTimeIncludedOrNot() 16 | { 17 | $cal = new CronCalendar(); 18 | // exclude all but business hours (8AM - 5PM) every 19 | $cal->setCronExpression('* * 0-7,18-23 ? * *'); 20 | 21 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 00:00:00'))); 22 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 07:59:59'))); 23 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-12 08:00:00'))); 24 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-12 17:59:59'))); 25 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-13 18:00:00'))); 26 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-13 23:59:59'))); 27 | } 28 | 29 | public function testShouldReturnNextInvalidTimeAfter() 30 | { 31 | $cal = new CronCalendar(); 32 | $cal->setCronExpression('0 */1 * * * *'); 33 | 34 | $invalidTime = $cal->getNextInvalidTimeAfter(new \DateTime('2012-12-12 12:00:59')); 35 | 36 | $this->assertEquals(new \DateTime('2012-12-12 12:01:01'), $invalidTime); 37 | } 38 | 39 | public function testShouldReturnNextIncludedTime() 40 | { 41 | $cal = new CronCalendar(); 42 | $cal->setCronExpression('0 */1 * * * *'); 43 | 44 | $invalidTime = $cal->getNextIncludedTime(strtotime('2012-12-12 12:00:59')); 45 | $this->assertEquals(strtotime('2012-12-12 12:01:01'), $invalidTime); 46 | 47 | $invalidTime = $cal->getNextIncludedTime(strtotime('2012-12-12 12:01:10')); 48 | $this->assertEquals(strtotime('2012-12-12 12:01:11'), $invalidTime); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Calendar/DailyCalendarTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Calendar::class, new DailyCalendar()); 13 | } 14 | 15 | public function testShouldReturnFalseWhenTimeIsIncluded() 16 | { 17 | $cal = new DailyCalendar(); 18 | $cal->setTimeRange(12, 12, 12, 13, 13, 13); 19 | 20 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-12 12:12:11'))); 21 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 12:12:12'))); 22 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 13:13:13'))); 23 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-12 13:13:14'))); 24 | } 25 | 26 | public function testShouldReturnTrueWhenTimeIsIncludedIfInvertTimeRangeIsSet() 27 | { 28 | $cal = new DailyCalendar(); 29 | $cal->setTimeRange(12, 12, 12, 13, 13, 13); 30 | $cal->setInvertTimeRange(true); 31 | 32 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 12:12:11'))); 33 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-12 12:12:12'))); 34 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-12 13:13:13'))); 35 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 13:13:14'))); 36 | } 37 | 38 | public function testShouldReturnNextIncludedTime() 39 | { 40 | $cal = new DailyCalendar(); 41 | $cal->setTimeRange(12, 12, 12, 13, 13, 13); 42 | 43 | $nextIncludedTime = $cal->getNextIncludedTime(strtotime('2012-12-12 13:00:00')); 44 | 45 | $this->assertInternalType('int', $nextIncludedTime); 46 | 47 | $this->assertEquals(strtotime('2012-12-12 13:13:14'), $nextIncludedTime); 48 | } 49 | 50 | public function testShouldReturnNextIncludedTimeWhenTimeIsIncludedIfInvertTimeRangeIsSet() 51 | { 52 | $cal = new DailyCalendar(); 53 | $cal->setTimeRange(12, 12, 12, 13, 13, 13); 54 | $cal->setInvertTimeRange(true); 55 | 56 | $nextIncludedTime = $cal->getNextIncludedTime(strtotime('2012-12-12 13:00:00')); 57 | 58 | $this->assertInternalType('int', $nextIncludedTime); 59 | 60 | $this->assertEquals(new \DateTime('2012-12-12 13:00:01'), \DateTime::createFromFormat('U', $nextIncludedTime)); 61 | } 62 | 63 | public function testShouldThrowExceptionIfEndTimeIsBeforeStartTime() 64 | { 65 | $cal = new DailyCalendar(); 66 | 67 | $this->expectException(\InvalidArgumentException::class); 68 | $this->expectExceptionMessage('Invalid time range: 12:12:12 - 12:12:11'); 69 | 70 | $cal->setTimeRange(12, 12, 12, 12, 12, 11); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Calendar/HolidayCalendarTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Calendar::class, new HolidayCalendar()); 13 | } 14 | 15 | public function testCouldAddExcludedDateAndSetTimeToMidnight() 16 | { 17 | $cal = new HolidayCalendar(); 18 | $cal->addExcludedDate(new \DateTime('2012-12-12 12:12:12')); 19 | 20 | $excludedDates = $cal->getExcludedDates(); 21 | 22 | $this->assertCount(1, $excludedDates); 23 | $this->assertEquals(new \DateTime('2012-12-12 00:00:00'), $excludedDates[0]); 24 | } 25 | 26 | public function testCouldRemoveExcludedDate() 27 | { 28 | $cal = new HolidayCalendar(); 29 | $cal->addExcludedDate(new \DateTime('2012-12-12 12:12:12')); 30 | $cal->addExcludedDate(new \DateTime('2012-12-13 12:12:12')); 31 | 32 | $this->assertCount(2, $cal->getExcludedDates()); 33 | 34 | $cal->removeExcludedDate(new \DateTime('2012-12-13 23:01:02')); 35 | $excludedDates = $cal->getExcludedDates(); 36 | 37 | $this->assertCount(1, $cal->getExcludedDates()); 38 | $this->assertEquals(new \DateTime('2012-12-12 00:00:00'), $excludedDates[0]); 39 | } 40 | 41 | public function testShouldReturnTrueFalseIfTimeIncludedOrNot() 42 | { 43 | $cal = new HolidayCalendar(); 44 | $cal->addExcludedDate(new \DateTime('2012-12-12 12:12:12')); 45 | 46 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-11 13:12:12'))); 47 | $this->assertFalse($cal->isTimeIncluded(strtotime('2012-12-12 13:12:12'))); 48 | $this->assertTrue($cal->isTimeIncluded(strtotime('2012-12-13 13:12:12'))); 49 | } 50 | 51 | public function testShouldReturnNextIncludedTime() 52 | { 53 | $cal = new HolidayCalendar(); 54 | $cal->addExcludedDate(new \DateTime('2012-12-10 12:12:12')); 55 | $cal->addExcludedDate(new \DateTime('2012-12-11 12:12:12')); 56 | $cal->addExcludedDate(new \DateTime('2012-12-12 12:12:12')); 57 | $cal->addExcludedDate(new \DateTime('2012-12-13 12:12:12')); 58 | 59 | $nextIncludedTime = $cal->getNextIncludedTime(strtotime('2012-12-11 13:12:12')); 60 | 61 | $this->assertSame(strtotime('2012-12-14 00:00:00'), $nextIncludedTime); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Calendar/MonthlyCalendarTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Calendar::class, new MonthlyCalendar()); 13 | } 14 | 15 | public function testOnSetDaysExcludedShouldThrowExceptionIfIsNotDayOfMonth() 16 | { 17 | $cal = new MonthlyCalendar(); 18 | 19 | $this->expectException(\InvalidArgumentException::class); 20 | $this->expectExceptionMessage('Invalid day of month (must be >= 1 and <= 31).'); 21 | 22 | $cal->setDaysExcluded([32]); 23 | } 24 | 25 | public function testShouldSetExcludedDaysOfMonth() 26 | { 27 | $cal = new MonthlyCalendar(); 28 | 29 | $cal->setDaysExcluded([1, 5, 10]); 30 | 31 | $this->assertSame([1, 5, 10], $cal->getDaysExcluded()); 32 | } 33 | 34 | public function testOnSetDayExcludedShouldThrowExceptionIfArgumentIsNotDayOfMonth() 35 | { 36 | $cal = new MonthlyCalendar(); 37 | 38 | $this->expectException(\InvalidArgumentException::class); 39 | $this->expectExceptionMessage('Invalid day of month (must be >= 1 and <= 31).'); 40 | 41 | $cal->setDayExcluded(32, true); 42 | } 43 | 44 | public function testShouldSetExcludedDayOfMonth() 45 | { 46 | $cal = new MonthlyCalendar(); 47 | 48 | $cal->setDayExcluded(3, true); 49 | $cal->setDayExcluded(5, true); 50 | 51 | $this->assertSame([3, 5], $cal->getDaysExcluded()); 52 | } 53 | 54 | public function testShouldUnsetExcludedDayOfMonth() 55 | { 56 | $cal = new MonthlyCalendar(); 57 | 58 | $cal->setDayExcluded(3, true); 59 | $cal->setDayExcluded(5, true); 60 | $cal->setDayExcluded(10, true); 61 | 62 | $this->assertSame([3, 5, 10], $cal->getDaysExcluded()); 63 | 64 | //unset 65 | $cal->setDayExcluded(5, false); 66 | $this->assertSame([3, 10], $cal->getDaysExcluded()); 67 | } 68 | 69 | public function testShouldReturnTrueWhenAllDaysAreExcluded() 70 | { 71 | $cal = new MonthlyCalendar(); 72 | 73 | $this->assertFalse($cal->areAllDaysExcluded()); 74 | 75 | $cal->setDaysExcluded(range(1, 31)); 76 | 77 | $this->assertTrue($cal->areAllDaysExcluded()); 78 | } 79 | 80 | public function testShouldReturnTrueWhenTimeIsIncluded() 81 | { 82 | $cal = new MonthlyCalendar(); 83 | 84 | $cal->setDaysExcluded([13]); 85 | 86 | $included = new \DateTime('2012-12-12 12:12:12'); 87 | $excluded = new \DateTime('2012-12-13 12:12:12'); 88 | 89 | // included 90 | $this->assertTrue($cal->isTimeIncluded((int) $included->format('U'))); 91 | 92 | // excluded 93 | $this->assertFalse($cal->isTimeIncluded((int) $excluded->format('U'))); 94 | } 95 | 96 | public function testShouldReturnNextIncludedTime() 97 | { 98 | $cal = new MonthlyCalendar(); 99 | 100 | $cal->setDaysExcluded([11, 12, 13, 14, 15]); 101 | 102 | $date = new \DateTime('2012-12-11 12:12:12'); 103 | 104 | $nextIncludedTime = $cal->getNextIncludedTime((int) $date->format('U')); 105 | 106 | $this->assertInternalType('int', $nextIncludedTime); 107 | 108 | $this->assertEquals(new \DateTime('2012-12-16 00:00:00'), \DateTime::createFromFormat('U', $nextIncludedTime)); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Calendar/WeeklyCalendarTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Calendar::class, new WeeklyCalendar()); 14 | } 15 | 16 | public function testShouldReturnDefaultExcludedWeekDays() 17 | { 18 | $cal = new WeeklyCalendar(); 19 | 20 | $this->assertSame([DateBuilder::SATURDAY, DateBuilder::SUNDAY], $cal->getDaysExcluded()); 21 | } 22 | 23 | public function testOnSetDaysExcludedShouldThrowExceptionIfArrayKeyIsNotDayOfWeek() 24 | { 25 | $cal = new WeeklyCalendar(); 26 | 27 | $this->expectException(\InvalidArgumentException::class); 28 | $this->expectExceptionMessage('Invalid day of week: "8"'); 29 | 30 | $cal->setDaysExcluded([8]); 31 | } 32 | 33 | public function testShouldSetExcludedDaysOfWeek() 34 | { 35 | $cal = new WeeklyCalendar(); 36 | 37 | $cal->setDaysExcluded([DateBuilder::MONDAY, DateBuilder::FRIDAY]); 38 | 39 | $this->assertSame([DateBuilder::MONDAY, DateBuilder::FRIDAY], $cal->getDaysExcluded()); 40 | } 41 | 42 | public function testOnSetDayExcludedShouldThrowExceptionIfArgumentIsNotDayOfWeek() 43 | { 44 | $cal = new WeeklyCalendar(); 45 | 46 | $this->expectException(\InvalidArgumentException::class); 47 | $this->expectExceptionMessage('Invalid day of week: "9"'); 48 | 49 | $cal->setDayExcluded(9, true); 50 | } 51 | 52 | public function testShouldSetExcludedDayOfWeek() 53 | { 54 | $cal = new WeeklyCalendar(); 55 | 56 | $cal->setDayExcluded(DateBuilder::THURSDAY, true); 57 | $cal->setDayExcluded(DateBuilder::FRIDAY, true); 58 | 59 | $this->assertSame([ 60 | DateBuilder::THURSDAY, 61 | DateBuilder::FRIDAY, 62 | DateBuilder::SATURDAY, 63 | DateBuilder::SUNDAY 64 | ], $cal->getDaysExcluded()); 65 | } 66 | 67 | public function testShouldUnsetExcludedDayOfWeek() 68 | { 69 | $cal = new WeeklyCalendar(); 70 | 71 | $cal->setDayExcluded(DateBuilder::FRIDAY, true); 72 | 73 | $this->assertSame([ 74 | DateBuilder::FRIDAY, 75 | DateBuilder::SATURDAY, 76 | DateBuilder::SUNDAY 77 | ], $cal->getDaysExcluded()); 78 | 79 | // unset 80 | $cal->setDayExcluded(DateBuilder::FRIDAY, false); 81 | $cal->setDayExcluded(DateBuilder::SUNDAY, false); 82 | 83 | $this->assertSame([ 84 | DateBuilder::SATURDAY, 85 | ], $cal->getDaysExcluded()); 86 | } 87 | 88 | public function testShouldReturnTrueWhenAllDaysAreExcluded() 89 | { 90 | $cal = new WeeklyCalendar(); 91 | 92 | $this->assertFalse($cal->areAllDaysExcluded()); 93 | 94 | $cal->setDaysExcluded(range(1, 7)); 95 | 96 | $this->assertTrue($cal->areAllDaysExcluded()); 97 | } 98 | 99 | public function testShouldReturnTrueWhenTimeIsIncluded() 100 | { 101 | $cal = new WeeklyCalendar(); 102 | 103 | $cal->setDaysExcluded([4]); 104 | 105 | $included = new \DateTime('2012-12-12 12:12:12'); 106 | $excluded = new \DateTime('2012-12-13 12:12:12'); 107 | 108 | // included 109 | $this->assertSame(3, (int) $included->format('N')); 110 | $this->assertTrue($cal->isTimeIncluded((int) $included->format('U'))); 111 | 112 | // excluded 113 | $this->assertSame(4, (int) $excluded->format('N')); 114 | $this->assertFalse($cal->isTimeIncluded((int) $excluded->format('U'))); 115 | } 116 | 117 | public function testShouldReturnNextIncludedTime() 118 | { 119 | $cal = new WeeklyCalendar(); 120 | 121 | $cal->setDaysExcluded([2, 3, 4, 5]); 122 | 123 | $date = new \DateTime('2012-12-11 12:12:12'); 124 | 125 | $this->assertSame(2, (int) $date->format('N')); 126 | 127 | $nextIncludedTime = $cal->getNextIncludedTime((int) $date->format('U')); 128 | 129 | $this->assertInternalType('int', $nextIncludedTime); 130 | 131 | $this->assertEquals(new \DateTime('2012-12-15 00:00:00'), \DateTime::createFromFormat('U', $nextIncludedTime)); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Core/DateBuilderTest.php: -------------------------------------------------------------------------------- 1 | format('Y'); 13 | 14 | $this->assertSame($year+100, DateBuilder::MAX_YEAR()); 15 | } 16 | 17 | public function testOnValidateDayOfWeekShouldThrowExceptionIfInvalidValue() 18 | { 19 | $this->expectException(\InvalidArgumentException::class); 20 | $this->expectExceptionMessage('Invalid day of week: "100"'); 21 | 22 | DateBuilder::validateDayOfWeek(100); 23 | } 24 | 25 | public function testOnValidateDayOfWeekShouldNotThrowExceptionIfValidValue() 26 | { 27 | DateBuilder::validateDayOfWeek(DateBuilder::MONDAY); 28 | DateBuilder::validateDayOfWeek(DateBuilder::THURSDAY); 29 | DateBuilder::validateDayOfWeek(DateBuilder::WEDNESDAY); 30 | DateBuilder::validateDayOfWeek(DateBuilder::THURSDAY); 31 | DateBuilder::validateDayOfWeek(DateBuilder::FRIDAY); 32 | DateBuilder::validateDayOfWeek(DateBuilder::SATURDAY); 33 | DateBuilder::validateDayOfWeek(DateBuilder::SUNDAY); 34 | } 35 | 36 | public function testOnValidateHourShouldThrowExceptionIfInvalidValue() 37 | { 38 | $this->expectException(\InvalidArgumentException::class); 39 | $this->expectExceptionMessage('Invalid hour (must be >= 0 and <= 23).'); 40 | 41 | DateBuilder::validateHour(24); 42 | } 43 | 44 | public function testOnValidateHourShouldNotThrowExceptionIfValidValue() 45 | { 46 | DateBuilder::validateHour(0); 47 | DateBuilder::validateHour(23); 48 | } 49 | 50 | public function testOnValidateMinuteShouldThrowExceptionIfInvalidValue() 51 | { 52 | $this->expectException(\InvalidArgumentException::class); 53 | $this->expectExceptionMessage('Invalid minute (must be >= 0 and <= 59).'); 54 | 55 | DateBuilder::validateMinute(60); 56 | } 57 | 58 | public function testOnValidateMinuteShouldNotThrowExceptionIfValidValue() 59 | { 60 | DateBuilder::validateMinute(0); 61 | DateBuilder::validateMinute(59); 62 | } 63 | 64 | public function testOnValidateSecondShouldThrowExceptionIfInvalidValue() 65 | { 66 | $this->expectException(\InvalidArgumentException::class); 67 | $this->expectExceptionMessage('Invalid second (must be >= 0 and <= 59).'); 68 | 69 | DateBuilder::validateSecond(60); 70 | } 71 | 72 | public function testOnValidateSecondShouldNotThrowExceptionIfValidValue() 73 | { 74 | DateBuilder::validateSecond(0); 75 | DateBuilder::validateSecond(59); 76 | } 77 | 78 | public function testOnValidateDayOfMonthShouldThrowExceptionIfInvalidValue() 79 | { 80 | $this->expectException(\InvalidArgumentException::class); 81 | $this->expectExceptionMessage('Invalid day of month (must be >= 1 and <= 31).'); 82 | 83 | DateBuilder::validateDayOfMonth(32); 84 | } 85 | 86 | public function testOnValidateDayOfMonthShouldNotThrowExceptionIfValidValue() 87 | { 88 | DateBuilder::validateDayOfMonth(1); 89 | DateBuilder::validateDayOfMonth(31); 90 | } 91 | 92 | public function testOnValidateMonthShouldThrowExceptionIfInvalidValue() 93 | { 94 | $this->expectException(\InvalidArgumentException::class); 95 | $this->expectExceptionMessage('Invalid month (must be >= 1 and <= 12.'); 96 | 97 | DateBuilder::validateMonth(13); 98 | } 99 | 100 | public function testOnValidateMonthShouldNotThrowExceptionIfValidValue() 101 | { 102 | DateBuilder::validateMonth(1); 103 | DateBuilder::validateMonth(12); 104 | } 105 | 106 | public function testOnValidateYearShouldThrowExceptionIfInvalidValue() 107 | { 108 | $year = (int) (new \DateTime())->format('Y'); 109 | 110 | $this->expectException(\InvalidArgumentException::class); 111 | $this->expectExceptionMessage(sprintf('Invalid year (must be >= 0 and <= %d', $year + 100)); 112 | 113 | DateBuilder::validateYear($year + 200); 114 | } 115 | 116 | public function testOnValidateYearShouldNotThrowExceptionIfValidValue() 117 | { 118 | $year = (int) (new \DateTime())->format('Y'); 119 | 120 | DateBuilder::validateYear(0); 121 | DateBuilder::validateYear($year + 100); 122 | } 123 | 124 | public function testOnValidateIntervalUnitShouldThrowExceptionIfInvalidValue() 125 | { 126 | $this->expectException(\InvalidArgumentException::class); 127 | $this->expectExceptionMessage('Invalid interval unit.'); 128 | 129 | DateBuilder::validateIntervalUnit(100); 130 | } 131 | 132 | public function testOnValidateIntervalUnitShouldNotThrowExceptionIfValidValue() 133 | { 134 | DateBuilder::validateIntervalUnit(IntervalUnit::SECOND); 135 | DateBuilder::validateIntervalUnit(IntervalUnit::MINUTE); 136 | DateBuilder::validateIntervalUnit(IntervalUnit::HOUR); 137 | DateBuilder::validateIntervalUnit(IntervalUnit::DAY); 138 | DateBuilder::validateIntervalUnit(IntervalUnit::WEEK); 139 | DateBuilder::validateIntervalUnit(IntervalUnit::MONTH); 140 | DateBuilder::validateIntervalUnit(IntervalUnit::YEAR); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Core/KeyTest.php: -------------------------------------------------------------------------------- 1 | assertSame('name', $key->getName()); 14 | $this->assertSame('DEFAULT', $key->getGroup()); 15 | } 16 | 17 | public function testCouldBeConstructedWithNameAndGroup() 18 | { 19 | $key = new Key('name', 'group'); 20 | 21 | $this->assertSame('name', $key->getName()); 22 | $this->assertSame('group', $key->getGroup()); 23 | } 24 | 25 | public function testShouldThrowExceptionIfNameIsEmpty() 26 | { 27 | $this->expectException(\InvalidArgumentException::class); 28 | $this->expectExceptionMessage('Name cannot be empty'); 29 | 30 | new Key(''); 31 | } 32 | 33 | public function testCouldCompareKeys() 34 | { 35 | $this->assertTrue((new Key('name', 'group'))->equals(new Key('name', 'group'))); 36 | $this->assertFalse((new Key('name1', 'group'))->equals(new Key('name', 'group'))); 37 | } 38 | 39 | public function testCouldCastObjectToString() 40 | { 41 | $this->assertSame('group.name', (string) new Key('name', 'group')); 42 | } 43 | 44 | public function testShouldGenerateUniqueNames() 45 | { 46 | $name1 = Key::createUniqueName(); 47 | $name2 = Key::createUniqueName(); 48 | 49 | $this->assertNotEmpty($name1); 50 | $this->assertNotEmpty($name2); 51 | $this->assertNotEquals($name1, $name2); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Core/SimpleJobFactoryTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(JobFactory::class, new SimpleJobFactory()); 17 | } 18 | 19 | public function testShouldReturnInstanceOfJobWhichSetInConstructor() 20 | { 21 | $job = $this->createMock(Job::class); 22 | 23 | $factory = new SimpleJobFactory([ 24 | 'job-name' => $job, 25 | ]); 26 | 27 | $jobDetail = new JobDetail(); 28 | $jobDetail->setJobClass('job-name'); 29 | 30 | $this->assertSame($job, $factory->newJob($jobDetail)); 31 | } 32 | 33 | public function testShouldCreateAndReturnNewInstanceJobDetailsClass() 34 | { 35 | $factory = new SimpleJobFactory([]); 36 | 37 | $jobDetail = new JobDetail(); 38 | $jobDetail->setJobClass(SimpleJobFactoryTestJob::class); 39 | 40 | $job = $factory->newJob($jobDetail); 41 | 42 | $this->assertInstanceOf(SimpleJobFactoryTestJob::class, $job); 43 | } 44 | 45 | public function testShouldThrowSchedulerExceptionIfClassWasNotFound() 46 | { 47 | $factory = new SimpleJobFactory([]); 48 | 49 | $jobDetail = new JobDetail(); 50 | $jobDetail->setJobClass('ClassDoesNotExists'); 51 | 52 | $this->expectException(SchedulerException::class); 53 | $this->expectExceptionMessage('Required instance of "Quartz\Core\Job", but got: "NULL"'); 54 | 55 | $factory->newJob($jobDetail); 56 | } 57 | 58 | public function testShouldThrowSchedulerExceptionIfInstanceOfObjectIsNotJobInterface() 59 | { 60 | $factory = new SimpleJobFactory([ 61 | 'job-name' => new \stdClass(), 62 | ]); 63 | 64 | $jobDetail = new JobDetail(); 65 | $jobDetail->setJobClass('job-name'); 66 | 67 | $this->expectException(SchedulerException::class); 68 | $this->expectExceptionMessage('Required instance of "Quartz\Core\Job", but got: "stdClass"'); 69 | 70 | $factory->newJob($jobDetail); 71 | } 72 | } 73 | 74 | class SimpleJobFactoryTestJob implements Job 75 | { 76 | public function execute(JobExecutionContext $context) 77 | { 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/JobDetail/JobDetailTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(JobDetailInterface::class, new JobDetail()); 14 | } 15 | 16 | public function testCouldGetSetKey() 17 | { 18 | $job = new JobDetail(); 19 | $job->setKey($key = new Key('name', 'group')); 20 | 21 | $this->assertTrue($key->equals($job->getKey())); 22 | } 23 | 24 | public function testCouldGetSetDescription() 25 | { 26 | $job = new JobDetail(); 27 | $job->setDescription('the description'); 28 | 29 | $this->assertSame('the description', $job->getDescription()); 30 | } 31 | 32 | public function testCouldGetSetDurable() 33 | { 34 | $job = new JobDetail(); 35 | 36 | $job->setDurable(true); 37 | $this->assertTrue($job->isDurable()); 38 | 39 | $job->setDurable(false); 40 | $this->assertFalse($job->isDurable()); 41 | } 42 | 43 | public function testCouldGetSetJobClass() 44 | { 45 | $job = new JobDetail(); 46 | $job->setJobClass('the job class'); 47 | 48 | $this->assertSame('the job class', $job->getJobClass()); 49 | } 50 | 51 | public function testCouldGetSetJobDataMap() 52 | { 53 | $job = new JobDetail(); 54 | $job->setJobDataMap(['key' => 'value']); 55 | 56 | $this->assertSame(['key' => 'value'], $job->getJobDataMap()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pkg/quartz/Tests/Triggers/SimpleTriggerTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Trigger::class, new SimpleTrigger()); 14 | } 15 | 16 | public function testCouldSetGetRepeatCount() 17 | { 18 | $t = new SimpleTrigger(); 19 | $t->setRepeatCount(123); 20 | 21 | $this->assertSame(123, $t->getRepeatCount()); 22 | } 23 | 24 | public function testCouldSetGetRepeatInterval() 25 | { 26 | $t = new SimpleTrigger(); 27 | $t->setRepeatInterval(123); 28 | 29 | $this->assertSame(123, $t->getRepeatInterval()); 30 | } 31 | 32 | public function testOnValidateShouldThrowExceptionIfRepeatIntervalIsLessThanOne() 33 | { 34 | $t = new SimpleTrigger(); 35 | $t->setRepeatInterval(0); 36 | 37 | $this->expectException(SchedulerException::class); 38 | $this->expectExceptionMessage('Trigger\'s name cannot be null'); 39 | 40 | $t->validate(); 41 | } 42 | 43 | public function testShouldComputeFirstFireTime() 44 | { 45 | $t = new SimpleTrigger(); 46 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 47 | $t->setRepeatInterval(10); 48 | 49 | $this->assertEquals(new \DateTime('2012-12-12 12:00:00'), $t->computeFirstFireTime()); 50 | } 51 | 52 | public function testShouldComputeFireTimeAfter() 53 | { 54 | $t = new SimpleTrigger(); 55 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 56 | $t->setRepeatInterval(10); 57 | $t->setRepeatCount(SimpleTrigger::REPEAT_INDEFINITELY); 58 | 59 | $this->assertEquals(new \DateTime('2012-12-12 12:00:10'), $t->getFireTimeAfter(new \DateTime('2012-12-12 12:00:00'))); 60 | $this->assertEquals(new \DateTime('2012-12-13 00:00:00'), $t->getFireTimeAfter(new \DateTime('2012-12-12 23:59:55'))); 61 | } 62 | 63 | public function testOnFireTimeAfterShouldReturnNullIfTimesTriggeredMoreThanRepeatCount() 64 | { 65 | $t = new SimpleTrigger(); 66 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 67 | $t->setRepeatInterval(10); 68 | $t->setTimesTriggered(5); 69 | $t->setRepeatCount(3); 70 | 71 | $this->assertNull($t->getFireTimeAfter()); 72 | } 73 | 74 | public function testOnFireTimeAfterShouldReturnNullIfRepeatCountZeroAndAfterTimeAfterStartTime() 75 | { 76 | $t = new SimpleTrigger(); 77 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 78 | $t->setRepeatInterval(10); 79 | $t->setRepeatCount(0); 80 | 81 | $this->assertNull($t->getFireTimeAfter(new \DateTime('2012-12-12 13:00:00'))); 82 | } 83 | 84 | public function testOnFireTimeAfterShouldReturnStartTimeIfAfterTimeBeforeStartTime() 85 | { 86 | $t = new SimpleTrigger(); 87 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 88 | $t->setRepeatInterval(10); 89 | $t->setRepeatCount(0); 90 | 91 | $this->assertEquals(new \DateTime('2012-12-12 12:00:00'), $t->getFireTimeAfter(new \DateTime('2012-12-12 11:00:00'))); 92 | } 93 | 94 | public function testOnFireTimeAfterShouldReturnNullIfNumTimesExecutedIsMoreThanRepeatCount() 95 | { 96 | $t = new SimpleTrigger(); 97 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 98 | $t->setRepeatInterval(10); 99 | $t->setRepeatCount(2); 100 | 101 | $this->assertNull($t->getFireTimeAfter(new \DateTime('2012-12-12 12:00:21'))); 102 | } 103 | 104 | public function testOnFireTimeAfterShouldReturnNullIfCalculatedTimeIsAfterEndTime() 105 | { 106 | $t = new SimpleTrigger(); 107 | $t->setStartTime(new \DateTime('2012-12-12 12:00:00')); 108 | $t->setEndTime(new \DateTime('2012-12-12 13:00:00')); 109 | $t->setRepeatInterval(10); 110 | $t->setRepeatCount(SimpleTrigger::REPEAT_INDEFINITELY); 111 | 112 | $this->assertNull($t->getFireTimeAfter(new \DateTime('2012-12-12 12:59:55'))); 113 | } 114 | 115 | public function testShouldUpdateAfterMisfireWithFireNowInstruction() 116 | { 117 | $t = new SimpleTrigger(); 118 | $t->setRepeatCount(0); 119 | $t->setMisfireInstruction(SimpleTrigger::MISFIRE_INSTRUCTION_FIRE_NOW); 120 | 121 | $this->assertNull($t->getNextFireTime()); 122 | 123 | $t->updateAfterMisfire(); 124 | 125 | $this->assertEquals(new \DateTime(), $t->getNextFireTime(), '', 5); // closer to now 126 | $this->assertSame(0, $t->getRepeatCount()); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /pkg/quartz/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "php-quartz/quartz", 3 | "type": "library", 4 | "minimum-stability": "dev", 5 | "description": "Job Time Scheduler Library", 6 | "keywords": ["job", "time", "task", "time scheduler", "quartz", "chrono"], 7 | "license": "MIT", 8 | "require": { 9 | "php": "^7.2", 10 | "ramsey/uuid": "^2|^3.5", 11 | "g4/cron": "^0.1", 12 | "symfony/event-dispatcher": "^3.4|^4" 13 | }, 14 | "require-dev": { 15 | "makasim/yadm": "^0.5.7", 16 | "makasim/values": "^0.5.2", 17 | "phpunit/phpunit": "^5.5" 18 | }, 19 | "suggest": { 20 | "php-quartz/bridge": "Provides a Yadm storage, Enqueue integration and other extension." 21 | }, 22 | "autoload": { 23 | "psr-4": { "Quartz\\": "" }, 24 | "exclude-from-classmap": [ 25 | "/Tests/" 26 | ] 27 | }, 28 | "extra": { 29 | "branch-alias": { 30 | "dev-master": "0.2.x-dev" 31 | } 32 | }, 33 | "config": { 34 | "bin-dir": "bin" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pkg/quartz/examples/calendar-interval-trigger.php: -------------------------------------------------------------------------------- 1 | sprintf('mongodb://%s:%s', getenv('MONGODB_HOST'), getenv('MONGODB_PORT')), 20 | 'dbName' => getenv('MONGODB_DB') 21 | ]; 22 | 23 | class MyJob implements Job 24 | { 25 | public function execute(JobExecutionContext $context) 26 | { 27 | echo sprintf('Now: %s | Scheduled: %s'.PHP_EOL, date('H:i:s'), $context->getTrigger()->getScheduledFireTime()->format('H:i:s')); 28 | } 29 | } 30 | 31 | $job = JobBuilder::newJob(MyJob::class)->build(); 32 | 33 | $trigger = TriggerBuilder::newTrigger() 34 | ->forJobDetail($job) 35 | ->endAt(new \DateTime('+2 minutes')) 36 | ->withSchedule(CalendarIntervalScheduleBuilder::calendarIntervalSchedule()->withIntervalInSeconds(10)) 37 | ->build(); 38 | 39 | $store = new YadmStore(new SimpleStoreResource($config)); 40 | $store->clearAllSchedulingData(); 41 | 42 | $scheduler = new StdScheduler($store, new StdJobRunShellFactory(new StdJobRunShell()), new SimpleJobFactory(), new EventDispatcher()); 43 | $scheduler->scheduleJob($trigger, $job); 44 | -------------------------------------------------------------------------------- /pkg/quartz/examples/cron-trigger.php: -------------------------------------------------------------------------------- 1 | sprintf('mongodb://%s:%s', getenv('MONGODB_HOST'), getenv('MONGODB_PORT')), 20 | 'dbName' => getenv('MONGODB_DB') 21 | ]; 22 | 23 | class MyJob implements Job 24 | { 25 | public function execute(JobExecutionContext $context) 26 | { 27 | echo sprintf('Now: %s | Scheduled: %s'.PHP_EOL, date('H:i:s'), $context->getTrigger()->getScheduledFireTime()->format('H:i:s')); 28 | } 29 | } 30 | 31 | $job = JobBuilder::newJob(MyJob::class)->build(); 32 | 33 | $trigger = TriggerBuilder::newTrigger() 34 | ->forJobDetail($job) 35 | ->endAt(new \DateTime('+1 minute')) 36 | ->withSchedule(CronScheduleBuilder::cronSchedule('*/5 * * * * *')) 37 | ->build(); 38 | 39 | $store = new YadmStore(new SimpleStoreResource($config)); 40 | $store->clearAllSchedulingData(); 41 | 42 | $scheduler = new StdScheduler($store, new StdJobRunShellFactory(new StdJobRunShell()), new SimpleJobFactory(), new EventDispatcher()); 43 | $scheduler->scheduleJob($job, $trigger); 44 | -------------------------------------------------------------------------------- /pkg/quartz/examples/daily-interval-trigger.php: -------------------------------------------------------------------------------- 1 | sprintf('mongodb://%s:%s', getenv('MONGODB_HOST'), getenv('MONGODB_PORT')), 21 | 'dbName' => getenv('MONGODB_DB') 22 | ]; 23 | 24 | class MyJob implements Job 25 | { 26 | public function execute(JobExecutionContext $context) 27 | { 28 | echo sprintf('Now: %s | Scheduled: %s'.PHP_EOL, date('H:i:s'), $context->getTrigger()->getScheduledFireTime()->format('H:i:s')); 29 | } 30 | } 31 | 32 | $job = JobBuilder::newJob(MyJob::class)->build(); 33 | 34 | $trigger = TriggerBuilder::newTrigger() 35 | ->forJobDetail($job) 36 | ->endAt(new \DateTime('+1 day')) 37 | ->withSchedule(DailyTimeIntervalScheduleBuilder::dailyTimeIntervalSchedule()->withIntervalInSeconds(10)) 38 | ->build(); 39 | 40 | $store = new YadmStore(new SimpleStoreResource($config)); 41 | $store->clearAllSchedulingData(); 42 | 43 | $scheduler = new StdScheduler($store, new StdJobRunShellFactory(new StdJobRunShell()), new SimpleJobFactory(), new EventDispatcher()); 44 | $scheduler->scheduleJob($trigger, $job); 45 | -------------------------------------------------------------------------------- /pkg/quartz/examples/scheduler.php: -------------------------------------------------------------------------------- 1 | sprintf('mongodb://%s:%s', getenv('MONGODB_HOST'), getenv('MONGODB_PORT')), 17 | 'dbName' => getenv('MONGODB_DB') 18 | ]; 19 | 20 | $store = new YadmStore(new SimpleStoreResource($config)); 21 | $store->clearAllSchedulingData(); 22 | 23 | class MyJob implements Job 24 | { 25 | public function execute(JobExecutionContext $context) 26 | { 27 | echo sprintf('Now: %s | Scheduled: %s'.PHP_EOL, date('H:i:s'), $context->getTrigger()->getScheduledFireTime()->format('H:i:s')); 28 | } 29 | } 30 | 31 | $scheduler = new StdScheduler($store, new StdJobRunShellFactory(new StdJobRunShell()), new SimpleJobFactory(), new EventDispatcher()); 32 | $scheduler->start(); 33 | -------------------------------------------------------------------------------- /pkg/quartz/examples/simple-trigger.php: -------------------------------------------------------------------------------- 1 | sprintf('mongodb://%s:%s', getenv('MONGODB_HOST'), getenv('MONGODB_PORT')), 20 | 'dbName' => getenv('MONGODB_DB') 21 | ]; 22 | 23 | class MyJob implements Job 24 | { 25 | public function execute(JobExecutionContext $context) 26 | { 27 | echo sprintf('Now: %s | Scheduled: %s'.PHP_EOL, date('H:i:s'), $context->getTrigger()->getScheduledFireTime()->format('H:i:s')); 28 | } 29 | } 30 | 31 | $job = JobBuilder::newJob(MyJob::class)->build(); 32 | 33 | $trigger = TriggerBuilder::newTrigger() 34 | ->forJobDetail($job) 35 | ->endAt(new \DateTime('+1 minutes')) 36 | ->withSchedule(SimpleScheduleBuilder::repeatSecondlyForever(5)) 37 | ->build(); 38 | 39 | $store = new YadmStore(new SimpleStoreResource($config)); 40 | $store->clearAllSchedulingData(); 41 | 42 | $scheduler = new StdScheduler($store, new StdJobRunShellFactory(new StdJobRunShell()), new SimpleJobFactory(), new EventDispatcher()); 43 | $scheduler->scheduleJob($job, $trigger); 44 | -------------------------------------------------------------------------------- /pkg/quartz/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 |{@link org.quartz.core.QuartzSchedulerThread}
17 | * to obtain instances of{@link JobRunShell}
. 18 | *14 | 15 | 30 | --------------------------------------------------------------------------------16 | 20 | 21 |17 | 19 |./Tests 18 |22 | 29 |23 | 28 |. 24 |25 | 27 |./vendor 26 |