Version Description
Release date: November 2nd, 2022
- Update: Fixing tdcron dependency.
Download this release
Release Info
Developer | boldgrid |
Plugin | Total Upkeep – WordPress Backup Plugin plus Restore & Migrate by BoldGrid |
Version | 1.15.4 |
Comparing to | |
See all releases |
Code changes from version 1.15.3 to 1.15.4
- admin/cron/entry/class-crontab.php +2 -2
- boldgrid-backup.php +1 -1
- cli/{verify-ef3bf6331c85b535eed0cffc76d35d3a.php → verify-539173f42c5a408cc287e505a961335f.php} +0 -0
- readme.txt +7 -1
- vendor/autoload.php +1 -1
- vendor/boldgrid/tdcron/LICENSE.md +21 -0
- vendor/boldgrid/tdcron/README.md +37 -0
- vendor/boldgrid/tdcron/class.tdcron.entry.php +295 -0
- vendor/boldgrid/tdcron/class.tdcron.php +438 -0
- vendor/boldgrid/tdcron/composer.json +18 -0
- vendor/boldgrid/tdcron/test.data.php +202 -0
- vendor/boldgrid/tdcron/test.php +80 -0
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +4 -4
- vendor/composer/installed.json +12 -0
admin/cron/entry/class-crontab.php
CHANGED
@@ -101,8 +101,8 @@ class Crontab extends Base implements Entry {
|
|
101 |
public function get_next_runtime() {
|
102 |
$core = apply_filters( 'boldgrid_backup_get_core', null );
|
103 |
|
104 |
-
require_once BOLDGRID_BACKUP_PATH . '/vendor/
|
105 |
-
require_once BOLDGRID_BACKUP_PATH . '/vendor/
|
106 |
|
107 |
/*
|
108 |
* Get our next runtime.
|
101 |
public function get_next_runtime() {
|
102 |
$core = apply_filters( 'boldgrid_backup_get_core', null );
|
103 |
|
104 |
+
require_once BOLDGRID_BACKUP_PATH . '/vendor/boldgrid/tdcron/class.tdcron.php';
|
105 |
+
require_once BOLDGRID_BACKUP_PATH . '/vendor/boldgrid/tdcron/class.tdcron.entry.php';
|
106 |
|
107 |
/*
|
108 |
* Get our next runtime.
|
boldgrid-backup.php
CHANGED
@@ -16,7 +16,7 @@
|
|
16 |
* Plugin Name: Total Upkeep
|
17 |
* Plugin URI: https://www.boldgrid.com/boldgrid-backup/
|
18 |
* Description: Automated backups, remote backup to Amazon S3 and Google Drive, stop website crashes before they happen and more. Total Upkeep is the backup solution you need.
|
19 |
-
* Version: 1.15.
|
20 |
* Author: BoldGrid
|
21 |
* Author URI: https://www.boldgrid.com/
|
22 |
* License: GPL-2.0+
|
16 |
* Plugin Name: Total Upkeep
|
17 |
* Plugin URI: https://www.boldgrid.com/boldgrid-backup/
|
18 |
* Description: Automated backups, remote backup to Amazon S3 and Google Drive, stop website crashes before they happen and more. Total Upkeep is the backup solution you need.
|
19 |
+
* Version: 1.15.4
|
20 |
* Author: BoldGrid
|
21 |
* Author URI: https://www.boldgrid.com/
|
22 |
* License: GPL-2.0+
|
cli/{verify-ef3bf6331c85b535eed0cffc76d35d3a.php → verify-539173f42c5a408cc287e505a961335f.php}
RENAMED
File without changes
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: backup, cloud backup, database backup, restore, wordpress backup
|
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 6.1
|
6 |
Requires PHP: 5.4
|
7 |
-
Stable tag: 1.15.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -132,6 +132,12 @@ Have a problem? First, take a look at our [Getting Started](https://www.boldgrid
|
|
132 |
|
133 |
== Changelog ==
|
134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
= 1.15.3 =
|
136 |
|
137 |
Release date: November 1st, 2022
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 6.1
|
6 |
Requires PHP: 5.4
|
7 |
+
Stable tag: 1.15.4
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
132 |
|
133 |
== Changelog ==
|
134 |
|
135 |
+
= 1.15.4 =
|
136 |
+
|
137 |
+
Release date: November 2nd, 2022
|
138 |
+
|
139 |
+
* Update: Fixing tdcron dependency.
|
140 |
+
|
141 |
= 1.15.3 =
|
142 |
|
143 |
Release date: November 1st, 2022
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit8907797e5ce4c58cc1367210818a76bc::getLoader();
|
vendor/boldgrid/tdcron/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2018 Christian Land
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
vendor/boldgrid/tdcron/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
> **WARNING**: This class was written back in 2010 ! Its pretty much untested with all PHP versions > 5.6.0 and might act funny. I mostly pushed it to GitHub for easier access and in case if somebody is looking for a simple cron-parser.
|
3 |
+
|
4 |
+
# tdCron
|
5 |
+
|
6 |
+
tdCron is a ***very*** simple class to parse cron-expressions and calculate schedules.
|
7 |
+
|
8 |
+
For something more sophisticated (and WAY more modern) you can take a look at the [cron-expression](https://github.com/dragonmantank/cron-expression) package by Michael Dowling and Chris Tankersley.
|
9 |
+
|
10 |
+
## Getting Started
|
11 |
+
|
12 |
+
### Installation
|
13 |
+
|
14 |
+
Just include `class.tdcron.php` and `class.tdcron.entry.php` in your project and you're done.
|
15 |
+
|
16 |
+
## Documentation
|
17 |
+
|
18 |
+
As i mentioned before - this class is really, really simple :-)
|
19 |
+
|
20 |
+
Please just look at the code in `test.php` and `class.tdcron.php` - its reasonably well documented and should be pretty easy to understand.
|
21 |
+
|
22 |
+
It basically comes down to calling `tdCron::getNextOccurrence()` or `tdCron::getLastOccurrence()` with your cron-expression as the first parameter and an optional reference-time as the second parameter.
|
23 |
+
|
24 |
+
Lets say you've got a cron-expression like `5 0 * 8 2` (so something at 00:05 on every tuesday in august). You could use something like
|
25 |
+
|
26 |
+
echo 'next: '.date('d.m.Y, H:i:s', tdCron::getNextOccurrence('5 0 * 8 2');
|
27 |
+
|
28 |
+
to see when it should run the next time.
|
29 |
+
|
30 |
+
## Running the tests
|
31 |
+
|
32 |
+
There aren't any "real" tests included with the class (so you won't find any PHPUnit-stuff here). You can find a bunch of edge-cases in the test.php / test.data.php files that were used to test the class during development.
|
33 |
+
|
34 |
+
## License
|
35 |
+
|
36 |
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details
|
37 |
+
|
vendor/boldgrid/tdcron/class.tdcron.entry.php
ADDED
@@ -0,0 +1,295 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* tinyCronEntry is part of tdCron. Its a class to parse Cron-Expressions like "1-45 1,2,3 1-30/5 January,February Mon,Tue"
|
5 |
+
* and convert it to an easily useable format.
|
6 |
+
*
|
7 |
+
* The parser is quite powerful and understands pretty much everything you will ever find in a Cron-Expression.
|
8 |
+
*
|
9 |
+
* A Cron-Expression consists of 5 segments:
|
10 |
+
*
|
11 |
+
* <pre>
|
12 |
+
* .---------------- minute (0 - 59)
|
13 |
+
* | .------------- hour (0 - 23)
|
14 |
+
* | | .---------- day of month (1 - 31)
|
15 |
+
* | | | .------- month (1 - 12)
|
16 |
+
* | | | | .----- day of week (0 - 6)
|
17 |
+
* | | | | |
|
18 |
+
* * * * * *
|
19 |
+
* </pre>
|
20 |
+
*
|
21 |
+
* Each segment can contain values, ranges and intervals. A range is always written as "value1-value2" and
|
22 |
+
* intervals as "value1/value2".
|
23 |
+
*
|
24 |
+
* Of course each segment can contain multiple values seperated by commas.
|
25 |
+
*
|
26 |
+
* Some valid examples:
|
27 |
+
*
|
28 |
+
* <pre>
|
29 |
+
* 1,2,3,4,5
|
30 |
+
* 1-5
|
31 |
+
* 10-20/*
|
32 |
+
* Jan,Feb,Oct
|
33 |
+
* Monday-Friday
|
34 |
+
* 1-10,15,20,40-50/2
|
35 |
+
* </pre>
|
36 |
+
*
|
37 |
+
* The current version of the parser understands all weekdays and month names in german and english!
|
38 |
+
*
|
39 |
+
* Usually you won't need to call this class directly.
|
40 |
+
*
|
41 |
+
* @author Christian Land <devel@tagdocs.de>
|
42 |
+
* @package tdCron
|
43 |
+
* @copyright Copyright (c) 2010-2018, Christian Land / tagdocs.de
|
44 |
+
* @license http://opensource.org/licenses/MIT MIT License
|
45 |
+
* @version 1.0.0
|
46 |
+
*/
|
47 |
+
|
48 |
+
class tdCronEntry {
|
49 |
+
|
50 |
+
/**
|
51 |
+
* The parsed cron-expression.
|
52 |
+
* @var mixed
|
53 |
+
*/
|
54 |
+
static private $cron = array();
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Ranges.
|
58 |
+
* @var mixed
|
59 |
+
*/
|
60 |
+
static private $ranges = array(IDX_MINUTE => array( 'min' => 0,
|
61 |
+
'max' => 59 ), // Minutes
|
62 |
+
IDX_HOUR => array( 'min' => 0,
|
63 |
+
'max' => 23 ), // Hours
|
64 |
+
IDX_DAY => array( 'min' => 1,
|
65 |
+
'max' => 31 ), // Days
|
66 |
+
IDX_MONTH => array( 'min' => 1,
|
67 |
+
'max' => 12 ), // Months
|
68 |
+
IDX_WEEKDAY => array( 'min' => 0,
|
69 |
+
'max' => 7 ) ); // Weekdays
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Named intervals.
|
73 |
+
* @var mixed
|
74 |
+
*/
|
75 |
+
static private $intervals = array('@yearly' => '0 0 1 1 *',
|
76 |
+
'@annualy' => '0 0 1 1 *',
|
77 |
+
'@monthly' => '0 0 1 * *',
|
78 |
+
'@weekly' => '0 0 * * 0',
|
79 |
+
'@midnight' => '0 0 * * *',
|
80 |
+
'@daily' => '0 0 * * *',
|
81 |
+
'@hourly' => '0 * * * *' );
|
82 |
+
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Possible keywords for months/weekdays.
|
86 |
+
* @var mixed
|
87 |
+
*/
|
88 |
+
static private $keywords = array(IDX_MONTH => array('/(january|januar|jan)/i' => 1,
|
89 |
+
'/(february|februar|feb)/i' => 2,
|
90 |
+
'/(march|maerz|m�rz|mar|mae|m�r)/i' => 3,
|
91 |
+
'/(april|apr)/i' => 4,
|
92 |
+
'/(may|mai)/i' => 5,
|
93 |
+
'/(june|juni|jun)/i' => 6,
|
94 |
+
'/(july|juli|jul)/i' => 7,
|
95 |
+
'/(august|aug)/i' => 8,
|
96 |
+
'/(september|sep)/i' => 9,
|
97 |
+
'/(october|oktober|okt|oct)/i' => 10,
|
98 |
+
'/(november|nov)/i' => 11,
|
99 |
+
'/(december|dezember|dec|dez)/i' => 12 ),
|
100 |
+
IDX_WEEKDAY => array('/(sunday|sonntag|sun|son|su|so)/i' => 0,
|
101 |
+
'/(monday|montag|mon|mo)/i' => 1,
|
102 |
+
'/(tuesday|dienstag|die|tue|tu|di)/i' => 2,
|
103 |
+
'/(wednesdays|mittwoch|mit|wed|we|mi)/i' => 3,
|
104 |
+
'/(thursday|donnerstag|don|thu|th|do)/i' => 4,
|
105 |
+
'/(friday|freitag|fre|fri|fr)/i' => 5,
|
106 |
+
'/(saturday|samstag|sam|sat|sa)/i' => 6 ) );
|
107 |
+
|
108 |
+
/**
|
109 |
+
* parseExpression() analyses crontab-expressions like "* * 1,2,3 * mon,tue" and returns an array
|
110 |
+
* containing all values. If it can't be parsed, an exception is thrown.
|
111 |
+
*
|
112 |
+
* @access public
|
113 |
+
* @param string $expression The cron-expression to parse.
|
114 |
+
* @return mixed
|
115 |
+
*/
|
116 |
+
|
117 |
+
static public function parse($expression) {
|
118 |
+
|
119 |
+
// Convert named expressions if neccessary
|
120 |
+
|
121 |
+
if (substr($expression,0,1) == '@') {
|
122 |
+
|
123 |
+
$expression = strtr($expression, self::$intervals);
|
124 |
+
|
125 |
+
if (substr($expression,0,1) == '@') {
|
126 |
+
|
127 |
+
// Oops... unknown named interval!?!!
|
128 |
+
throw new Exception('Unknown named interval ['.$expression.']', 10000);
|
129 |
+
|
130 |
+
}
|
131 |
+
|
132 |
+
}
|
133 |
+
|
134 |
+
// Next basic check... do we have 5 segments?
|
135 |
+
|
136 |
+
$cron = explode(' ',$expression);
|
137 |
+
|
138 |
+
if (count($cron) <> 5) {
|
139 |
+
|
140 |
+
// No... we haven't...
|
141 |
+
throw new Exception('Wrong number of segments in expression. Expected: 5, Found: '.count($cron), 10001);
|
142 |
+
|
143 |
+
} else {
|
144 |
+
|
145 |
+
// Yup, 5 segments... lets see if we can work with them
|
146 |
+
|
147 |
+
foreach ($cron as $idx=>$segment) {
|
148 |
+
|
149 |
+
try {
|
150 |
+
|
151 |
+
$dummy[$idx] = self::expandSegment($idx, $segment);
|
152 |
+
|
153 |
+
} catch (Exception $e) {
|
154 |
+
|
155 |
+
throw $e;
|
156 |
+
|
157 |
+
}
|
158 |
+
|
159 |
+
}
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
return $dummy;
|
164 |
+
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* expandSegment() analyses a single segment
|
169 |
+
*
|
170 |
+
* @access public
|
171 |
+
* @param void
|
172 |
+
* @return void
|
173 |
+
*/
|
174 |
+
|
175 |
+
static private function expandSegment($idx, $segment) {
|
176 |
+
|
177 |
+
// Store original segment for later use
|
178 |
+
|
179 |
+
$osegment = $segment;
|
180 |
+
|
181 |
+
// Replace months/weekdays like "January", "February", etc. with numbers
|
182 |
+
|
183 |
+
if (isset(self::$keywords[$idx])) {
|
184 |
+
|
185 |
+
$segment = preg_replace( array_keys(self::$keywords[$idx]),
|
186 |
+
array_values(self::$keywords[$idx]),
|
187 |
+
$segment );
|
188 |
+
|
189 |
+
}
|
190 |
+
|
191 |
+
// Replace wildcards
|
192 |
+
|
193 |
+
if (substr($segment,0,1) == '*') {
|
194 |
+
|
195 |
+
$segment = preg_replace('/^\*(\/\d+)?$/i',
|
196 |
+
self::$ranges[$idx]['min'].'-'.self::$ranges[$idx]['max'].'$1',
|
197 |
+
$segment);
|
198 |
+
|
199 |
+
}
|
200 |
+
|
201 |
+
// Make sure that nothing unparsed is left :)
|
202 |
+
|
203 |
+
$dummy = preg_replace('/[0-9\-\/\,]/','',$segment);
|
204 |
+
|
205 |
+
if (!empty($dummy)) {
|
206 |
+
|
207 |
+
// Ohoh.... thats not good :-)
|
208 |
+
throw new Exception('Failed to parse segment: '.$osegment, 10002);
|
209 |
+
|
210 |
+
}
|
211 |
+
|
212 |
+
// At this point our string should be OK - lets convert it to an array
|
213 |
+
|
214 |
+
$result = array();
|
215 |
+
$atoms = explode(',',$segment);
|
216 |
+
|
217 |
+
foreach ($atoms as $curatom) {
|
218 |
+
|
219 |
+
$result = array_merge($result, self::parseAtom($curatom));
|
220 |
+
|
221 |
+
}
|
222 |
+
|
223 |
+
// Get rid of duplicates and sort the array
|
224 |
+
|
225 |
+
$result = array_unique($result);
|
226 |
+
sort($result);
|
227 |
+
|
228 |
+
// Check for invalid values
|
229 |
+
|
230 |
+
if ($idx == IDX_WEEKDAY) {
|
231 |
+
|
232 |
+
if (end($result) == 7) {
|
233 |
+
|
234 |
+
if (reset($result) <> 0) {
|
235 |
+
array_unshift($result, 0);
|
236 |
+
}
|
237 |
+
|
238 |
+
array_pop($result);
|
239 |
+
|
240 |
+
}
|
241 |
+
|
242 |
+
}
|
243 |
+
|
244 |
+
foreach ($result as $key=>$value) {
|
245 |
+
|
246 |
+
if (($value < self::$ranges[$idx]['min']) || ($value > self::$ranges[$idx]['max'])) {
|
247 |
+
throw new Exception('Failed to parse segment, invalid value ['.$value.']: '.$osegment, 10003);
|
248 |
+
}
|
249 |
+
|
250 |
+
}
|
251 |
+
|
252 |
+
return $result;
|
253 |
+
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* parseAtom() analyses a single segment
|
258 |
+
*
|
259 |
+
* @access public
|
260 |
+
* @param string $atom The segment to parse
|
261 |
+
* @return array
|
262 |
+
*/
|
263 |
+
|
264 |
+
static private function parseAtom($atom) {
|
265 |
+
|
266 |
+
$expanded = array();
|
267 |
+
|
268 |
+
if (preg_match('/^(\d+)-(\d+)(\/(\d+))?/i', $atom, $matches)) {
|
269 |
+
|
270 |
+
$low = $matches[1];
|
271 |
+
$high = $matches[2];
|
272 |
+
|
273 |
+
if ($low > $high) {
|
274 |
+
list($low,$high) = array($high,$low);
|
275 |
+
}
|
276 |
+
|
277 |
+
$step = isset($matches[4]) ? $matches[4] : 1;
|
278 |
+
|
279 |
+
for($i = $low; $i <= $high; $i += $step) {
|
280 |
+
$expanded[] = (int)$i;
|
281 |
+
}
|
282 |
+
|
283 |
+
} else {
|
284 |
+
|
285 |
+
$expanded[] = (int)$atom;
|
286 |
+
|
287 |
+
}
|
288 |
+
|
289 |
+
$expanded2 = array_unique($expanded);
|
290 |
+
|
291 |
+
return $expanded;
|
292 |
+
|
293 |
+
}
|
294 |
+
|
295 |
+
}
|
vendor/boldgrid/tdcron/class.tdcron.php
ADDED
@@ -0,0 +1,438 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
define('IDX_MINUTE', 0);
|
4 |
+
define('IDX_HOUR', 1);
|
5 |
+
define('IDX_DAY', 2);
|
6 |
+
define('IDX_MONTH', 3);
|
7 |
+
define('IDX_WEEKDAY', 4);
|
8 |
+
define('IDX_YEAR', 5);
|
9 |
+
|
10 |
+
/*
|
11 |
+
* @author Christian Land <devel@tagdocs.de>
|
12 |
+
* @package tdCron
|
13 |
+
* @copyright Copyright (c) 2010-2018, Christian Land / tagdocs.de
|
14 |
+
* @license http://opensource.org/licenses/MIT MIT License
|
15 |
+
* @version 1.0.0
|
16 |
+
*/
|
17 |
+
|
18 |
+
class tdCron {
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Parsed cron-expressions cache.
|
22 |
+
* @var mixed
|
23 |
+
*/
|
24 |
+
static private $pcron = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* getNextOccurrence() uses a cron-expression to calculate the time and date at which a cronjob
|
28 |
+
* should be executed the next time. If a reference-time is passed, the next time and date
|
29 |
+
* after that time is calculated.
|
30 |
+
*
|
31 |
+
* @access public
|
32 |
+
* @param string $expression cron-expression to use
|
33 |
+
* @param int $timestamp optional reference-time
|
34 |
+
* @return int
|
35 |
+
* @since 0.0.1 Initial Release
|
36 |
+
* @author Christian Land
|
37 |
+
*/
|
38 |
+
static public function getNextOccurrence($expression, $timestamp = null) {
|
39 |
+
|
40 |
+
try {
|
41 |
+
|
42 |
+
// Convert timestamp to array
|
43 |
+
|
44 |
+
$next = self::getTimestamp($timestamp);
|
45 |
+
|
46 |
+
// Calculate date/time
|
47 |
+
|
48 |
+
$next_time = self::calculateDateTime($expression, $next);
|
49 |
+
|
50 |
+
} catch (Exception $e) {
|
51 |
+
|
52 |
+
throw $e;
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
// return calculated time
|
57 |
+
|
58 |
+
return $next_time;
|
59 |
+
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* getLastOccurrence() does pretty much the same as getNextOccurrence(). The only difference
|
64 |
+
* is, that it doesn't calculate the next but the last time a cronjob should have been executed.
|
65 |
+
*
|
66 |
+
* @access public
|
67 |
+
* @param string $expression cron-expression to use
|
68 |
+
* @param int $timestamp optional reference-time
|
69 |
+
* @return int
|
70 |
+
* @since 0.0.1 Initial Release
|
71 |
+
* @author Christian Land
|
72 |
+
*/
|
73 |
+
|
74 |
+
static public function getLastOccurrence($expression, $timestamp = null) {
|
75 |
+
|
76 |
+
try {
|
77 |
+
|
78 |
+
// Convert timestamp to array
|
79 |
+
|
80 |
+
$last = self::getTimestamp($timestamp);
|
81 |
+
|
82 |
+
// Calculate date/time
|
83 |
+
|
84 |
+
$last_time = self::calculateDateTime($expression, $last, false);
|
85 |
+
|
86 |
+
} catch (Exception $e) {
|
87 |
+
|
88 |
+
throw $e;
|
89 |
+
|
90 |
+
}
|
91 |
+
|
92 |
+
// return calculated time
|
93 |
+
|
94 |
+
return $last_time;
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* calculateDateTime() is the function where all the magic happens :-)
|
100 |
+
*
|
101 |
+
* It calculates the time and date at which the next/last call of a cronjob is/was due.
|
102 |
+
*
|
103 |
+
* @access private
|
104 |
+
* @param mixed $value cron-expression
|
105 |
+
* @param mixed $rtime reference-time
|
106 |
+
* @param bool $next true = nextOccurence, false = lastOccurence
|
107 |
+
* @return int
|
108 |
+
* @since 0.0.1 Initial Release
|
109 |
+
* @author Christian Land
|
110 |
+
*/
|
111 |
+
|
112 |
+
static private function calculateDateTime($expression, $rtime, $next = true) {
|
113 |
+
|
114 |
+
// Initialize vars
|
115 |
+
|
116 |
+
$calc_date = true;
|
117 |
+
|
118 |
+
// Parse cron-expression (if neccessary)
|
119 |
+
|
120 |
+
$cron = self::getExpression($expression, !$next);
|
121 |
+
|
122 |
+
// OK, lets see if the day/month/weekday of the reference-date exist in our
|
123 |
+
// $cron-array.
|
124 |
+
|
125 |
+
if (!in_array($rtime[IDX_DAY], $cron[IDX_DAY]) ||
|
126 |
+
!in_array($rtime[IDX_MONTH], $cron[IDX_MONTH]) ||
|
127 |
+
!in_array($rtime[IDX_WEEKDAY], $cron[IDX_WEEKDAY])) {
|
128 |
+
|
129 |
+
// OK, things are easy. The day/month/weekday of the reference time
|
130 |
+
// can't be found in the $cron-array. This means that no matter what
|
131 |
+
// happens, we WILL end up at at a different date than that of our
|
132 |
+
// reference-time. And in this case, the lastOccurrence will ALWAYS
|
133 |
+
// happen at the latest possible time of the day and the nextOccurrence
|
134 |
+
// at the earliest possible time.
|
135 |
+
//
|
136 |
+
// In both cases, the time can be found in the first elements of the
|
137 |
+
// hour/minute cron-arrays.
|
138 |
+
|
139 |
+
$rtime[IDX_HOUR] = reset($cron[IDX_HOUR]);
|
140 |
+
$rtime[IDX_MINUTE] = reset($cron[IDX_MINUTE]);
|
141 |
+
|
142 |
+
} else {
|
143 |
+
|
144 |
+
// OK, things are getting a little bit more complicated...
|
145 |
+
|
146 |
+
$nhour = self::findValue($rtime[IDX_HOUR], $cron[IDX_HOUR], $next);
|
147 |
+
|
148 |
+
// Meh. Such a cruel world. Something has gone awry. Lets see HOW awry it went.
|
149 |
+
|
150 |
+
if ($nhour === false) {
|
151 |
+
|
152 |
+
// Ah, the hour-part went wrong. Thats easy. Wrong hour means that no
|
153 |
+
// matter what we do we'll end up at a different date. Thus we can use
|
154 |
+
// some simple operations to make things look pretty ;-)
|
155 |
+
//
|
156 |
+
// As alreasy mentioned before -> different date means earliest/latest
|
157 |
+
// time:
|
158 |
+
|
159 |
+
$rtime[IDX_HOUR] = reset($cron[IDX_HOUR]);
|
160 |
+
$rtime[IDX_MINUTE] = reset($cron[IDX_MINUTE]);
|
161 |
+
|
162 |
+
// Now all we have to do is add/subtract a day to get a new reference time
|
163 |
+
// to use later to find the right date. The following line probably looks
|
164 |
+
// a little odd but thats the easiest way of adding/substracting a day without
|
165 |
+
// screwing up the date. Just trust me on that one ;-)
|
166 |
+
|
167 |
+
$rtime = explode(',', strftime('%M,%H,%d,%m,%w,%Y', mktime($rtime[IDX_HOUR], $rtime[IDX_MINUTE], 0, $rtime[IDX_MONTH], $rtime[IDX_DAY], $rtime[IDX_YEAR]) + ((($next) ? 1 : -1) * 86400)));
|
168 |
+
|
169 |
+
} else {
|
170 |
+
|
171 |
+
// OK, there is a higher/lower hour available. Check the minutes-part.
|
172 |
+
|
173 |
+
$nminute = self::findValue($rtime[IDX_MINUTE], $cron[IDX_MINUTE], $next);
|
174 |
+
|
175 |
+
if ($nminute === false) {
|
176 |
+
|
177 |
+
// No matching minute-value found... lets see what happens if we substract/add an hour
|
178 |
+
|
179 |
+
$nhour = self::findValue($rtime[IDX_HOUR] + (($next) ? 1 : -1), $cron[IDX_HOUR], $next);
|
180 |
+
|
181 |
+
if ($nhour === false) {
|
182 |
+
|
183 |
+
// No more hours available... add/substract a day... you know what happens ;-)
|
184 |
+
|
185 |
+
$nminute = reset($cron[IDX_MINUTE]);
|
186 |
+
$nhour = reset($cron[IDX_HOUR]);
|
187 |
+
|
188 |
+
$rtime = explode(',', strftime('%M,%H,%d,%m,%w,%Y', mktime($nhour, $nminute, 0, $rtime[IDX_MONTH], $rtime[IDX_DAY], $rtime[IDX_YEAR]) + ((($next) ? 1 : -1) * 86400)));
|
189 |
+
|
190 |
+
} else {
|
191 |
+
|
192 |
+
// OK, there was another hour. Set the right minutes-value
|
193 |
+
|
194 |
+
$rtime[IDX_HOUR] = $nhour;
|
195 |
+
$rtime[IDX_MINUTE] = (($next) ? reset($cron[IDX_MINUTE]) : end($cron[IDX_MINUTE]));
|
196 |
+
|
197 |
+
$calc_date = false;
|
198 |
+
|
199 |
+
}
|
200 |
+
|
201 |
+
} else {
|
202 |
+
|
203 |
+
// OK, there is a matching minute... reset minutes if hour has changed
|
204 |
+
|
205 |
+
if ($nhour <> $rtime[IDX_HOUR]) {
|
206 |
+
$nminute = reset($cron[IDX_MINUTE]);
|
207 |
+
}
|
208 |
+
|
209 |
+
// Set time
|
210 |
+
|
211 |
+
$rtime[IDX_HOUR] = $nhour;
|
212 |
+
$rtime[IDX_MINUTE] = $nminute;
|
213 |
+
|
214 |
+
$calc_date = false;
|
215 |
+
|
216 |
+
}
|
217 |
+
|
218 |
+
}
|
219 |
+
|
220 |
+
}
|
221 |
+
|
222 |
+
// If we have to calculate the date... we'll do so
|
223 |
+
|
224 |
+
if ($calc_date === true) {
|
225 |
+
|
226 |
+
if (in_array($rtime[IDX_DAY], $cron[IDX_DAY]) &&
|
227 |
+
in_array($rtime[IDX_MONTH], $cron[IDX_MONTH]) &&
|
228 |
+
in_array($rtime[IDX_WEEKDAY], $cron[IDX_WEEKDAY])) {
|
229 |
+
|
230 |
+
return mktime($rtime[1], $rtime[0], 0, $rtime[3], $rtime[2], $rtime[5]);
|
231 |
+
|
232 |
+
} else {
|
233 |
+
|
234 |
+
// OK, some searching necessary...
|
235 |
+
|
236 |
+
$cdate = mktime(0, 0, 0, $rtime[IDX_MONTH], $rtime[IDX_DAY], $rtime[IDX_YEAR]);
|
237 |
+
|
238 |
+
// OK, these three nested loops are responsible for finding the date...
|
239 |
+
//
|
240 |
+
// The class has 2 limitations/bugs right now:
|
241 |
+
//
|
242 |
+
// -> it doesn't work for dates in 2036 or later!
|
243 |
+
// -> it will most likely fail if you search for a February, 29th with a given weekday
|
244 |
+
// (this does happen because the class only searches in the next/last 10 years! And
|
245 |
+
// while it usually takes less than 10 years for a "normal" date to iterate through
|
246 |
+
// all weekdays, it can take 20+ years for Feb, 29th to iterate through all weekdays!
|
247 |
+
|
248 |
+
for ($nyear = $rtime[IDX_YEAR];(($next) ? ($nyear <= $rtime[IDX_YEAR] + 10) : ($nyear >= $rtime[IDX_YEAR] -10));$nyear = $nyear + (($next) ? 1 : -1)) {
|
249 |
+
|
250 |
+
foreach ($cron[IDX_MONTH] as $nmonth) {
|
251 |
+
|
252 |
+
foreach ($cron[IDX_DAY] as $nday) {
|
253 |
+
|
254 |
+
if (checkdate($nmonth,$nday,$nyear)) {
|
255 |
+
|
256 |
+
$ndate = mktime(0,0,1,$nmonth,$nday,$nyear);
|
257 |
+
|
258 |
+
if (($next) ? ($ndate >= $cdate) : ($ndate <= $cdate)) {
|
259 |
+
|
260 |
+
$dow = date('w',$ndate);
|
261 |
+
|
262 |
+
// The date is "OK" - lets see if the weekday matches, too...
|
263 |
+
|
264 |
+
if (in_array($dow,$cron[IDX_WEEKDAY])) {
|
265 |
+
|
266 |
+
// WIN! :-) We found a valid date...
|
267 |
+
|
268 |
+
$rtime = explode(',', strftime('%M,%H,%d,%m,%w,%Y', mktime($rtime[IDX_HOUR], $rtime[IDX_MINUTE], 0, $nmonth, $nday, $nyear)));
|
269 |
+
|
270 |
+
return mktime($rtime[1], $rtime[0], 0, $rtime[3], $rtime[2], $rtime[5]);
|
271 |
+
|
272 |
+
}
|
273 |
+
|
274 |
+
}
|
275 |
+
|
276 |
+
}
|
277 |
+
|
278 |
+
}
|
279 |
+
|
280 |
+
}
|
281 |
+
|
282 |
+
}
|
283 |
+
|
284 |
+
}
|
285 |
+
|
286 |
+
throw new Exception('Failed to find date, No matching date found in a 10 years range!', 10004);
|
287 |
+
|
288 |
+
}
|
289 |
+
|
290 |
+
return mktime($rtime[1], $rtime[0], 0, $rtime[3], $rtime[2], $rtime[5]);
|
291 |
+
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* getTimestamp() converts an unix-timestamp to an array. The returned array contains the following values:
|
296 |
+
*
|
297 |
+
* [0] -> minute
|
298 |
+
* [1] -> hour
|
299 |
+
* [2] -> day
|
300 |
+
* [3] -> month
|
301 |
+
* [4] -> weekday
|
302 |
+
* [5] -> year
|
303 |
+
*
|
304 |
+
* The array is used by various functions.
|
305 |
+
*
|
306 |
+
* @access private
|
307 |
+
* @param int $timestamp If none is given, the current time is used
|
308 |
+
* @return mixed
|
309 |
+
* @since 0.0.1 Initial Release
|
310 |
+
* @author Christian Land
|
311 |
+
*/
|
312 |
+
|
313 |
+
static private function getTimestamp($timestamp = null) {
|
314 |
+
|
315 |
+
if (is_null($timestamp)) {
|
316 |
+
$arr = explode(',', strftime('%M,%H,%d,%m,%w,%Y', time()));
|
317 |
+
} else {
|
318 |
+
$arr = explode(',', strftime('%M,%H,%d,%m,%w,%Y', $timestamp));
|
319 |
+
}
|
320 |
+
|
321 |
+
// Remove leading zeros (or we'll get in trouble ;-)
|
322 |
+
|
323 |
+
foreach ($arr as $key=>$value) {
|
324 |
+
$arr[$key] = (int)ltrim($value,'0');
|
325 |
+
}
|
326 |
+
|
327 |
+
return $arr;
|
328 |
+
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* findValue() checks if the given value exists in an array. If it does not exist, the next
|
333 |
+
* higher/lower value is returned (depending on $next). If no higher/lower value exists,
|
334 |
+
* false is returned.
|
335 |
+
*
|
336 |
+
* @access public
|
337 |
+
* @param int $value
|
338 |
+
* @param mixed $data
|
339 |
+
* @param bool $next
|
340 |
+
* @return mixed
|
341 |
+
* @since 0.0.1 Initial Release
|
342 |
+
* @author Christian Land
|
343 |
+
*/
|
344 |
+
|
345 |
+
static private function findValue($value, $data, $next = true) {
|
346 |
+
|
347 |
+
if (in_array($value, $data)) {
|
348 |
+
|
349 |
+
return (int)$value;
|
350 |
+
|
351 |
+
} else {
|
352 |
+
|
353 |
+
if (($next) ? ($value <= end($data)) : ($value >= end($data))) {
|
354 |
+
|
355 |
+
foreach ($data as $curval) {
|
356 |
+
|
357 |
+
if (($next) ? ($value <= (int)$curval) : ($curval <= $value)) {
|
358 |
+
|
359 |
+
return (int)$curval;
|
360 |
+
|
361 |
+
}
|
362 |
+
|
363 |
+
}
|
364 |
+
|
365 |
+
}
|
366 |
+
|
367 |
+
}
|
368 |
+
|
369 |
+
return false;
|
370 |
+
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* getExpression() returns a parsed cron-expression. Parsed cron-expressions are cached to reduce
|
375 |
+
* unneccessary calls of the parser.
|
376 |
+
*
|
377 |
+
* @access public
|
378 |
+
* @param string $value
|
379 |
+
* @param bool $reverse
|
380 |
+
* @return mixed
|
381 |
+
* @since 0.0.1 Initial Release
|
382 |
+
* @author Christian Land
|
383 |
+
*/
|
384 |
+
|
385 |
+
static private function getExpression($expression, $reverse=false) {
|
386 |
+
|
387 |
+
// First of all we cleanup the expression and remove all duplicate tabs/spaces/etc.
|
388 |
+
// For example "* * * * *" would be converted to "* * * * *", etc.
|
389 |
+
|
390 |
+
$expression = preg_replace('/(\s+)/', ' ', strtolower(trim($expression)));
|
391 |
+
|
392 |
+
// Lets see if we've already parsed that expression
|
393 |
+
|
394 |
+
if (!isset(self::$pcron[$expression])) {
|
395 |
+
|
396 |
+
// Nope - parse it!
|
397 |
+
|
398 |
+
try {
|
399 |
+
|
400 |
+
self::$pcron[$expression] = tdCronEntry::parse($expression);
|
401 |
+
self::$pcron['reverse'][$expression] = self::arrayReverse(self::$pcron[$expression]);
|
402 |
+
|
403 |
+
} catch (Exception $e) {
|
404 |
+
|
405 |
+
throw $e;
|
406 |
+
|
407 |
+
}
|
408 |
+
|
409 |
+
}
|
410 |
+
|
411 |
+
return ($reverse ? self::$pcron['reverse'][$expression] : self::$pcron[$expression]);
|
412 |
+
|
413 |
+
}
|
414 |
+
|
415 |
+
/**
|
416 |
+
* arrayReverse() reverses all sub-arrays of our cron array. The reversed values are used for calculations
|
417 |
+
* that are run when getLastOccurence() is called.
|
418 |
+
*
|
419 |
+
* @access public
|
420 |
+
* @param mixed $cron
|
421 |
+
* @return mixed
|
422 |
+
* @since 0.0.1 Initial Release
|
423 |
+
* @author Christian Land
|
424 |
+
*/
|
425 |
+
|
426 |
+
static private function arrayReverse($cron) {
|
427 |
+
|
428 |
+
foreach ($cron as $key=>$value) {
|
429 |
+
|
430 |
+
$cron[$key] = array_reverse($value);
|
431 |
+
|
432 |
+
}
|
433 |
+
|
434 |
+
return $cron;
|
435 |
+
|
436 |
+
}
|
437 |
+
|
438 |
+
}
|
vendor/boldgrid/tdcron/composer.json
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "boldgrid/tdcron",
|
3 |
+
"description": "A simple utility to manipulate cron jobs.",
|
4 |
+
"type": "library",
|
5 |
+
"license": "GPL-2.0-or-later",
|
6 |
+
"authors": [
|
7 |
+
{
|
8 |
+
"name": "Joe Cartonia",
|
9 |
+
"email": "joec@boldgrid.com",
|
10 |
+
"homepage": "https://twitter.com/joemotocss",
|
11 |
+
"role": "Developer"
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"name": "bwmarkle",
|
15 |
+
"role": "Developer"
|
16 |
+
}
|
17 |
+
]
|
18 |
+
}
|
vendor/boldgrid/tdcron/test.data.php
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Define some tests :-)
|
4 |
+
|
5 |
+
$tests = array();
|
6 |
+
|
7 |
+
$tests[] = array(
|
8 |
+
'expression' => '10,20,45 9,10,11,12 * * *',
|
9 |
+
'reftime' => mktime(9,9,0,8,2,2010),
|
10 |
+
'expected_n' => '02.08.2010, 09:10:00',
|
11 |
+
'expected_l' => '01.08.2010, 12:45:00'
|
12 |
+
);
|
13 |
+
|
14 |
+
$tests[] = array(
|
15 |
+
'expression' => '10,20,45 9,10,11,12 * * *',
|
16 |
+
'reftime' => mktime(9,46,0,8,2,2010),
|
17 |
+
'expected_n' => '02.08.2010, 10:10:00',
|
18 |
+
'expected_l' => '02.08.2010, 09:45:00'
|
19 |
+
);
|
20 |
+
|
21 |
+
$tests[] = array(
|
22 |
+
'expression' => '10,20,45 9,10,11,12 * * *',
|
23 |
+
'reftime' => mktime(12,46,0,8,2,2010),
|
24 |
+
'expected_n' => '03.08.2010, 09:10:00',
|
25 |
+
'expected_l' => '02.08.2010, 12:45:00'
|
26 |
+
);
|
27 |
+
|
28 |
+
$tests[] = array(
|
29 |
+
'expression' => '10,20,45 9,10,11,12 * * *',
|
30 |
+
'reftime' => mktime(10,36,0,8,2,2010),
|
31 |
+
'expected_n' => '02.08.2010, 10:45:00',
|
32 |
+
'expected_l' => '02.08.2010, 10:20:00'
|
33 |
+
);
|
34 |
+
|
35 |
+
$tests[] = array(
|
36 |
+
'expression' => '10,20,45 9,10,11,12 * * *',
|
37 |
+
'reftime' => mktime(12,46,0,8,2,2010),
|
38 |
+
'expected_n' => '03.08.2010, 09:10:00',
|
39 |
+
'expected_l' => '02.08.2010, 12:45:00'
|
40 |
+
);
|
41 |
+
|
42 |
+
$tests[] = array(
|
43 |
+
'expression' => '25 9,10,12 * * *',
|
44 |
+
'reftime' => mktime(10,20,0,8,2,2010),
|
45 |
+
'expected_n' => '02.08.2010, 10:25:00',
|
46 |
+
'expected_l' => '02.08.2010, 09:25:00'
|
47 |
+
);
|
48 |
+
|
49 |
+
$tests[] = array(
|
50 |
+
'expression' => '1,2,10-20,40-50/5 10,11,12 * * *',
|
51 |
+
'reftime' => mktime(9,45,0,8,2,2010),
|
52 |
+
'expected_n' => '02.08.2010, 10:01:00',
|
53 |
+
'expected_l' => '01.08.2010, 12:50:00'
|
54 |
+
);
|
55 |
+
|
56 |
+
$tests[] = array(
|
57 |
+
'expression' => '10,30,50 10,11,12 * * *',
|
58 |
+
'reftime' => mktime(11,45,0,8,2,2010),
|
59 |
+
'expected_n' => '02.08.2010, 11:50:00',
|
60 |
+
'expected_l' => '02.08.2010, 11:30:00'
|
61 |
+
);
|
62 |
+
|
63 |
+
$tests[] = array(
|
64 |
+
'expression' => '* * 29 2 *',
|
65 |
+
'reftime' => mktime(11,45,0,8,2,2010),
|
66 |
+
'expected_n' => '29.02.2012, 00:00:00',
|
67 |
+
'expected_l' => '29.02.2008, 23:59:00'
|
68 |
+
);
|
69 |
+
|
70 |
+
$tests[] = array(
|
71 |
+
'expression' => '* * * * *',
|
72 |
+
'reftime' => mktime(11,45,0,8,2,2010),
|
73 |
+
'expected_n' => '02.08.2010, 11:45:00',
|
74 |
+
'expected_l' => '02.08.2010, 11:45:00'
|
75 |
+
);
|
76 |
+
|
77 |
+
$tests[] = array(
|
78 |
+
'expression' => '* * 3 6 3',
|
79 |
+
'reftime' => mktime(11,45,0,8,2,2010),
|
80 |
+
'expected_n' => '03.06.2015, 00:00:00',
|
81 |
+
'expected_l' => '03.06.2009, 23:59:00'
|
82 |
+
);
|
83 |
+
|
84 |
+
$tests[] = array(
|
85 |
+
'expression' => '* * 3 Feb Sat',
|
86 |
+
'reftime' => mktime(11,45,0,8,2,2010),
|
87 |
+
'expected_n' => '03.02.2018, 00:00:00',
|
88 |
+
'expected_l' => '03.02.2007, 23:59:00'
|
89 |
+
);
|
90 |
+
|
91 |
+
$tests[] = array(
|
92 |
+
'expression' => '*/15 * * * *',
|
93 |
+
'reftime' => mktime(11,40,0,8,2,2010),
|
94 |
+
'expected_n' => '02.08.2010, 11:45:00',
|
95 |
+
'expected_l' => '02.08.2010, 11:30:00'
|
96 |
+
);
|
97 |
+
|
98 |
+
$tests[] = array(
|
99 |
+
'expression' => '*/15 * * * Fri,Tue',
|
100 |
+
'reftime' => mktime(11,40,0,8,2,2010),
|
101 |
+
'expected_n' => '03.08.2010, 00:00:00',
|
102 |
+
'expected_l' => '30.07.2010, 23:45:00'
|
103 |
+
);
|
104 |
+
|
105 |
+
$tests[] = array(
|
106 |
+
'expression' => '*/15 * 1 4 Fri,Tue',
|
107 |
+
'reftime' => mktime(11,40,0,8,2,2010),
|
108 |
+
'expected_n' => '01.04.2011, 00:00:00',
|
109 |
+
'expected_l' => '01.04.2008, 23:45:00'
|
110 |
+
);
|
111 |
+
|
112 |
+
$tests[] = array(
|
113 |
+
'desc' => 'Hours match, no more minutes -> next day',
|
114 |
+
'expression' => '10,20,45 9,10,11 * * *',
|
115 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
116 |
+
'expected_n' => '02.02.2010, 09:10:00'
|
117 |
+
);
|
118 |
+
|
119 |
+
$tests[] = array(
|
120 |
+
'desc' => 'Hours match, no more minutes -> last day',
|
121 |
+
'expression' => '10,20,45 9,10,11 * * *',
|
122 |
+
'reftime' => mktime(9,5,0,2,1,2010),
|
123 |
+
'expected_l' => '31.01.2010, 11:45:00'
|
124 |
+
);
|
125 |
+
|
126 |
+
$tests[] = array(
|
127 |
+
'desc' => 'Hours match, no more minutes -> next day -> LEAP YEAR',
|
128 |
+
'expression' => '10,20,45 9,10,11 * * *',
|
129 |
+
'reftime' => mktime(11,50,0,2,28,2008),
|
130 |
+
'expected_n' => '29.02.2008, 09:10:00'
|
131 |
+
);
|
132 |
+
|
133 |
+
$tests[] = array(
|
134 |
+
'desc' => 'Hours match, no more minutes -> last day -> LEAP YEAR',
|
135 |
+
'expression' => '10,20,45 9,10,11 * * *',
|
136 |
+
'reftime' => mktime(9,5,0,3,1,2008),
|
137 |
+
'expected_l' => '29.02.2008, 11:45:00'
|
138 |
+
);
|
139 |
+
|
140 |
+
$tests[] = array(
|
141 |
+
'desc' => 'Thursday before/after Feb. 1st 2010',
|
142 |
+
'expression' => '* * * * 4',
|
143 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
144 |
+
'expected_n' => '04.02.2010, 00:00:00',
|
145 |
+
'expected_l' => '28.01.2010, 23:59:00'
|
146 |
+
);
|
147 |
+
|
148 |
+
$tests[] = array(
|
149 |
+
'desc' => 'Tuesday before/after Jan. 1st 2010',
|
150 |
+
'expression' => '* * * * 2',
|
151 |
+
'reftime' => mktime(11,50,0,1,1,2010),
|
152 |
+
'expected_n' => '05.01.2010, 00:00:00',
|
153 |
+
'expected_l' => '29.12.2009, 23:59:00'
|
154 |
+
);
|
155 |
+
|
156 |
+
$tests[] = array(
|
157 |
+
'desc' => 'Hours match, no more minutes -> next day -> August',
|
158 |
+
'expression' => '10,20,45 9,10,11 * 8,9 *',
|
159 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
160 |
+
'expected_n' => '01.08.2010, 09:10:00'
|
161 |
+
);
|
162 |
+
|
163 |
+
$tests[] = array(
|
164 |
+
'desc' => 'Hours match, no more minutes -> last day -> September',
|
165 |
+
'expression' => '10,20,45 9,10,11 * 8,9 *',
|
166 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
167 |
+
'expected_l' => '30.09.2009, 11:45:00'
|
168 |
+
);
|
169 |
+
|
170 |
+
$tests[] = array(
|
171 |
+
'desc' => 'Last February, 29th - 11:45',
|
172 |
+
'expression' => '10,20,45 9,10,11 29 2 5',
|
173 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
174 |
+
'expected_l' => '29.02.2008, 11:45:00'
|
175 |
+
);
|
176 |
+
|
177 |
+
$tests[] = array(
|
178 |
+
'desc' => 'Lets get wild with the cron-expression...',
|
179 |
+
'expression' => '7-20,3,1 5-8,12-20/3 1-10,13,15,20-30/2 March-Sep Wed-Friday',
|
180 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
181 |
+
'expected_l' => '30.09.2009, 18:20:00',
|
182 |
+
'expected_n' => '03.03.2010, 05:01:00'
|
183 |
+
);
|
184 |
+
|
185 |
+
$tests[] = array(
|
186 |
+
'desc' => 'Just a simple -> * * * * *',
|
187 |
+
'expression' => '* * * * *',
|
188 |
+
'reftime' => mktime(11,50,0,2,1,2010),
|
189 |
+
'expected_l' => '01.02.2010, 11:50:00',
|
190 |
+
'expected_n' => '01.02.2010, 11:50:00'
|
191 |
+
);
|
192 |
+
|
193 |
+
/*
|
194 |
+
// This WILL FAIL!
|
195 |
+
|
196 |
+
$tests[] = array(
|
197 |
+
'expression' => '99 * * * *',
|
198 |
+
'reftime' => mktime(11,40,0,8,2,2010),
|
199 |
+
'expected_n' => 'Error',
|
200 |
+
'expected_l' => 'Error'
|
201 |
+
);
|
202 |
+
*/
|
vendor/boldgrid/tdcron/test.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Load classes
|
4 |
+
|
5 |
+
require_once('class.tdcron.php');
|
6 |
+
require_once('class.tdcron.entry.php');
|
7 |
+
|
8 |
+
// Load tests
|
9 |
+
|
10 |
+
require_once('test.data.php');
|
11 |
+
|
12 |
+
// Rock it....
|
13 |
+
|
14 |
+
$ok = 0;
|
15 |
+
$fail = 0;
|
16 |
+
|
17 |
+
echo "\n".str_repeat('-',80)."\n";
|
18 |
+
|
19 |
+
echo 'Testing '.count($tests).' expressions...';
|
20 |
+
|
21 |
+
echo "\n\n".str_repeat('-',80)."\n";
|
22 |
+
|
23 |
+
foreach ($tests as $curtest) {
|
24 |
+
|
25 |
+
try {
|
26 |
+
|
27 |
+
if (!empty($curtest['desc'])) {
|
28 |
+
echo 'Description: ['.$curtest['desc'].']'."\n";
|
29 |
+
}
|
30 |
+
echo 'Expression: ['.$curtest['expression'].']'."\n";
|
31 |
+
|
32 |
+
echo 'Ref-Time: ['.date('d.m.Y, H:i:s', $curtest['reftime'])."]\n\n";
|
33 |
+
|
34 |
+
if (isset($curtest['expected_n'])) {
|
35 |
+
|
36 |
+
echo 'nextRun(): ['.date('d.m.Y, H:i:s', tdCron::getNextOccurrence($curtest['expression'],$curtest['reftime']))."]\n";
|
37 |
+
echo 'Expected: ['.$curtest['expected_n']."] - ";
|
38 |
+
|
39 |
+
if (date('d.m.Y, H:i:s', tdCron::getNextOccurrence($curtest['expression'],$curtest['reftime'])) == $curtest['expected_n']) {
|
40 |
+
echo 'passed!';
|
41 |
+
$ok++;
|
42 |
+
} else {
|
43 |
+
echo 'FAILED!';
|
44 |
+
$fail++;
|
45 |
+
}
|
46 |
+
|
47 |
+
echo "\n\n";
|
48 |
+
|
49 |
+
}
|
50 |
+
|
51 |
+
if (isset($curtest['expected_l'])) {
|
52 |
+
|
53 |
+
echo 'lastRun(): ['.date('d.m.Y, H:i:s', tdCron::getLastOccurrence($curtest['expression'],$curtest['reftime']))."]\n";
|
54 |
+
echo 'Expected: ['.$curtest['expected_l']."] - ";
|
55 |
+
|
56 |
+
if (date('d.m.Y, H:i:s', tdCron::getLastOccurrence($curtest['expression'],$curtest['reftime'])) == $curtest['expected_l']) {
|
57 |
+
echo 'passed!';
|
58 |
+
$ok++;
|
59 |
+
} else {
|
60 |
+
echo 'FAILED!';
|
61 |
+
$fail++;
|
62 |
+
}
|
63 |
+
|
64 |
+
echo "\n\n";
|
65 |
+
|
66 |
+
}
|
67 |
+
|
68 |
+
} catch (Exception $e) {
|
69 |
+
|
70 |
+
echo 'ERROR!'."\n\n";
|
71 |
+
print_r($e);
|
72 |
+
|
73 |
+
}
|
74 |
+
|
75 |
+
echo str_repeat('-',80)."\n";
|
76 |
+
|
77 |
+
}
|
78 |
+
|
79 |
+
echo 'OK: '.$ok."\n";
|
80 |
+
echo 'FAIL: '.$fail."\n";
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -22,15 +22,15 @@ class ComposerAutoloaderInitd3475abad362b46ca6ec161094303b5a
|
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
-
spl_autoload_register(array('
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
-
spl_autoload_unregister(array('
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
-
call_user_func(\Composer\Autoload\
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
@@ -51,19 +51,19 @@ class ComposerAutoloaderInitd3475abad362b46ca6ec161094303b5a
|
|
51 |
$loader->register(true);
|
52 |
|
53 |
if ($useStaticLoader) {
|
54 |
-
$includeFiles = Composer\Autoload\
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
-
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
function
|
67 |
{
|
68 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
require $file;
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit8907797e5ce4c58cc1367210818a76bc
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInit8907797e5ce4c58cc1367210818a76bc', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit8907797e5ce4c58cc1367210818a76bc', 'loadClassLoader'));
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit8907797e5ce4c58cc1367210818a76bc::getInitializer($loader));
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
51 |
$loader->register(true);
|
52 |
|
53 |
if ($useStaticLoader) {
|
54 |
+
$includeFiles = Composer\Autoload\ComposerStaticInit8907797e5ce4c58cc1367210818a76bc::$files;
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
+
composerRequire8907797e5ce4c58cc1367210818a76bc($fileIdentifier, $file);
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
+
function composerRequire8907797e5ce4c58cc1367210818a76bc($fileIdentifier, $file)
|
67 |
{
|
68 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
require $file;
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
@@ -91,9 +91,9 @@ class ComposerStaticInitd3475abad362b46ca6ec161094303b5a
|
|
91 |
public static function getInitializer(ClassLoader $loader)
|
92 |
{
|
93 |
return \Closure::bind(function () use ($loader) {
|
94 |
-
$loader->prefixLengthsPsr4 =
|
95 |
-
$loader->prefixDirsPsr4 =
|
96 |
-
$loader->classMap =
|
97 |
|
98 |
}, null, ClassLoader::class);
|
99 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit8907797e5ce4c58cc1367210818a76bc
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
91 |
public static function getInitializer(ClassLoader $loader)
|
92 |
{
|
93 |
return \Closure::bind(function () use ($loader) {
|
94 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit8907797e5ce4c58cc1367210818a76bc::$prefixLengthsPsr4;
|
95 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit8907797e5ce4c58cc1367210818a76bc::$prefixDirsPsr4;
|
96 |
+
$loader->classMap = ComposerStaticInit8907797e5ce4c58cc1367210818a76bc::$classMap;
|
97 |
|
98 |
}, null, ClassLoader::class);
|
99 |
}
|
vendor/composer/installed.json
CHANGED
@@ -54,6 +54,18 @@
|
|
54 |
],
|
55 |
"description": "The BoldGrid Library for shared code used in official BoldGrid plugins and themes."
|
56 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
{
|
58 |
"name": "ifsnop/mysqldump-php",
|
59 |
"version": "v2.9",
|
54 |
],
|
55 |
"description": "The BoldGrid Library for shared code used in official BoldGrid plugins and themes."
|
56 |
},
|
57 |
+
{
|
58 |
+
"name": "boldgrid/tdcron",
|
59 |
+
"version": "dev-master",
|
60 |
+
"version_normalized": "9999999-dev",
|
61 |
+
"source": {
|
62 |
+
"type": "git",
|
63 |
+
"url": "https://github.com/boldgrid/tdcron",
|
64 |
+
"reference": "origin/master"
|
65 |
+
},
|
66 |
+
"type": "library",
|
67 |
+
"installation-source": "source"
|
68 |
+
},
|
69 |
{
|
70 |
"name": "ifsnop/mysqldump-php",
|
71 |
"version": "v2.9",
|