1+ <?php
2+
3+ /*
4+ Copyright (c) 2007, Till Brehm, projektfarm Gmbh
5+ Modified 2009, Marius Cramer, pixcept KG
6+ All rights reserved.
7+
8+ Redistribution and use in source and binary forms, with or without modification,
9+ are permitted provided that the following conditions are met:
10+
11+ * Redistributions of source code must retain the above copyright notice,
12+ this list of conditions and the following disclaimer.
13+ * Redistributions in binary form must reproduce the above copyright notice,
14+ this list of conditions and the following disclaimer in the documentation
15+ and/or other materials provided with the distribution.
16+ * Neither the name of ISPConfig nor the names of its contributors
17+ may be used to endorse or promote products derived from this software without
18+ specific prior written permission.
19+
20+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+ IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+ */
31+
32+ class validate_cron {
33+
34+ function get_error ($ errmsg ) {
35+ global $ app ;
36+
37+ if (isset ($ app ->tform ->wordbook [$ errmsg ])) {
38+ return $ app ->tform ->wordbook [$ errmsg ]."<br> \r\n" ;
39+ } else {
40+ return $ errmsg ."<br> \r\n" ;
41+ }
42+ }
43+
44+ /*
45+ Validator function to check if a given cron command is in correct form (url only).
46+ */
47+ function command_format ($ field_name , $ field_value , $ validator ) {
48+ if (preg_match ("'^(\w+):\/\/' " , $ field_value , $ matches )) {
49+
50+ $ parsed = parse_url ($ field_value );
51+ if ($ parsed === false ) return $ this ->get_error ($ validator ['errmsg ' ]);
52+
53+ if ($ parsed ["scheme " ] != "http " && $ parsed ["scheme " ] != "https " ) return $ this ->get_error ($ validator ['errmsg ' ]);
54+
55+ if (preg_match ("'^([a-z0-9][a-z0-9-]{0,62}\.)+([a-z]{2,4})$'i " , $ parsed ["host " ]) == false ) return $ this ->get_error ($ validator ['errmsg ' ]);
56+ }
57+ }
58+
59+ /*
60+ Validator function to check if a given cron time is in correct form.
61+ */
62+ function run_time_format ($ field_name , $ field_value , $ validator ) {
63+ global $ app ;
64+
65+ //* check general form
66+ $ is_ok = true ;
67+ $ field_value = str_replace (" " , "" , $ field_value ); // spaces are not needed
68+ $ used_times = array ();
69+
70+ if (preg_match ("'^[0-9\-\,\/\*]+$' " , $ field_value ) == false ) return $ this ->get_error ($ validator ['errmsg ' ]); // allowed characters are 0-9, comma, *, -, /
71+ elseif (preg_match ("'[\-\,\/][\-\,\/]' " , $ field_value ) == true ) return $ this ->get_error ($ validator ['errmsg ' ]); // comma, - and / never stand together
72+ //* now split list and check each entry. store used values in array for later limit-check
73+ $ time_list = split (", " , $ field_value );
74+ if (count ($ time_list ) < 1 ) return $ this ->get_error ($ validator ['errmsg ' ]);
75+
76+ $ max_entry = 0 ;
77+ $ min_entry = 0 ;
78+ $ in_minutes = 1 ;
79+ //* get maximum value of entry for each field type (name)
80+ switch ($ field_name ) {
81+ case "run_min " :
82+ $ max_entry = 59 ;
83+ break ;
84+ case "run_hour " :
85+ $ max_entry = 23 ;
86+ $ in_minutes = 60 ;
87+ break ;
88+ case "run_mday " :
89+ $ max_entry = 31 ;
90+ $ min_entry = 1 ;
91+ $ in_minutes = 1440 ;
92+ break ;
93+ case "run_month " :
94+ $ max_entry = 12 ;
95+ $ min_entry = 1 ;
96+ $ in_minutes = 1440 * 28 ; // not exactly but enough
97+ break ;
98+ case "run_wday " :
99+ $ max_entry = 7 ;
100+ $ in_minutes = 1440 ;
101+ break ;
102+ }
103+
104+ if ($ max_entry == 0 ) return $ this ->get_error ('unknown_fieldtype_error ' );
105+
106+ foreach ($ time_list as $ entry ) {
107+ //* possible value combinations:
108+ //* x => ^(\d+)$
109+ //* x-y => ^(\d+)\-(\d+)$
110+ //* x/y => ^(\d+)\/([1-9]\d*)$
111+ //* x-y/z => ^(\d+)\-(\d+)\/([1-9]\d*)$
112+ //* */x => ^\*\/([1-9]\d*)$
113+ //* combined regex => ^(\d+|\*)(\-(\d+))?(\/([1-9]\d*))?$
114+
115+ if (preg_match ("'^(((\d+)(\-(\d+))?)|\*)(\/([1-9]\d*))?$' " , $ entry , $ matches ) == false ) {
116+ return $ this ->get_error ($ validator ['errmsg ' ]);
117+ }
118+
119+ //* matches contains:
120+ //* 1 => * or value or x-y range
121+ //* 2 => unused
122+ //* 3 => value if [1] != *
123+ //* 4 => empty if no range was used
124+ //* 5 => 2nd value of range if [1] != * and range was used
125+ //* 6 => empty if step was not used
126+ //* 7 => step
127+
128+ $ loop_step = 1 ;
129+ $ loop_from = $ min_entry ;
130+ $ loop_to = $ max_entry ;
131+
132+ //* calculate used values
133+ if ($ matches [1 ] == "* " ) {
134+ //* not to check
135+ } else {
136+ if ($ matches [3 ] < $ min_entry || $ matches [3 ] > $ max_entry ) {
137+ //* check if value is in allowed range
138+ return $ this ->get_error ($ validator ['errmsg ' ]);
139+ } elseif ($ matches [4 ] && ($ matches [5 ] < $ min_entry || $ matches [5 ] > $ max_entry || $ matches [5 ] <= $ matches [3 ])) {
140+ //* check if value is in allowed range and not less or equal to first value
141+ return $ this ->get_error ($ validator ['errmsg ' ]);
142+ }
143+
144+ $ loop_from = $ matches [3 ];
145+ $ loop_to = $ matches [3 ];
146+ if ($ matches [4 ]) $ loop_to = $ matches [5 ];
147+ }
148+ if ($ matches [6 ] && ($ matches [7 ] < 2 || $ matches [7 ] > $ max_entry - 1 )) {
149+ //* check if step value is valid
150+ return $ this ->get_error ($ validator ['errmsg ' ]);
151+ }
152+ if ($ matches [7 ]) $ loop_step = $ matches [7 ];
153+
154+ //* loop through values to set used times
155+ for ($ t = $ loop_from ; $ t <= $ loop_to ; $ t = $ t + $ loop_step ) {
156+ $ used_times [] = $ t ;
157+ }
158+ } //* end foreach entry loop
159+
160+ //* sort used times and erase doubles
161+ sort ($ used_times );
162+ $ used_times = array_unique ($ used_times );
163+
164+ //* get minimum frequency and store it in $app->tform->cron_min_freq for usage in onUpdateSave and onInsertSave!
165+ $ min_freq = -1 ;
166+ $ prev_time = -1 ;
167+ foreach ($ used_times as $ curtime ) {
168+ if ($ prev_time != -1 ) {
169+ $ freq = $ curtime - $ prev_time ;
170+ if ($ min_freq == -1 || $ freq < $ min_freq ) $ min_freq = $ freq ;
171+ }
172+ $ prev_time = $ curtime ;
173+ }
174+
175+ //* check last against first (needed because e.g. wday 1,4,7 has diff 1 not 3
176+ $ prev_time = $ used_times [0 ];
177+ $ freq = ($ prev_time - $ min_entry ) + ($ max_entry - $ curtime ) + 1 ;
178+ if ($ min_freq == -1 || $ freq < $ min_freq ) $ min_freq = $ freq ;
179+
180+ if ($ min_freq > 0 && $ min_freq <= $ max_entry ) { //* only store if > 1 && < $max_entry!
181+ $ min_freq = $ min_freq * $ in_minutes ; // we have to overwrite $app->tform->cron_min_freq if this is higher value
182+ if (!$ app ->tform ->cron_min_freq || $ app ->tform ->cron_min_freq > $ min_freq ) $ app ->tform ->cron_min_freq = $ min_freq ;
183+ }
184+
185+ //return "DEBUG: " . $app->tform->cron_min_freq . " ($min_freq) --- " . var_export($used_times, true) . "<br />";
186+ }
187+
188+
189+
190+
191+ }
0 commit comments