.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgment:
* "This product includes software developed by the pfSense Project
* for use in the pfSense® software distribution. (http://www.pfsense.org/).
*
* 4. The names "pfSense" and "pfSense Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* coreteam@pfsense.org.
*
* 5. Products derived from this software may not be called "pfSense"
* nor may "pfSense" appear in their names without prior written
* permission of the Electric Sheep Fencing, LLC.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
*
* "This product includes software developed by the pfSense Project
* for use in the pfSense software distribution (http://www.pfsense.org/).
*
* THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
##|+PRIV
##|*IDENT=page-firewall-schedules-edit
##|*NAME=Firewall: Schedules: Edit
##|*DESCR=Allow access to the 'Firewall: Schedules: Edit' page.
##|*MATCH=firewall_schedule_edit.php*
##|-PRIV
function schedulecmp($a, $b) {
return strcmp($a['name'], $b['name']);
}
function schedule_sort() {
global $g, $config;
if (!is_array($config['schedules']['schedule'])) {
return;
}
usort($config['schedules']['schedule'], "schedulecmp");
}
require_once("guiconfig.inc");
require_once("functions.inc");
require_once("filter.inc");
require_once("shaper.inc");
$pgtitle = array(gettext("Firewall"), gettext("Schedules"), gettext("Edit"));
$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/firewall_schedule.php');
$dayArray = array (gettext('Mon'), gettext('Tues'), gettext('Wed'), gettext('Thur'), gettext('Fri'), gettext('Sat'), gettext('Sun'));
$monthArray = array (gettext('January'), gettext('February'), gettext('March'), gettext('April'), gettext('May'), gettext('June'), gettext('July'), gettext('August'), gettext('September'), gettext('October'), gettext('November'), gettext('December'));
if (!is_array($config['schedules']['schedule'])) {
$config['schedules']['schedule'] = array();
}
$a_schedules = &$config['schedules']['schedule'];
if (is_numericint($_GET['id'])) {
$id = $_GET['id'];
}
if (isset($_POST['id']) && is_numericint($_POST['id'])) {
$id = $_POST['id'];
}
if (isset($id) && $a_schedules[$id]) {
$pconfig['name'] = $a_schedules[$id]['name'];
$pconfig['descr'] = html_entity_decode($a_schedules[$id]['descr']);
$pconfig['timerange'] = $a_schedules[$id]['timerange'];
$pconfig['schedlabel'] = $a_schedules[$id]['schedlabel'];
$getSchedule = true;
}
if ($_POST) {
if (strtolower($_POST['name']) == "lan") {
$input_errors[] = gettext("Schedule may not be named LAN.");
}
if (strtolower($_POST['name']) == "wan") {
$input_errors[] = gettext("Schedule may not be named WAN.");
}
if (strtolower($_POST['name']) == "") {
$input_errors[] = gettext("Schedule name cannot be blank.");
}
if (!is_validaliasname($_POST['name'])) {
$input_errors[] = invalidaliasnamemsg($_POST['name'], gettext("schedule"));
}
/* check for name conflicts */
foreach ($a_schedules as $schedule) {
if (isset($id) && ($a_schedules[$id]) && ($a_schedules[$id] === $schedule)) {
continue;
}
if ($schedule['name'] == $_POST['name']) {
$input_errors[] = gettext("A Schedule with this name already exists.");
break;
}
}
$schedule = array();
$schedule['name'] = $_POST['name'];
$schedule['descr'] = htmlentities($_POST['descr'], ENT_QUOTES, 'UTF-8');
$timerangeFound = false;
for ($x = 0; $x < 99; $x++) {
if ($_POST['schedule' . $x]) {
if (!preg_match('/^[0-9]+:[0-9]+$/', $_POST['starttime' . $x])) {
$input_errors[] = sprintf(gettext("Invalid start time - '%s'"), $_POST['starttime' . $x]);
continue;
}
if (!preg_match('/^[0-9]+:[0-9]+$/', $_POST['stoptime' . $x])) {
$input_errors[] = sprintf(gettext("Invalid stop time - '%s'"), $_POST['stoptime' . $x]);
continue;
}
$timerangeFound = true;
$timeparts = array();
$firstprint = false;
$timestr = $_POST['schedule' . $x];
$timehourstr = $_POST['starttime' . $x];
$timehourstr .= "-";
$timehourstr .= $_POST['stoptime' . $x];
$timedescrstr = htmlentities($_POST['timedescr' . $x], ENT_QUOTES, 'UTF-8');
$dashpos = strpos($timestr, '-');
if ($dashpos === false) {
$timeparts['position'] = $timestr;
} else {
$tempindarray = array();
$monthstr = "";
$daystr = "";
$tempindarray = explode(",", $timestr);
foreach ($tempindarray as $currentselection) {
if ($currentselection) {
if ($firstprint) {
$monthstr .= ",";
$daystr .= ",";
}
$tempstr = "";
$monthpos = strpos($currentselection, "m");
$daypos = strpos($currentselection, "d");
$monthstr .= substr($currentselection, $monthpos+1, $daypos-$monthpos-1);
$daystr .= substr($currentselection, $daypos+1);
$firstprint = true;
}
}
$timeparts['month'] = $monthstr;
$timeparts['day'] = $daystr;
}
$timeparts['hour'] = $timehourstr;
$timeparts['rangedescr'] = $timedescrstr;
$schedule['timerange'][$x] = $timeparts;
}
}
if (!$timerangeFound) {
$input_errors[] = gettext("The schedule must have at least one time range configured.");
}
if (!$input_errors) {
if (!empty($pconfig['schedlabel'])) {
$schedule['schedlabel'] = $pconfig['schedlabel'];
} else {
$schedule['schedlabel'] = uniqid();
}
if (isset($id) && $a_schedules[$id]) {
$a_schedules[$id] = $schedule;
} else {
$a_schedules[] = $schedule;
}
schedule_sort();
if (write_config()) {
filter_configure();
}
header("Location: firewall_schedule.php");
exit;
}
//we received input errors, copy data to prevent retype
else {
if (!$_POST['schedule0']) {
$getSchedule = false;
} else {
$getSchedule = true;
}
$pconfig['name'] = $schedule['name'];
$pconfig['descr'] = $schedule['descr'];
$pconfig['timerange'] = $schedule['timerange'];
}
}
include("head.inc");
// Returns a string containg the HTML to display a calendar table
function build_date_table() {
$tblstr = "";
$firstmonth = TRUE;
$monthcounter = date("n");
$yearcounter = date("Y");
for ($k = 0; $k < 12; $k++) {
$firstdayofmonth = date("w", mktime(0, 0, 0, date($monthcounter), 1, date($yearcounter)));
if ($firstdayofmonth == 0) {
$firstdayofmonth = 7;
}
$daycounter = 1;
//number of day in month
$numberofdays = date("t", mktime(0, 0, 0, date($monthcounter), 1, date($yearcounter)));
$firstdayprinted = FALSE;
$lasttr = FALSE;
$positioncounter = 1;//7 for Sun, 1 for Mon, 2 for Tues, etc
$mostr = '
' . date("F_Y", mktime(0, 0, 0, date($monthcounter), 1, date($yearcounter))) . ' |
' . gettext("Mon") . ' |
' . gettext("Tue") . ' |
' . gettext("Wed") . ' |
' . gettext("Thu") . ' |
' . gettext("Fri") . ' |
' . gettext("Sat") . ' |
' . gettext("Sun") . ' |
' . "\r\n";
$firstmonth = FALSE;
while ($daycounter<=$numberofdays) {
$weekcounter = date("W", mktime(0, 0, 0, date($monthcounter), date($daycounter), date($yearcounter)));
$weekcounter = ltrim($weekcounter, "0");
if ($positioncounter == 1) {
$mostr .= "";
}
if ($firstdayofmonth == $positioncounter) {
$mostr .= '' . $daycounter . "\r\n";
$daycounter++;
$firstdayprinted = TRUE;
$mostr .= " | ";
} elseif ($firstdayprinted == TRUE && $daycounter <= $numberofdays) {
$mostr .= '' . $daycounter . "\r\n";
$daycounter++;
$mostr .= " | ";
} else {
$mostr .= ' | ';
}
if ($daycounter > $numberofdays) {
while ($positioncounter < 7) {
$mostr .= ' | ';
$positioncounter++;
}
}
if ($positioncounter == 7) {
$positioncounter = 1;
$mostr .= "
";
} else {
$positioncounter++;
}
}
$mostr .= '';
$mostr .= gettext('Click individual date to select that date only. Click the appropriate weekday Header to select all occurrences of that weekday. ');
$mostr .= '
';
if ($monthcounter == 12) {
$monthcounter = 1;
$yearcounter++;
} else {
$monthcounter++;
}
$tblstr .= $mostr;
} //end for loop
return($tblstr);
}
function build_month_list() {
$list = array();
$monthcounter = date("n");
$monthlimit = $monthcounter + 12;
$yearcounter = date("Y");
for ($k = 0; $k < 12; $k++) {
$list[$monthcounter] = date("F_y", mktime(0, 0, 0, date($monthcounter), 1, date($yearcounter)));
if ($monthcounter == 12) {
$monthcounter = 1;
$yearcounter++;
} else {
$monthcounter++;
}
}
return($list);
}
if ($input_errors) {
print_input_errors($input_errors);
}
$form = new Form();
$section = new Form_Section('Schedule Information');
$input = new Form_Input(
'name',
'Schedule Name',
'text',
$pconfig['name']
);
$input->setHelp((is_schedule_inuse($pconfig['name']) != true) ? 'The name of the schedule may only consist of the characters "a-z, A-Z, 0-9 and _".':
'This schedule is in use so the name may not be modified!');
if (is_schedule_inuse($pconfig['name']) == true) {
$input->setReadonly();
}
$section->addInput($input);
$section->addInput(new Form_Input(
'descr',
'Description',
'text',
$pconfig['descr']
))->setHelp('A description may be entered here for administrative reference (not parsed). ');
$section->addInput(new Form_Select(
'monthsel',
'Month',
null,
build_month_list()
));
$section->addInput(new Form_StaticText(
'Date',
build_date_table()
));
$group = new Form_Group('Time');
$group->add(new Form_Select(
'starttimehour',
null,
null,
array_combine(range(0, 23, 1), range(0, 23, 1))
))->setHelp('Start Hrs');
$group->add(new Form_Select(
'starttimemin',
null,
null,
array('00' => '00', '15' => '15', '30' => '30', '45' => '45', '59' => '59')
))->setHelp('Start Mins');
$group->add(new Form_Select(
'stoptimehour',
null,
'23',
array_combine(range(0, 23, 1), range(0, 23, 1))
))->setHelp('Stop Hrs');
$group->add(new Form_Select(
'stoptimemin',
null,
'59',
array('00' => '00', '15' => '15', '30' => '30', '45' => '45', '59' => '59')
))->setHelp('Stop Mins');
$group->setHelp('Select the time range for the day(s) selected on the Month(s) above. A full day is 0:00-23:59.');
$section->add($group);
$section->addInput(new Form_Input(
'timerangedescr',
'Time range description',
'text',
$pconfig['timerangedescr']
))->setHelp('A description may be entered here for administrative reference (not parsed). ');
$group = new Form_Group(null);
$group->add(new Form_Button(
'btnaddtime',
'Add Time',
null,
'fa-plus'
))->setAttribute('type','button')->addClass('btn-success btn-sm');
$group->add(new Form_Button(
'btnclrsel',
'Clear selection',
null,
'fa-undo'
))->setAttribute('type','button')->addClass('btn-info btn-sm');
$section->add($group);
if (isset($id) && $a_schedules[$id]) {
$section->addInput(new Form_Input(
'id',
null,
'hidden',
$id
));
}
$form->add($section);
$section = new Form_Section('Configured Ranges');
$counter = 0;
if ($getSchedule) {
$maxrows = count($pconfig['timerange']) -1;
foreach ($pconfig['timerange'] as $timerange) {
$tempFriendlyTime = "";
$tempID = "";
if ($timerange) {
$dayFriendly = "";
$tempFriendlyTime = "";
$timedescr = $timerange['rangedescr'];
//get hours
$temptimerange = $timerange['hour'];
$temptimeseparator = strrpos($temptimerange, "-");
$starttime = substr ($temptimerange, 0, $temptimeseparator);
$stoptime = substr ($temptimerange, $temptimeseparator+1);
$currentDay = "";
$firstDay = "";
$nextDay = "";
$foundEnd = false;
$firstDayFound = false;
$firstPrint = false;
$firstprint2 = false;
if ($timerange['month']) {
$tempmontharray = explode(",", $timerange['month']);
$tempdayarray = explode(",", $timerange['day']);
$arraycounter = 0;
foreach ($tempmontharray as $monthtmp) {
$month = $tempmontharray[$arraycounter];
$day = $tempdayarray[$arraycounter];
$daypos = date("w", mktime(0, 0, 0, date($month), date($day), date("Y")));
//if sunday, set position to 7 to get correct week number. This is due to php limitations on ISO-8601. When we move to php5.1 we can change this.
if ($daypos == 0) {
$daypos = 7;
}
$weeknumber = date("W", mktime(0, 0, 0, date($month), date($day), date("Y")));
$weeknumber = ltrim($weeknumber, "0");
if ($firstPrint) {
$tempID .= ",";
}
$tempID .= "w" . $weeknumber . "p" . $daypos . "-m" . $month . "d" . $day;
$firstPrint = true;
if (!$firstDayFound) {
$firstDay = $day;
$firstmonth = $month;
$firstDayFound = true;
}
$currentDay = $day;
$nextDay = $tempdayarray[$arraycounter+1];
$currentDay++;
if (($currentDay != $nextDay) || ($tempmontharray[$arraycounter] != $tempmontharray[$arraycounter+1])) {
if ($firstprint2) {
$tempFriendlyTime .= ", ";
}
$currentDay--;
if ($currentDay != $firstDay) {
$tempFriendlyTime .= $monthArray[$firstmonth-1] . " " . $firstDay . " - " . $currentDay ;
} else {
$tempFriendlyTime .= $monthArray[$month-1] . " " . $day;
}
$firstDayFound = false;
$firstprint2 = true;
}
$arraycounter++;
}
} else {
$dayFriendly = $timerange['position'];
$tempID = $dayFriendly;
}
$tempTime = $tempID . "||" . $starttime . "-" . $stoptime . "||" . $timedescr;
//following code makes the days friendly appearing, IE instead of Mon, Tues, Wed it will show Mon - Wed
$foundEnd = false;
$firstDayFound = false;
$firstprint = false;
$tempFriendlyDayArray = explode(",", $dayFriendly);
$currentDay = "";
$firstDay = "";
$nextDay = "";
$i = 0;
if (!$timerange['month']) {
foreach ($tempFriendlyDayArray as $day) {
if ($day != "") {
if (!$firstDayFound) {
$firstDay = $tempFriendlyDayArray[$i];
$firstDayFound = true;
}
$currentDay =$tempFriendlyDayArray[$i];
//get next day
$nextDay = $tempFriendlyDayArray[$i+1];
$currentDay++;
if ($currentDay != $nextDay) {
if ($firstprint) {
$tempFriendlyTime .= ", ";
}
$currentDay--;
if ($currentDay != $firstDay) {
$tempFriendlyTime .= $dayArray[$firstDay-1] . " - " . $dayArray[$currentDay-1];
} else {
$tempFriendlyTime .= $dayArray[$firstDay-1];
}
$firstDayFound = false;
$firstprint = true;
}
$i++;
}
}
}
$group = new Form_Group('');
$group->add(new Form_Input(
'tempFriendlyTime' . $counter,
null,
'text',
$tempFriendlyTime
))->setWidth(2)->setReadonly()->setHelp($counter == $maxrows ? 'Day(s)':'');
$group->add(new Form_Input(
'starttime' . $counter,
null,
'text',
$starttime
))->setWidth(2)->setReadonly()->setHelp($counter == $maxrows ? 'Start time':'');
$group->add(new Form_Input(
'stoptime' . $counter,
null,
'text',
$stoptime
))->setWidth(2)->setReadonly()->setHelp($counter == $maxrows ? 'Stop time':'');
$group->add(new Form_Input(
'timedescr' . $counter,
null,
'text',
$timedescr
))->setWidth(2)->setHelp($counter == $maxrows ? 'Description':'');
$group->add(new Form_Button(
'Delete' . $counter,
'Delete',
null,
'fa-trash'
))->setAttribute('type','button')->addClass('btn-xs btn-warning');
$group->add(new Form_Input(
'schedule' . $counter,
null,
'hidden',
$tempID
));
$group->addClass('schedulegrp' . $counter);
$counter++;
$section->add($group);
}
}
}
// This is just a marker that the javascript can use to insertBefore() when adding new rows
$section->addInput(new Form_Input(
'marker',
null,
'hidden'
))->addClass('noranges');
$form->add($section);
print($form);
?>