Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • None
  • system
    • base
    • caching
    • console
    • db
      • ar
      • schema
    • validators
    • web
      • actions
      • auth
      • helpers
      • widgets
        • captcha
        • pagers
  • zii
    • widgets
      • grid

Classes

  • AppFileUtil
  • CommandUtil
  • CrontabUtil
  • EncryptUtil
  • FileUtil
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /*****************************************************************************************
  3:  * X2Engine Open Source Edition is a customer relationship management program developed by
  4:  * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  5:  * 
  6:  * This program is free software; you can redistribute it and/or modify it under
  7:  * the terms of the GNU Affero General Public License version 3 as published by the
  8:  * Free Software Foundation with the addition of the following permission added
  9:  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 10:  * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
 11:  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 12:  * 
 13:  * This program is distributed in the hope that it will be useful, but WITHOUT
 14:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 15:  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 16:  * details.
 17:  * 
 18:  * You should have received a copy of the GNU Affero General Public License along with
 19:  * this program; if not, see http://www.gnu.org/licenses or write to the Free
 20:  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 21:  * 02110-1301 USA.
 22:  * 
 23:  * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
 24:  * California 95067, USA. or at email address contact@x2engine.com.
 25:  * 
 26:  * The interactive user interfaces in modified source and object code versions
 27:  * of this program must display Appropriate Legal Notices, as required under
 28:  * Section 5 of the GNU Affero General Public License version 3.
 29:  * 
 30:  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 31:  * these Appropriate Legal Notices must retain the display of the "Powered by
 32:  * X2Engine" logo. If the display of the logo is not reasonably feasible for
 33:  * technical reasons, the Appropriate Legal Notices must display the words
 34:  * "Powered by X2Engine".
 35:  *****************************************************************************************/
 36: 
 37: /**
 38:  * Class providing an abstraction layer for cron table editing.
 39:  *
 40:  * Abstracted data comes in the form (for each line of the X2Engine-managed section
 41:  * of the cron table): an array with keys
 42:  *
 43:  * <dl>
 44:  * <dt>schedule</dt><dd>Preset schedule. If this key is set, min-dayOfWeek keys will not be set.</dd>
 45:  * <dt>min</dt><dd>Minutes of the hour at which to run</dd>
 46:  * <dt>hour</dt><dd>Hours of the day at which to run</dd>
 47:  * <dt>dayOfMonth</dt><dd>Days of the month at which to run</dd>
 48:  * <dt>month</dt><dd>Months of the year at which to run</dd>
 49:  * <dt>dayOfWeek</dt><dd>Days of the week at which to run</dd>
 50:  * <dt>cmd</dt><dd>The cmd to run</dd>
 51:  * <dt>tag</dt><dd>Unique string identifying the cron job</dd>
 52:  * <dt>desc</dt><dd>Brief one-line (no carraige returns) description</dd>
 53:  * </dl>
 54:  * For each of the above that are defined as plural, the values could be either
 55:  * an array of possible values or "*" for "all" (see {@link https://en.wikipedia.org/wiki/Cron}
 56:  * for more information on cron table formatting and specification).
 57:  *
 58:  * NOTE: the crontab field and manged section delimeters are set the way they are
 59:  * for backwards compatibility (with old crontabs that use the old markers)
 60:  * despite the change in product naming (from X2Engine back to X2Engine).
 61:  * 
 62:  * @package application.components.util
 63:  * @author Demitri Morgan <demitri@x2engine.com>
 64:  */
 65: class CrontabUtil {
 66: 
 67:     const CRONTAB_FIELD_DELIM = '#@X2CRM@';
 68: 
 69:     const CRONTAB_MANAGED_BEGIN = '#<X2CRM>';
 70: 
 71:     const CRONTAB_MANAGED_END = '#</X2CRM>';
 72: 
 73:     /**
 74:      * If set to true, the cron tab form will include the hint.
 75:      * @var type
 76:      */
 77:     public static $printHint = true;
 78: 
 79:     /**
 80:      * @var array The parts of the cron entry that define the task itself, including metadata
 81:      *     that is ignored by the cron daemon
 82:      */
 83:     public static $taskFields = array('cmd', 'tag', 'desc');
 84: 
 85:     public static $schedules = array('hourly','daily','weekly','monthly','yearly');
 86: 
 87:     /**
 88:      * @var array The fields of the cron entry that define its schedule
 89:      */
 90:     public static $schedFields = array('min', 'hour', 'dayOfMonth', 'month', 'dayOfWeek');
 91: 
 92:     /**
 93:      * Adds delimiters for identifying X2Engine-managed cron tasks to the crontab, if they
 94:      * don't already exist.
 95:      *
 96:      * @param string $crontab reference to the current cron table in string form.
 97:      * @param bool $check if enabled, an exception will be thrown in the event that no management delimeters were found.
 98:      */
 99:     public static function addCronMarker(&$crontab, $check = false){
100:         if(strpos($crontab, self::CRONTAB_MANAGED_BEGIN) === false){
101:             if($check)
102:                 throw new Exception('X2Engine management delimiters not found in cron table.');
103:             $crontab .= implode("\n", array('', self::CRONTAB_MANAGED_BEGIN, self::CRONTAB_MANAGED_END, ''));
104:         }
105:     }
106: 
107:     /**
108:      * Modifies an existing cron table according to a specified array.
109:      * @param string $crontab The existing cron table
110:      * @param array $crontabArray The array (each index a tag and each value an
111:      *     array as specified in this class's documentation)
112:      */
113:     public static function arrayToCrontab(&$crontab, $crontabArray){
114:         self::addCronMarker($crontab);
115:         $crontabLines = explode("\n", $crontab);
116:         $newCrontabLines = array();
117:         $managed = false;
118:         $finished = false;
119:         foreach($crontabLines as $line){
120:             if(strpos($line, self::CRONTAB_MANAGED_BEGIN) !== false)
121:                 $managed = true;
122:             if(strpos($line, self::CRONTAB_MANAGED_END) !== false && $finished && $managed)
123:                 $managed = false;
124:             if($managed){
125:                 if($finished) // Done writing managed cron tasks
126:                     continue;
127:                 // The line is being replaced, technically, so it is necessary to
128:                 // re-insert the opening delimeter:
129:                 $newCrontabLines[] = self::CRONTAB_MANAGED_BEGIN;
130:                 // Add cron jobs from the array:
131:                 foreach($crontabArray as $lineCfg)
132:                     $newCrontabLines[] = self::crontabLine($lineCfg);
133:                 $finished = true;
134:             } else
135:                 $newCrontabLines[] = $line;
136:         }
137:         $crontab = implode("\n", $newCrontabLines);
138:     }
139:     
140:     /**
141:      * Takes a crontab line array and converts it to an array appropriate for
142:      * pre-populating the cron job schedule/configuration form (i.e. with
143:      * a preexisting cron job).
144:      */
145:     public static function cronJobToForm($crontabLine) {
146:         $data = $crontabLine;
147:         $data['use_schedule'] = 0;
148:         foreach(self::$schedFields as $name) {
149:             // Add "all" options for each schedule field
150:             $data["all_$name"] = 1;
151:             if(isset($data[$name])) {
152:                 if($data[$name] == '*') {
153:                     $data[$name] = array();
154:                 } else {
155:                     $data["all_$name"] = 0;
156:                 }
157:             } else {
158:                 $data[$name] = array();
159:             }
160:         }
161:         if(isset($data['schedule'])) {
162:             $data['use_schedule'] = 1;
163:         }
164:         return $data;
165:     }
166: 
167:     /**
168:      * Formats a crontab line according to the specification defined in {@link crontabArray}
169:      * @param type $l Line configuration array. Should have the keys specified in
170:      *     the main documentation of this class.
171:      * @return string
172:      */
173:     public static function crontabLine($l){
174:         if(isset($l['schedule'])) {
175:             return "@{$l['schedule']} {$l['cmd']} ".self::CRONTAB_FIELD_DELIM.$l['tag'].self::CRONTAB_FIELD_DELIM.$l['desc'];
176:         }else{
177:             foreach(self::$schedFields as $f){
178:                 ${$f} = is_array($l[$f]) ? implode(',', $l[$f]) : $l[$f];
179:             }
180:             return "$min $hour $dayOfMonth $month $dayOfWeek {$l['cmd']} ".self::CRONTAB_FIELD_DELIM.$l['tag'].self::CRONTAB_FIELD_DELIM.$l['desc'];
181:         }
182:     }
183: 
184:     /**
185:      * Parse the cron table into an array.
186:      *
187:      * Each line is followed by a management delimeter, a tag (uniquely
188:      * identifying string for the cron job) another management delimeter and a
189:      * description.
190:      *
191:      * @param string $crontab The cron table.
192:      * @return array
193:      */
194:     public static function crontabToArray(&$crontab){
195:         try{
196:             self::addCronMarker($crontab,true);
197:         }catch(Exception $e){
198:             return array();
199:         }
200:         $cron = explode(self::CRONTAB_MANAGED_BEGIN."\n", $crontab);
201:         $cron = explode("\n".self::CRONTAB_MANAGED_END, $cron[1]);
202:         $cron = explode("\n", $cron[0]);
203:         $cronArray = array();
204:         foreach($cron as $line){
205:             if(!($lineCfg = self::parseCrontabLine($line)))
206:                 continue;
207:             $cronArray[$lineCfg['tag']] = $lineCfg;
208:         }
209:         return $cronArray;
210:     }
211:     
212:     /**
213:      * Generates a form input name for a cron job configuration form section
214:      *
215:      * @param type $name Name of the input
216:      * @param type $formName Name of the form section to contain the cron input
217:      * @param type $isArray Whether the input will produce array-type data, i.e.
218:      *  a multi-select input
219:      * @return string
220:      */
221:     public static function inputName($formName,$tag,$name,$isArray=0) {
222:         return $formName."[$tag][$name]".($isArray?'[]':'');
223:     }
224: 
225:     public static function jsName($name,$tag) {
226:        return (strpos($name,'[') ? strtr($name,array('['=>'_',']'=>'_')) : $name)."_$tag";
227:     }
228:     
229:     /**
230:      * The inverse operation of {@link crontabLine}; returns false
231:      * if the line isn't compatible with specifications.
232:      *
233:      * Does not support the "/" notation (i.e. /2 for every second of whatever
234:      * time interval is being denoted)
235:      *
236:      * @param string $l The line to be parsed
237:      * @return bool|array False if the line isn't compatible with specifications, the parsed array otherwise
238:      */
239:     public static function parseCrontabLine($line) {
240:         $configTagDesc = explode(self::CRONTAB_FIELD_DELIM, $line);
241:         $nFields = count($configTagDesc);
242:         if(strpos($line,'#') === 0) // Ignore; this is a comment in the cron table.
243:             return false;
244:         if($nFields < 2) // Ignore; cron task on this line has no tag or description.
245:             return false;
246:         // Eliminate excess whitespace and normalize to single-space delineation:
247:         $config = mb_ereg_replace('\s+', ' ', $configTagDesc[0]);
248:         $configArr = explode(' ', $config);
249:         $tag = $configTagDesc[1];
250:         $cronLine = array(
251:             'tag' => $tag,
252:             'desc' => $nFields == 3 ? $configTagDesc[2] : ''
253:         );
254:         if(preg_match('/^@('.implode('|',self::$schedules).')/',$config,$matches)){
255:             // Simple schedule
256:             $cronLine['schedule'] = $matches[1];
257:             $cronLine['cmd'] = implode(' ', array_slice($configArr, 1, -1));
258:         }else if(preg_match('/^(?:[\*0-9,]+ ){5}/',$config,$matches)){
259:             // Complex schedule
260:             foreach(self::$schedFields as $i => $field){
261:                 $cronLine[$field] = $configArr[$i] == '*' ? '*' : explode(',', $configArr[$i]);
262:             }
263:             $cronLine['cmd'] = implode(' ', array_slice($configArr, 5, -1)); // Remove trailing space between cmd and delimiter.
264:         } else {
265:             // Improperly formatted cron line
266:             return false;
267:         }
268:         return $cronLine;
269:     }
270: 
271:     /**
272:      * Takes data from an instance of the crontab form generated in {@link schedForm()} and
273:      * creates a well-formatted array for creating a corresponding crontab entry.
274:      *
275:      * Can also initialize a cron job form field set from an empty array.
276:      */
277:     public static function processForm($form=array()){
278:         // Initial crontab array, with unnecessary elements stripped out
279:         $ca = array_intersect_key($form,array_fill_keys(array_merge(self::$taskFields,self::$schedFields),''));
280: 
281:         if(isset($form['schedule'],$form['use_schedule'])?$form['use_schedule']:false){
282:             // Handle preset schedule options:
283:             $ca['schedule'] = $form['schedule'];
284:         }else{
285:             // Incorporate the "all" switches (which should override selection) and
286:             // assume unrestricted if any parts aren't set:
287:             foreach(self::$schedFields as $schedPart){
288:                 // If "all_$schedPart" (i.e. all_minutes) is set to 1, or if the
289:                 // schedule part of the form is empty / not set, assume we want
290:                 // ALL (i.e. unselected or designated "all" for minutes will put
291:                 // "*" in for minutes
292:                 if((isset($form["all_$schedPart"]) ? (bool)(int)$form["all_$schedPart"] : false) || empty($form[$schedPart]))
293:                     $ca[$schedPart] = '*';
294:             }
295:         }
296:         return $ca;
297:     }
298: 
299:     /**
300:      * Generate form inputs for creating a cron task.
301:      *
302:      * Note, the JavaScript in this cron form is namespace-protected to allow
303:      * multiple cron forms within the same page. The "name" argument should be
304:      * used to control the name.
305:      *
306:      * @param array $data Previous form data submitted, if any.
307:      * @param string $name The name of the nested array in the form data containing
308:      *     information about the cron job. Must be usable as a JavaScript object
309:      *     name.
310:      * @param string $desc Optional description of cron job to save in crontab as a desc
311:      * @param string $cmd The command to run at the scheuled dates. If unspecified,
312:      * @param string $tag A "tag" in the comments uniquely identifying the cron job
313:      * @return string
314:      */
315:     public static function schedForm($data = array(), $name = 'cron',
316:             $cmd = null, $tag = 'default', $desc = null){
317:         $jsName = self::jsName($name,$tag);
318:         // JavaScript namespace for scripts pertaining to this form:
319:         $jsns = "cronForm.$jsName";
320:         $ns = function($return = 0) use($jsns) {if($return) return $jsns; else echo $jsns;};
321:         if(empty($cmd))
322:             $cmd = $desc = "";
323:         foreach(array('cmd', 'tag', 'desc') as $var){
324:             if(!empty(${$var}) && empty($data[$var])){
325:                 $data[$var] = ${$var};
326:             }
327:         }
328:         
329:         // Sets a select input to disabled (i.e. minutes, if "all_minutes" is
330:         // set) based on the previous data and the defaults for the field.
331:         $formDisabled = function($n)use($data){
332:             (isset($data[$n]) ? $data[$n] : true) ? 'disabled' : '';};
333:         // Normalizes a list of values for a crontab time interval class into an array.
334:         // Argument $t is the value
335:         // Argument $l is the list of possible values
336:         
337:         // Use a local function named similar to the message function in the
338:         // installer so that the codebase parser (when auto-translating) will
339:         // pick up on it:
340:         $installer_t = function_exists('installer_t')
341:                 ? function($m){return call_user_func('installer_t',$m);}
342:                 : (class_exists('Yii')
343:                         ? function($m){return Yii::t('install',$m);}
344:                         : function($m){return $m;}
345:                 );
346:         // Inline styles:
347:         $inlineStyles = array(
348:             '#cron-form-top' => 'display: block;',
349:             '#top-form' => 'padding-bottom: 10px;',
350:             '#cron-text-value' => 'margin-left: 125px;',
351:             '#cron-form-textarea' => 'max-width: 420px;',
352:             '#cron-form-value' => 'padding-left: 125px;',
353:             '#cron-cmd-value' => 'display: table-cell; padding-left: 26px;',
354:             '#cron-form-pair' => 'display: table;',
355:             '#cron-form-label' => 'float: left; display: table-cell;',
356:             '#cron-form-value' => 'display: table-cell; position: relative; padding-left: 20px;',
357:             '#schedFormTitle' => 'width: 100%;',
358:             '#simpleTitle' => 'padding-bottom: 15px;',
359:             '#mainTitle' => 'display: table; margin-top: -10px;',
360:             '#schedInputs' => 'width: 120px;display: table-cell;margin-top: -50px;padding-bottom: 15px;',
361:             '#cron-ui-submit' => 'position: relative; top: 7px; left: 450px; color: buttontext;',
362:             '#ui-radio' => 'margin-left: -50px;',
363:             '#cron-bot' => 'padding-bottom: 10px;',
364:             '#startCron' => 'margin-top: 20px;'
365:         );
366:         $checked = function($n,$tf) use($data) {
367:             if((bool)(int)$data[$n] == (bool)(int)$tf)
368:                 echo 'checked';
369:         };
370: 
371:         ob_start();
372:         ?>
373:         <div style="#cron-form-top">
374:             <?php if(empty($cmd)): ?>
375:                 <div style="#cron-form-pair">
376:                     <div style="#cron-form-label"><?php echo $installer_t('Command'); ?></div>
377:                     <div style="#cron-cmd-value">
378:                         <input style="#cron-textbox" name="<?php echo self::inputName($name,$tag,'cmd'); ?>" size="60" value="<?php echo $cmd; ?>" />
379:                         <input type="hidden" value="<?php echo $tag; ?>" name="<?php echo self::inputName($name,$tag,'tag'); ?>" />
380:                     </div>
381:                 </div>
382:                 <div style="#cron-form-pair">
383:                     <div style="#cron-form-label"><?php echo $installer_t('Description'); ?></div>
384:                     <div style="#cron-form-value">
385:                         <input style="#cron-textbox" name="<?php echo self::inputName($name,$tag,'desc'); ?>" size="60" value="<?php echo $desc; ?>" />
386:                         <span style="#cron-error"><?php echo $desc; ?></span>
387:                         <input type="hidden" name="<?php echo self::inputName($name,$tag,'desc'); ?>" value="" />
388:                     </div>
389:                 </div>
390:                 <input type="hidden" name="<?php echo self::inputName($name,$tag,'tag'); ?>" value="<?php echo htmlentities($data['tag'],ENT_QUOTES); ?>" />
391:             <?php else: ?>
392:                 <input type="hidden" name="<?php echo self::inputName($name,$tag,'cmd'); ?>" value="<?php echo htmlentities($cmd, ENT_QUOTES); ?>" />
393:                 <input type="hidden" name="<?php echo self::inputName($name,$tag,'desc'); ?>" value="<?php echo htmlentities($desc, ENT_QUOTES); ?>" />
394:                 <input type="hidden" name="<?php echo self::inputName($name,$tag,'tag'); ?>" value="<?php echo $tag; ?>" />
395:             <?php endif; ?>
396:         </div>
397: 
398:         <div>
399:             <input type='radio' value='1' name="<?php echo self::inputName($name,$tag,'use_schedule'); ?>" <?php $checked('use_schedule',1); ?> onclick="<?php $ns(); ?>.scheduleMode(form,1);" />
400:             <?php echo $installer_t('Simple Schedule');
401:             $scheduleList = array(
402:                 'hourly' => $installer_t('Hourly'),
403:                 'daily' => $installer_t('Daily (at Midnight)'),
404:                 'weekly' => $installer_t('Weekly (on Sunday)'),
405:                 'monthly' => $installer_t('Monthly (on the 1st)'),
406:                 'yearly' => $installer_t('Yearly (on Jan 1st)'),
407:             );
408:             $schedule = isset($data['schedule']) ? $data['schedule'] : 'hourly';
409:         ?>
410:             <select name="<?php echo self::inputName($name,$tag,'schedule'); ?>">
411:                 <?php
412:                 foreach($scheduleList as $scheduleName => $scheduleLabel){
413:                     $sel = $scheduleName == $schedule ? ' selected' : '';
414:                     echo "<option value=\"$scheduleName\"$sel>$scheduleLabel</option>";
415:                 }
416:                 ?>
417:             </select>
418:             <input type="radio" name="<?php echo self::inputName($name,$tag,'use_schedule'); ?>"  value="0" <?php $checked('use_schedule',0); ?> onchange="<?php $ns(); ?>.scheduleMode(form,0);" />
419:             <?php echo $installer_t('Times and Dates Selected'); ?>
420:             <?php echo '<p>'.(self::$printHint ? $installer_t('Note: hold down the control key (or command key, on Macintosh) to select or deselect multiple values.'):'').'</p>'; ?>
421:             <div style="#schedFormTitle">
422:                 <div style="#mainTitle">
423:                     <div style="#schedInputs">
424:                         <strong><?php echo $installer_t('Minutes'); ?></strong><br />
425:                         <div>
426:                             <input type="radio" name="<?php echo self::inputName($name,$tag,'all_min'); ?>" value="1" <?php $checked('all_min',1); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'min',1); ?>',0);" />
427:                             <?php echo $installer_t('All'); ?>
428:                             <br>
429:                             <input type="radio" name="<?php echo self::inputName($name,$tag,'all_min'); ?>" value="0" <?php $checked('all_min',0); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'min',1); ?>',1);" />
430:                             <?php echo $installer_t('Selected'); ?>
431:                         </div>
432:                         <select multiple size="10" name="<?php echo self::inputName($name,$tag,'min',1); ?>" <?php echo $formDisabled(self::inputName($name,$tag,'min',1)); ?>>
433:                             <?php
434:                             $minList = range(0,59);
435:                             $minSel = self::timeList(isset($data['min']) ? $data['min'] : array());
436:                             foreach($minList as $min){
437:                                 $sel = in_array($min,$minSel) ? ' selected' : '';
438:                                 echo "<option value=\"$min\"$sel>$min</option>";
439:                             }
440:                             ?>
441:                         </select>
442:                     </div>
443:                     <div style="#schedInputs">
444:                         <strong><?php echo $installer_t('Hours'); ?></strong><br />
445:                         <div>
446:                             <input type="radio" name="<?php echo self::inputName($name,$tag,'all_hour'); ?>" value="1" <?php $checked('all_hour',1); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'hour',1); ?>',0);" />
447:                             <?php echo $installer_t('All'); ?>
448:                             <br>
449:                             <input type="radio" name="<?php echo self::inputName($name,$tag,'all_hour'); ?>" value="0" <?php $checked('all_hour',0); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'hour',1); ?>',1);" />
450:                             <?php echo $installer_t('Selected'); ?>
451:                         </div>
452:                         <select multiple size="10" name="<?php echo self::inputName($name,$tag,'hour',1); ?>" <?php echo $formDisabled(self::inputName($name,$tag,'hour',1)); ?>>
453:                             <?php
454:                             $hourList = range(0,23);
455:                             $hourSel = self::timeList(isset($data['hour']) ? $data['hour'] : array(),$hourList);
456:                             foreach($hourList as $hour){
457:                                 $sel = in_array($hour,$hourSel) ? ' selected' : '';
458:                                 echo "<option value=\"$hour\"$sel>$hour</option>";
459:                             }
460:                             ?>
461:                         </select>
462:                     </div>
463:                     <div style="#schedInputs">
464:                         <strong><?php echo $installer_t('Days'); ?></strong><br />
465:                         <div>
466:                             <input type="radio" name="<?php echo self::inputName($name,$tag,'all_dayOfMonth'); ?>" value="1" <?php $checked('all_dayOfMonth',1); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'dayOfMonth',1); ?>',0);" />
467:                             <?php echo $installer_t('All'); ?>
468:                             <br>
469:                             <input type="radio" name="<?php echo self::inputName($name,$tag,'all_dayOfMonth'); ?>" value="0" <?php $checked('all_dayOfMonth',0); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'dayOfMonth',1); ?>',1);" />
470:                             <?php echo $installer_t('Selected'); ?>
471:                         </div>
472:                         <select multiple size="10" name="<?php echo self::inputName($name,$tag,'dayOfMonth',1); ?>" <?php echo $formDisabled(self::inputName($name,$tag,'days')); ?>>
473:                             <?php
474:                             $daysList = range(1,31);
475:                             $daysSel = self::timeList(isset($data['dayOfMonth']) ? $data['dayOfMonth'] : array(), $daysList);
476:                             foreach($daysList as $day){
477:                                 $sel = in_array($day,$daysSel) ? ' selected' : '';
478:                                 echo "<option value=\"$day\"$sel>$day</option>";
479:                             }
480:                             ?>
481:                         </select>
482:                     </div>
483:                     <div style="#schedInputs">
484:                         <strong><?php echo $installer_t('Months'); ?></strong><br />
485:                         <input type="radio" name="<?php echo self::inputName($name,$tag,'all_month'); ?>" value="1" <?php $checked('all_month',1); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'month',1); ?>',0);" />
486:                         <?php echo $installer_t('All'); ?>
487:                         <br>
488:                         <input type="radio" name="<?php echo self::inputName($name,$tag,'all_month'); ?>" value="0" <?php $checked('all_month',0); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'month',1); ?>',1);" />
489:                         <?php echo $installer_t('Selected'); ?>
490:                         <select multiple size="10" name="<?php echo self::inputName($name,$tag,'month',1); ?>" <?php echo $formDisabled(self::inputName($name,$tag,'all_month')); ?>>
491:                             <?php
492:                             $monthList = array(
493:                                 $installer_t('January'),
494:                                 $installer_t('Febraury'),
495:                                 $installer_t('March'),
496:                                 $installer_t('April'),
497:                                 $installer_t('May'),
498:                                 $installer_t('June'),
499:                                 $installer_t('July'),
500:                                 $installer_t('August'),
501:                                 $installer_t('September'),
502:                                 $installer_t('October'),
503:                                 $installer_t('November'),
504:                                 $installer_t('December'),
505:                             );
506:                             $month = self::timeList(isset($data['month']) ? $data['month'] : array());
507:                             foreach($monthList as $i => $m){
508:                                 $ii = $i+1;
509:                                 $sel = in_array($ii, $month) ? ' selected' : '';
510:                                 echo "<option value=\"$ii\"$sel>$m</option>";
511:                             }
512:                             ?>
513:                         </select>
514:                     </div>
515:                     <div style="#schedInputs">
516:                         <strong><?php echo $installer_t('Weekdays'); ?></strong><br />
517:                         <input type="radio" name="<?php echo self::inputName($name,$tag,'all_dayOfWeek'); ?>" value="1" <?php $checked('all_dayOfWeek',1); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'dayOfWeek',1); ?>',0);" />
518:                         <?php echo $installer_t('All'); ?>
519:                         <br>
520:                         <input type="radio" name="<?php echo self::inputName($name,$tag,'all_dayOfWeek'); ?>" value="0" <?php $checked('all_dayOfWeek',0); ?> onclick="<?php $ns(); ?>.enableField(form,'<?php echo self::inputName($name,$tag,'dayOfWeek',1); ?>',1);" />
521:                         <?php echo $installer_t('Selected'); ?>
522:                         <select multiple size="7" name="<?php echo self::inputName($name,$tag,'dayOfWeek',1); ?>" <?php echo $formDisabled(self::inputName($name,$tag,'dayOfWeek')); ?>>
523:                             <?php
524:                             $dayOfWeekList = array(
525:                                 $installer_t('Sunday'),
526:                                 $installer_t('Monday'),
527:                                 $installer_t('Tuesday'),
528:                                 $installer_t('Wednesday'),
529:                                 $installer_t('Thursday'),
530:                                 $installer_t('Friday'),
531:                                 $installer_t('Sautrday')
532:                             );
533:                             $dayOfWeek = self::timeList(isset($data['dayOfWeek']) ? $data['dayOfWeek'] : array());
534: 
535:                             foreach($dayOfWeekList as $i => $w){
536:                                 $sel = in_array($i, $dayOfWeek) ? ' selected' : '';
537:                                 echo "<option value=\"$i\"$sel>$w</option>";
538:                             }
539:                             ?>
540:                         </select>
541:                     </div>
542:                 </div>
543:             </div>
544:             <script>
545:                 if(typeof cronForm == 'undefined')
546:                     cronForm = {};
547:                 if(typeof cronForm._namespaces == 'undefined')
548:                     cronForm._nameSpaces = {};
549:                 if(typeof(cronForm._getSubForm) == 'undefined') {
550:                     cronForm._subForm = function(tag) {
551:                         var ns = cronForm._nameSpaces[tag];
552:                         if(typeof ns == 'undefined')
553:                             return undefined;
554:                         if(typeof cronForm[ns] == 'undefined')
555:                             return {};
556:                         return cronForm[ns];
557:                     }
558:                 }
559:                 if(typeof <?php $ns(); ?> == 'undefined') {
560:                     <?php $ns(); ?> = {};
561:                     cronForm._nameSpaces["<?php echo $tag; ?>"] = "<?php echo $jsName; ?>";
562:                 }
563:                 <?php
564:                 $schedParts =  self::$schedFields; // indexes for all "parts" of the schedule
565:                 $schedAllParts = array_map(function($n){return "all_$n";},$schedParts); // indexes for the "all" option for each part of the schedule
566:                 $schedNames = array(); // Full names for each input part of the scheule
567:                 $schedAllNames = array(); // Full names for the "all" option input
568:                 foreach($schedParts as $part) {
569:                     $schedNames[$part] = self::inputName($name,$tag,$part);
570:                     $schedAllNames["all_$part"] = self::inputName($name,$tag,"all_$part");
571:                 }
572:                 foreach(array('Parts','Names') as $array) {
573:                     foreach(array('','All') as $type) {
574:                         $jsVarName = "sched$type$array";
575:                         echo $ns(1).".$jsVarName = ".json_encode(${"$jsVarName"}).";\n".str_repeat(' ',16);
576:                     }
577:                 }
578:                 ?>
579:                 <?php $ns(); ?>.scheduleField = <?php echo json_encode(self::inputName($name,$tag,'schedule')); ?>;
580:                 <?php $ns(); ?>.scheduleModeField = <?php echo json_encode(self::inputName($name,$tag,'use_schedule')); ?>;
581:                 /**
582:                  * Enables a field in the form
583:                  */
584:                 <?php $ns(); ?>.enableField = function(form, name, enable) {
585:                     var elts = form.elements[name];
586:                     elts.disabled = !enable;
587:                     for(var i=0; i<elts.length; i++) {
588:                         elts[i].disabled = !enable;
589:                     }
590:                 }
591:                 /**
592:                  * Gets the "value" of a radio button group
593:                  */
594:                 <?php $ns(); ?>.radioButtonValue = function(form,elt) {
595:                     for(var i=0;i<form[elt].length;i++)
596:                         if(form[elt][i].checked)
597:                             return form[elt][i].value
598:                 }
599: 
600:                 /**
601:                  * Sets the form into one of two modes: one where a simple/preset
602:                  * schedule is selected, and one in which a more complex schedule
603:                  * can be selected.
604:                  */
605:                 <?php $ns(); ?>.scheduleMode = function(form,mode) {
606:                     var allElt,i;
607:                     for(var i=0;i<<?php $ns(); ?>.schedParts.length;i++) {
608:                         allElt = <?php $ns(); ?>.schedAllNames[<?php $ns(); ?>.schedAllParts[i]];
609:                         <?php $ns(); ?>.enableField(form,allElt,!mode);
610:                         <?php $ns(); ?>.enableField(form,<?php $ns(); ?>.schedNames[<?php $ns(); ?>.schedParts[i]]+'[]',(<?php $ns(); ?>.radioButtonValue(form,allElt) == '0' && !mode));
611:                     }
612:                     form.elements[<?php $ns(); ?>.scheduleField].disabled = !mode;
613:                 }
614: 
615: 
616:                 /**
617:                  * Initializes the form, enabling/disabling inputs as appropriate
618:                  */
619:                 <?php $ns(); ?>.setup = function () {
620:                     for(var i=0;i<document.forms.length;i++) {
621:                         if(typeof document.forms[i].elements[<?php $ns(); ?>.scheduleField] != 'undefined') {
622:                             <?php $ns(); ?>.scheduleMode(document.forms[i],<?php $ns(); ?>.radioButtonValue(document.forms[i],<?php $ns(); ?>.scheduleModeField)=='1');
623:                             var schedModeButton = document.forms[i].elements[<?php $ns(); ?>.scheduleModeField];
624:                         }
625:                     }
626:                 }
627: 
628:                 // Final set-up, attempting to set forms properly:
629:                 <?php $ns(); ?>.setup();
630:             </script>
631:             </div>
632:             <br />
633:             <?php
634:             $inputs = strtr(ob_get_clean(),$inlineStyles);
635:             
636:             return $inputs;
637:         }
638: 
639:     /**
640:      *
641:      * @param type $timeField The field to be parsed
642:      * @param type $values Possible values
643:      * @return type
644:      */
645:     public static function timeList($timeField){
646:         if(is_string($timeField)) {
647:             if($timeField == '*') {
648:                 // Select none; "all" option in use
649:                 return array();
650:             } else {
651:                 return explode(',',$timeField);
652:             }
653:         } else {
654:             return $timeField;
655:         }
656:     }
657: 
658: }
659:     ?>
660: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0