function displayCalendar($formframes, $mainforms = "", $viewHandles, $dateHandles, $filters, $viewPrefixes, $scopes, $hidden, $type = "month", $start = "", $multiPageData = "") { global $xoopsDB, $xoopsUser; global $xoopsTpl; // Set some required variables $mid = getFormulizeModId(); for ($i = 0; $i < count($formframes); $i++) { unset($fid); unset($frid); if ($mainforms[$i]) { list($fid, $frid) = getFormFramework($formframes[$i], $mainforms[$i]); } else { list($fid, $frid) = getFormFramework($formframes[$i]); } $fids[] = $fid; $frids[] = $frid; } $gperm_handler =& xoops_gethandler('groupperm'); $member_handler =& xoops_gethandler('member'); $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); $uid = $xoopsUser ? $xoopsUser->getVar('uid') : 0; foreach ($fids as $thisFid) { // check that the user is allowed to see all the fids if (!($scheck = security_check($thisFid, "", $uid, "", $groups, $mid, $gperm_handler))) { print "<p>" . _NO_PERM . "</p>"; return; } } $currentURL = getCurrentURL(); // get the current view, ie: the month if ($_POST['calview']) { // if we're recieving a view from a form submission... $settings['calview'] = $_POST['calview']; } else { if (!$start) { // nothing passed from form, and no default value specified, so use current date $today = getDate(); if ($today['mon'] < 10) { $today['mon'] = "0" . $today['mon']; } $settings['calview'] = $today['year'] . "-" . $today['mon']; } else { $settings['calview'] = $start; } } $settings['calfrid'] = $_POST['calfrid']; $settings['calfid'] = $_POST['calfid']; $settings['calhidden'] = $hidden; // check to see if a switch to a form has been requested $settings['ventry'] = $_POST['ventry']; if ($settings['ventry']) { if ($_POST['ventry'] == "addnew") { $this_ent = ""; $dateOverride = $_POST['adddate']; } elseif ($_POST['ventry'] == "proxy") { // support for proxies not currently written $this_ent = "proxy"; } else { $this_ent = $_POST['ventry']; } if ($_POST['calfrid']) { if (isset($multiPageData[$_POST['calfid']])) { if (is_numeric($multiPageData[$_POST['calfid']])) { // numeric value indicates a screen id $screenData = readScreenId($multiPageData[$_POST['calfid']], $_POST['calfid']); if (is_array($screenData)) { $multiPageData = $screenData; } } include_once XOOPS_ROOT_PATH . "/modules/formulize/include/formdisplaypages.php"; displayFormPages($_POST['calfrid'], $this_ent, $_POST['calfid'], $multiPageData[$_POST['calfid']]['pages'], $multiPageData[$_POST['calfid']]['conditions'], $multiPageData[$_POST['calfid']]['introtext'], $multiPageData[$_POST['calfid']]['thankstext'], $currentURL, _formulize_CAL_RETURNFROMMULTI, $settings, $dateOverride, $multiPageData[$_POST['calfid']]['printall']); } else { displayForm($_POST['calfrid'], $this_ent, $_POST['calfid'], $currentURL, "", $settings, "", $dateOverride, 1, 1); // first "" is the done text, second is the onetoonetitles, last two 1s are the overrides for multi form behaviour } return; } else { if (isset($multiPageData[$_POST['calfid']])) { if (is_numeric($multiPageData[$_POST['calfid']])) { // numeric value indicates a screen id $screenData = readScreenId($multiPageData[$_POST['calfid']], $_POST['calfid']); if (is_array($screenData)) { $multiPageData = $screenData; } } include_once XOOPS_ROOT_PATH . "/modules/formulize/include/formdisplaypages.php"; displayFormPages($_POST['calfid'], $this_ent, "", $multiPageData[$_POST['calfid']]['pages'], $multiPageData[$_POST['calfid']]['conditions'], $multiPageData[$_POST['calfid']]['introtext'], $multiPageData[$_POST['calfid']]['thankstext'], $currentURL, _formulize_CAL_RETURNFROMMULTI, $settings, $dateOverride, $multiPageData[$_POST['calfid']]['printall']); } else { displayForm($_POST['calfid'], $this_ent, "", $currentURL, "", $settings, "", $dateOverride, 1, 1); // "" is the done text } return; } } // handle deletion if requested, added sept 18 2005 if ($_POST['delentry']) { deleteEntry($_POST['delentry'], $_POST['delfrid'], $_POST['delfid'], $gperm_handler, $member_handler, $mid); } // get the data for all the fids // 1. convert the scopes for each one // 2. do the extraction (filter by calview) include_once XOOPS_ROOT_PATH . "/modules/formulize/include/extract.php"; for ($i = 0; $i < count($fids); $i++) { $scope = ""; if ($scopes[$i]) { list($scope, $throwAwayCurrentView) = buildScope($scopes[$i], $member_handler, $gperm_handler, $uid, $groups, $fids[$i], $mid); } if (is_array($dateHandles[$i])) { $dateField = $dateHandles[$i][0]; $dateField2 = $dateHandles[$i][1]; } else { $dateField = $dateHandles[$i]; $dateField2 = ""; } if (!$frids[$i]) { $filterDH = $dateField; $filterDH2 = $dateField2; } else { $filterDH = $dateField; $filterDH2 = $dateField2; } // new, complex filter format is: // $filter[0][0] -- andor setting for filter 0 // $filter[0][1] -- filter for filter 0 $filter = array(); $filter[0][0] = "OR"; $filter[0][1] = $filterDH . "/**/" . $settings['calview']; if ($filterDH2) { $filter[0][1] .= "][" . $filterDH2 . "/**/" . $settings['calview']; } if ($filters[$i]) { $filter[1][0] = "AND"; $filter[1][1] = $filters[$i]; } $data[$i] = getData($frids[$i], $fids[$i], $filter, "AND", $scope); $data[$i] = resultSort($data[$i], $dateField); } // need the formatting magic to go here, to whip it all into a nice calendar // basic display of data is below // demonstrates linking to a form for updating/viewing that entry // demonstrates altering the calview setting to change months // need to do something a little more complex for adding a new entry, since we have to know for which fid/frid pair the add operation is being requested. // probably best to leave out adding for now and leave it as a future feature. It can always be custom added within a pageworks page if necessary for a particular calendar $rights = $gperm_handler->checkRight("add_own_entry", $fid, $groups, $mid); // information to pass to the template global $calendarData; // initialize language constants global $arrayMonthNames; global $arrayWeekNames; global $dateMonthStartDay; $arrayMonthNames = array(_formulize_CAL_MONTH_01, _formulize_CAL_MONTH_02, _formulize_CAL_MONTH_03, _formulize_CAL_MONTH_04, _formulize_CAL_MONTH_05, _formulize_CAL_MONTH_06, _formulize_CAL_MONTH_07, _formulize_CAL_MONTH_08, _formulize_CAL_MONTH_09, _formulize_CAL_MONTH_10, _formulize_CAL_MONTH_11, _formulize_CAL_MONTH_12); if ($type == "mini_month") { $arrayWeekNames = array(_formulize_CAL_WEEK_1_3ABRV, _formulize_CAL_WEEK_2_3ABRV, _formulize_CAL_WEEK_3_3ABRV, _formulize_CAL_WEEK_4_3ABRV, _formulize_CAL_WEEK_5_3ABRV, _formulize_CAL_WEEK_6_3ABRV, _formulize_CAL_WEEK_7_3ABRV); } else { $arrayWeekNames = array(_formulize_CAL_WEEK_1, _formulize_CAL_WEEK_2, _formulize_CAL_WEEK_3, _formulize_CAL_WEEK_4, _formulize_CAL_WEEK_5, _formulize_CAL_WEEK_6, _formulize_CAL_WEEK_7); } // convert string date into parts $arrayDate = getdate(strtotime($settings['calview'] . "-01")); $dateMonth = $arrayDate["mon"]; $dateDay = $arrayDate["mday"]; $dateYear = $arrayDate["year"]; // get the number of days in the month. $dateMonthDays = days_in_month($dateMonth, $dateYear); // get the month's first week start day. $dateMonthStartDay = $arrayDate["wday"]; // get the number of weeks. $dateMonthWeeks = week_in_month($dateMonthDays) + 1; // intialize MONTH template information // each cell is an array: // [0] - is control information, where each entry is an array: // [0] - day number // [1] - send date // [1] - is an array containing all items, where each item is also an array: // [0] - $ids[0] // [1] - $frids[$i] // [2] - $fids[$i] // [3] - $textToDisplay // [4] - true/false based on user's right to delete this item (based on either delete own, or delete others permission) if ($type == "month" || $type == "mini_month" || $type == "micro_month") { // initialize grid: convert the data set into a grid of 7 columns for // days and a row for each week $displayDay = ""; for ($intWeeks = 0; $intWeeks < $dateMonthWeeks; $intWeeks++) { $calendarData[$intWeeks] = array(); for ($intDays = 0; $intDays < 7; $intDays++) { // check to see if the processing day is the start day. if ($intWeeks == 0 && $displayDay == "") { if ($intDays == $dateMonthStartDay) { $displayDay = 1; } } else { if ($displayDay != "") { $displayDay++; if ($displayDay > $dateMonthDays) { $displayDay = ""; } } } $calendarData[$intWeeks][$intDays] = array(); $calendarData[$intWeeks][$intDays][0][0] = $displayDay; $calendarData[$intWeeks][$intDays][0][1] = $dateYear . "-" . $dateMonth . "-" . ($displayDay < 10 ? "0" . $displayDay : $displayDay); //$calendarData[$intWeeks][$intDays][1] = array(); } } // Initialize template variables $xoopsTpl->assign('previousMonth', $dateMonth - 1 < 1 ? $dateYear - 1 . "-12" : $dateYear . "-" . ($dateMonth - 1 < 10 ? "0" . ($dateMonth - 1) : $dateMonth - 1)); $xoopsTpl->assign('nextMonth', $dateMonth + 1 > 12 ? $dateYear + 1 . "-01" : $dateYear . "-" . ($dateMonth + 1 < 10 ? "0" . ($dateMonth + 1) : $dateMonth + 1)); $monthSelector = array(); $numberOfMonths = count($arrayMonthNames); for ($intMonth = 0; $intMonth < $numberOfMonths; $intMonth++) { $monthName = $arrayMonthNames[$intMonth]; $monthSelector[$intMonth + 1 < 10 ? "0" . ($intMonth + 1) : $intMonth + 1] = $monthName; } $xoopsTpl->assign('monthSelector', $monthSelector); $yearSelector = array(); $startYear = $dateYear - 4; $endYear = $dateYear + 3; for ($intYear = $startYear; $intYear <= $endYear; $intYear++) { $yearSelector[] = $intYear; } $xoopsTpl->assign('yearSelector', $yearSelector); } // process data set(s) for ($i = 0; $i < count($data); $i++) { foreach ($data[$i] as $id => $entry) { if (!$frids[$i]) { if (is_array($viewHandles[$i])) { $formhandle = getFormHandleFromEntry($entry, $viewHandles[$i][0]); } else { $formhandle = getFormHandleFromEntry($entry, $viewHandles[$i]); } } else { $formhandle = $mainforms[$i]; } $ids = internalRecordIds($entry, $formhandle); if (is_array($viewHandles[$i])) { $needsep = 0; // make sure that no data is keep from previous processing $textToDisplay = ""; foreach ($viewHandles[$i] as $thisVH) { if ($needsep) { $textToDisplay .= ", "; } $needsep = 1; $textToDisplay .= display($entry, $thisVH); } } else { $textToDisplay = display($entry, $viewHandles[$i]); } if ($viewPrefixes[$i]) { $textToDisplay = $viewPrefixes[$i] . $textToDisplay; } $calendarDataItem = array(); $calendarDataItem[0] = $ids[0]; $calendarDataItem[1] = $frids[$i]; $calendarDataItem[2] = $fids[$i]; $calendarDataItem[3] = $textToDisplay; $calendarDataItem[4] = ($i == 0 and formulizePermHandler::user_can_delete_entry($fids[$i], display($entry, "uid"), $ids[0])); if ($type == "month" || $type == "mini_month" || $type == "micro_month") { if (is_array($dateHandles[$i])) { $startValue = display($entry, $dateHandles[$i][0]); $endValue = display($entry, $dateHandles[$i][1]); if ($startValue && $endValue) { $startDate = strtotime($startValue); $endDate = strtotime($endValue); for ($x = $startDate; $x <= $endDate; $x = $x + 86400) { $arrayDate = getdate($x); if ($arrayDate["mon"] == $dateMonth) { $calendarData = assignItem($arrayDate, $calendarDataItem, $calendarData); } } } else { if ($startValue) { $startDate = strtotime($startValue); $arrayDate = getdate($startDate); $calendarData = assignItem($arrayDate, $calendarDataItem, $calendarData); } else { $endDate = strtotime($endValue); $arrayDate = getdate($endDate); $calendarData = assignItem($arrayDate, $calendarDataItem, $calendarData); } } } else { $currentDate = display($entry, $dateHandles[$i]); $arrayDate = getdate(strtotime($currentDate)); $calendarData = assignItem($arrayDate, $calendarDataItem, $calendarData); } } } } // Initialize common template variables $xoopsTpl->assign('cal_type', $type); $xoopsTpl->assign('rights', $rights); $xoopsTpl->assign('frids', $frids[0]); $xoopsTpl->assign('fids', $fids[0]); $xoopsTpl->assign('addItem', _formulize_CAL_ADD_ITEM); $xoopsTpl->assign('rowStyleEven', true); $xoopsTpl->assign('MonthNames', $arrayMonthNames); $xoopsTpl->assign('WeekNames', $arrayWeekNames); $xoopsTpl->assign('dateMonthZeroIndex', $dateMonth - 1); $xoopsTpl->assign('dateMonth', $dateMonth); $xoopsTpl->assign('dateYear', $dateYear); $xoopsTpl->assign('currentURL', $currentURL); $xoopsTpl->assign('hidden', $hidden); $xoopsTpl->assign('calview', $settings['calview']); $xoopsTpl->assign('calendarData', $calendarData); $xoopsTpl->assign('delete', _formulize_DELETE); $xoopsTpl->assign('delconf', _formulize_DELCONF); // force template to be drawn $xoopsTpl->display("db:calendar_" . $type . ".html"); }
function formulize_getCalcs($formframe, $mainform, $savedView, $handle = "all", $type = "all", $grouping = "all") { list($fid, $frid) = getFormFramework($formframe, $mainform); static $cachedResults = array(); if (!isset($cachedResults[$frid][$fid][$savedView])) { include_once XOOPS_ROOT_PATH . "/modules/formulize/include/entriesdisplay.php"; foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_") { unset($_POST[$k]); } } // load the saved view requested, and get everything ready for calling gatherDataSet list($_POST['currentview'], $_POST['oldcols'], $_POST['asearch'], $_POST['calc_cols'], $_POST['calc_calcs'], $_POST['calc_blanks'], $_POST['calc_grouping'], $_POST['sort'], $_POST['order'], $_POST['hlist'], $_POST['hcalc'], $_POST['lockcontrols'], $quicksearches) = loadReport($savedView, $fid, $frid); // must check for this and set it here, inside this section, where we know for sure that $_POST['lockcontrols'] has been set based on the database value for the saved view, and not anything else sent from the user!!! Otherwise the user might be injecting a greater scope for themselves than they should have! $currentViewCanExpand = $_POST['lockcontrols'] ? false : true; // explode quicksearches into the search_ values $allqsearches = explode("&*=%4#", $quicksearches); $colsforsearches = explode(",", $_POST['oldcols']); for ($i = 0; $i < count($allqsearches); $i++) { if ($allqsearches[$i] != "") { // need to remove the hiddencolumn indicator if it is present $_POST["search_" . str_replace("hiddencolumn_", "", $colsforsearches[$i])] = $allqsearches[$i]; if (strstr($colsforsearches[$i], "hiddencolumn_")) { unset($colsforsearches[$i]); // remove columns that were added to the column list just so we would know the name of the hidden searches } } } foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and $v != "") { $thiscol = substr($k, 7); $searches[$thiscol] = $v; } } global $xoopsUser; $mid = getFormulizeModId(); $gperm_handler =& xoops_gethandler('groupperm'); $member_handler =& xoops_gethandler('member'); $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); $uid = $xoopsUser ? $xoopsUser->getVar('uid') : "0"; list($scope, $throwAwayCurrentView) = buildScope($_POST['currentview'], $member_handler, $gperm_handler, $uid, $groups, $fid, $mid, $currentViewCanExpand); // by calling this, we will set the base query that needs to be used in order to generate the calculations // special flag is used to force return once base query is set $GLOBALS['formulize_returnAfterSettingBaseQuery'] = true; formulize_gatherDataSet(array(), $searches, "", "", $frid, $fid, $scope); unset($GLOBALS['formulize_returnAfterSettingBaseQuery']); $ccols = explode("/", $_POST['calc_cols']); $ccalcs = explode("/", $_POST['calc_calcs']); // need to add in proper handling of long calculation results, like grouping percent breakdowns that result in many, many rows. foreach ($ccalcs as $onecalc) { $thesecalcs = explode(",", $onecalc); if (!is_array($thesecalcs)) { $thesecalcs[0] = ""; } $totalalcs = $totalcalcs + count($thesecalcs); } $cblanks = explode("/", $_POST['calc_blanks']); $cgrouping = explode("/", $_POST['calc_grouping']); //formulize_benchmark("before performing calcs"); $cachedResults[$frid][$fid][$savedView] = performCalcs($ccols, $ccalcs, $cblanks, $cgrouping, $frid, $fid); } $calcResults = $cachedResults[$frid][$fid][$savedView]; // individual handle requested, so convert to array $origHandle = $handle; if ($handle != "all" and !is_array($handle)) { $handles[0] = $handle; } elseif (is_array($handle)) { $handles = $handle; } else { // all the handles in the result array $handles = array_keys($calcResults[0]); } foreach ($handles as $handle) { if ($grouping != "all") { $groupingTypeMap = array(); foreach ($calcResults[3][$handle] as $groupType => $values) { if ($groupType == $type or $type == "all") { foreach ($values as $groupingId => $theseValues) { if (array_search($grouping, $theseValues) !== false) { // this is a grouping selection for this type that we need to return $groupingTypeMap[$groupType][$groupingId] = true; } } } } } $indexer = 0; foreach ($calcResults[0][$handle] as $calcType => $results) { if ($type == $calcType or $type == "all") { foreach ($results as $groupingId => $thisResult) { if (isset($groupingTypeMap[$calcType][$groupingId]) or $grouping == "all") { $resultArray[$handle][$calcType][$indexer]['result'] = $thisResult; $resultArray[$handle][$calcType][$indexer]['grouping'] = $calcResults[3][$handle][$calcType][$groupingId]; $indexer++; } } } } } return $resultArray; // multiple handles requested so return everything }
/** * @param $fid * @param $newfid */ public function setPermissionsForClonedForm($fid, $newfid) { // replicate permissions of the original form on the new cloned form $criteria = new CriteriaCompo(); $criteria->add(new Criteria('gperm_itemid', $fid), 'AND'); $criteria->add(new Criteria('gperm_modid', getFormulizeModId()), 'AND'); $gperm_handler = xoops_gethandler('groupperm'); $oldFormPerms = $gperm_handler->getObjects($criteria); foreach ($oldFormPerms as $thisOldPerm) { // do manual inserts, since addRight uses the xoopsDB query method, which won't do updates/inserts on GET requests $sql = "INSERT INTO " . $this->db->prefix("group_permission") . " (gperm_name, gperm_itemid, gperm_groupid, gperm_modid) VALUES ('" . $thisOldPerm->getVar('gperm_name') . "', {$newfid}, " . $thisOldPerm->getVar('gperm_groupid') . ", " . getFormulizeModId() . ")"; $res = $this->db->queryF($sql); } }
print "/* eval */ reloadWithScrollPosition()"; } else { print "Error: this form is locked!"; } } // if deletion requested and the user has permission for that if (isset($_POST['deleteapp']) and $_POST['deleteapp'] > 0) { $application_handler = xoops_getmodulehandler('applications', 'formulize'); $application_handler->delete(intval($_POST['deleteapp'])); print "/* evalnow */ reloadWithScrollPosition()"; } if (isset($_POST['cloneform']) and $_POST['cloneform'] > 0 or isset($_POST['cloneformdata']) and $_POST['cloneformdata'] > 0) { $formToClone = (isset($_POST['cloneform']) and $_POST['cloneform'] > 0) ? intval($_POST['cloneform']) : intval($_POST['cloneformdata']); $cloneData = (isset($_POST['cloneform']) and $_POST['cloneform'] > 0) ? false : true; $form_handler = xoops_getmodulehandler('forms', 'formulize'); $form_handler->cloneForm($formToClone, $cloneData); print "/* evalnow */ reloadWithScrollPosition()"; } if (isset($_POST['lockdown']) and $_POST['lockdown'] > 0 and $gperm_handler->checkRight("delete_form", intval($_POST['lockdown']), $xoopsUser->getGroups(), getFormulizeModId())) { $form_handler = xoops_getmodulehandler('forms', 'formulize'); $formObject = $form_handler->get($_POST['lockdown']); if (!$formObject->getVar('lockedform')) { if (!$form_handler->lockForm(intval($_POST['lockdown']))) { print "Error: could not lock the form"; } else { print "/* evalnow */ reloadWithScrollPosition()"; } } else { print "Error: this form is locked!"; } }
############################################################################### ## Author of this file: Freeform Solutions ## ## URL: http://www.freeformsolutions.ca/formulize ## ## Project: Formulize ## ############################################################################### // this file gets all the data about elements, so we can display the tabs for elements include_once XOOPS_ROOT_PATH . "/modules/formulize/include/functions.php"; // this file contains objects to retrieve screen(s) information for elements include_once XOOPS_ROOT_PATH . "/modules/formulize/class/formScreen.php"; // need to listen for $_GET['aid'] later so we can limit this to just the application that is requested $aid = intval($_GET['aid']); $application_handler = xoops_getmodulehandler('applications', 'formulize'); $form_handler = xoops_getmodulehandler('forms', 'formulize'); $element_handler = xoops_getmodulehandler('elements', 'formulize'); $config_handler = $config_handler =& xoops_gethandler('config'); $formulizeConfig =& $config_handler->getConfigsByCat(0, getFormulizeModId()); if ($aid == 0) { $appName = "Forms with no app"; } else { $appObject = $application_handler->get($aid); $appName = $appObject->getVar('name'); } $names = array(); $display = array(); $advanced = array(); $member_handler = xoops_gethandler('member'); $allGroups = $member_handler->getGroups(); $groups = array(); foreach ($allGroups as $thisGroup) { $groups[$thisGroup->getVar('name')]['id'] = $thisGroup->getVar('groupid'); $groups[$thisGroup->getVar('name')]['name'] = $thisGroup->getVar('name');
function formulize_setupPreviousEntryUI($screen, $element_id, $type, $owner, $de = false, $entryId = "", $ele_handle, $fid) { // 1. need to get and cache the values of the entry for this screen // 2. need to put the values into a dropdown list with an onchange event that populates the actual form element // this should be cached in some other way, since every instance of the renderer will need to cache this. If it were a GLOBAL or this whole thing were in some other function, that would work. static $cachedEntries = array(); if (!isset($cachedEntries[$screen->getVar('sid')])) { // identify the entry belonging to this user's group(s) in the other form. Currently only group correspondence is supported. global $xoopsUser; $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); $member_handler =& xoops_gethandler('member'); $gperm_handler =& xoops_gethandler('groupperm'); $mid = getFormulizeModId(); $owner_groups =& $member_handler->getGroupsByUser($owner, FALSE); // in this particular case, it's okay to make the owner_groups based on the users's memberships, since we want to present the single entry that belongs to whichever groups the user is a member of...I think. :-) $singleData = getSingle($screen->getVar('paraentryform'), $owner, $owner_groups, $member_handler, $gperm_handler, $mid); if ($singleData['flag'] == "group" and $singleData['entry'] > 0) { // only proceed if there is a one-entry-per-group situation in the target form formulize_benchmark("Ready to do previous entry query."); $cachedEntries[$screen->getVar('sid')] = getData("", $screen->getVar('paraentryform'), $singleData['entry']); formulize_benchmark("Done query."); } else { return ""; } } $entries = $cachedEntries[$screen->getVar('sid')]; // big assumption below is corresponding captions. In future there will be more ad hoc ways of describing which elements align to which other ones. // 1. figure out the corresponding element ID based on matching captions // 2. grab the previous value from the $entry/entries // 3. create the dropdown list with these values, including javascript $formHandler =& xoops_getmodulehandler('forms', 'formulize'); $currentForm = $formHandler->get($screen->getVar('fid')); $previousForm = $formHandler->get($screen->getVar('paraentryform')); $currentCaptions = $currentForm->getVar('elementCaptions'); $captionToMatch = $currentCaptions[$ele_handle]; $previousCaptions = $previousForm->getVar('elementCaptions'); $previousElementHandle = array_search($captionToMatch, $previousCaptions); if (!$previousElementHandle) { return ""; } $elementName = $de ? "de_" . $fid . "_" . $entryId . "_" . $element_id : "ele_" . $element_id; // displayElement elements have different names from regular elements $previousElementId = formulize_getIdFromElementHandle($previousElementHandle); // function is in extract.php // setup the javascript based on the type of question, and setup other data that is required switch ($type) { case "text": case "date": $javascript = "onchange='javascript:this.form." . $elementName . ".value=this.form.prev_" . $element_id . ".value;'"; break; case "radio": // need to get the options of the question so we know what to match $prevElementMetaData = formulize_getElementMetaData($previousElementId); // use this function in extract instead of the get element method in handler, since this is guaranteed to be already be cached in memory $prevElement_ele_value = unserialize($prevElementMetaData['ele_value']); $prevElementOptions = array_keys($prevElement_ele_value); $javascript = "onchange='javascript:if(this.form.prev_" . $element_id . ".value !== \"\") { this.form." . $elementName . "[this.form.prev_" . $element_id . ".value].checked=true; }'"; break; case "yn": $javascript = "onchange='javascript:if(this.form.prev_" . $element_id . ".value !== \"\") { this.form." . $elementName . "[this.form.prev_" . $element_id . ".value].checked=true; }'"; break; } $previousOptions = array(); $prevOptionsExist = false; foreach ($entries as $id => $entry) { $value = htmlspecialchars(strip_tags(display($entry, $previousElementHandle))); if (is_array($value)) { $value = printSmart(implode(", ", $value)); } if (trim($value) === "" or trim($value) == "0000-00-00") { continue; } $prevOptionsExist = true; switch ($type) { case "text": case "date": $previousOptions[$value] = $value; break; case "radio": $prevElementPosition = array_search($value, $prevElementOptions); // need to figure out which option matches the text of the value if ($prevElementPosition !== false) { $previousOptions[$prevElementPosition] = $value; // for radio buttons, we need to pass the position of the option } break; case "yn": if ($value == _formulize_TEMP_QYES) { $previousOptions[0] = $value; } elseif ($value == _formulize_TEMP_QNO) { $previousOptions[1] = $value; } break; } } if (!$prevOptionsExist) { return ""; } $prevUI = new xoopsFormSelect('', 'prev_' . $element_id, '123qweasdzxc', 1, false); // 123qweasdzxc is meant to be a unique value that will never be selected, since we don't ever want a previous selection showing by default $prevUI->addOption('', _AM_FORMULIZE_PREVIOUS_OPTION); $prevUI->addOptionArray($previousOptions); $prevUI->setExtra($javascript); return $prevUI; }
function render($ele_value, $caption, $markupName, $isDisabled, $element, $entry_id) { global $xoopsDB, $xoopsUser, $myts; $renderer = new formulizeElementRenderer(); $form_handler = xoops_getmodulehandler('forms', 'formulize'); $id_form = $element->getVar('id_form'); if ($entry_id != "new") { $owner = getEntryOwner($entry_id, $id_form); } else { $owner = $xoopsUser ? $xoopsUser->getVar('uid') : 0; } $formObject = $form_handler->get($id_form); $isDisabled = false; if (strstr(getCurrentURL(), "printview.php")) { $isDisabled = true; // disabled all elements if we're on the printable view } $ele_desc = $element->getVar('ele_desc', "f"); if (strstr($ele_value[2], "#*=:*")) { // if we've got a link on our hands... -- jwe 7/29/04 // new process for handling links...May 10 2008...new datastructure for formulize 3.0 $boxproperties = explode("#*=:*", $ele_value[2]); $sourceFid = $boxproperties[0]; $sourceHandle = $boxproperties[1]; $sourceEntryIds = explode(",", trim($boxproperties[2], ",")); // grab the user's groups and the module id global $regcode; if ($regcode) { // if we're dealing with a registration code, determine group membership based on the code $reggroupsq = q("SELECT reg_codes_groups FROM " . XOOPS_DB_PREFIX . "_reg_codes WHERE reg_codes_code=\"{$regcode}\""); $groups = explode("&8(%\$", $reggroupsq[0]['reg_codes_groups']); if ($groups[0] === "") { unset($groups); } // if a code has no groups associated with it, then kill the null value that will be in position 0 in the groups array. $groups[] = XOOPS_GROUP_USERS; $groups[] = XOOPS_GROUP_ANONYMOUS; } else { $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); } $module_id = getFormulizeModId(); $pgroups = array(); // handle new linkscope option -- August 30 2006 $emptylist = false; if ($ele_value[3]) { $scopegroups = explode(",", $ele_value[3]); if (!in_array("all", $scopegroups)) { if ($ele_value[4]) { // limit by user's groups foreach ($groups as $gid) { // want to loop so we can get rid of reg users group simply if ($gid == XOOPS_GROUP_USERS) { continue; } if (in_array($gid, $scopegroups)) { $pgroups[] = $gid; } } } else { // just use scopegroups $pgroups = $scopegroups; } if (count($pgroups) == 0) { // specific scope was specified, and nothing found, so we should show nothing $emptylist = true; } } else { if ($ele_value[4]) { // all groups selected, but limiting by user's groups is turned on foreach ($groups as $gid) { // want to loop so we can get rid of reg users group simply if ($gid == XOOPS_GROUP_USERS) { continue; } $pgroups[] = $gid; } } else { // all groups should be used unset($pgroups); $allgroupsq = q("SELECT groupid FROM " . $xoopsDB->prefix("groups")); // . " WHERE groupid != " . XOOPS_GROUP_USERS); // use all groups now, if all groups are picked, with no restrictions on membership or anything, then use all groups foreach ($allgroupsq as $thisgid) { $pgroups[] = $thisgid['groupid']; } } } } // Note: OLD WAY: if no groups were found, then pguidq will be empty and so all entries will be shown, no restrictions // NEW WAY: if a specific group(s) was specified, and no match with the current user was found, then we return an empty list array_unique($pgroups); // remove duplicate groups from the list if ($ele_value[6] and count($pgroups) > 0) { $pgroupsfilter = " ("; $start = true; foreach ($pgroups as $thisPgroup) { if (!$start) { $pgroupsfilter .= " AND "; } $pgroupsfilter .= "EXISTS(SELECT 1 FROM " . $xoopsDB->prefix("formulize_entry_owner_groups") . " AS t2 WHERE t2.groupid={$thisPgroup} AND t2.fid={$sourceFid} AND t2.entry_id=t1.entry_id)"; $start = false; } $pgroupsfilter .= ")"; } elseif (count($pgroups) > 0) { $pgroupsfilter = " t2.groupid IN (" . formulize_db_escape(implode(",", $pgroups)) . ") AND t2.entry_id=t1.entry_id AND t2.fid={$sourceFid}"; } else { $pgroupsfilter = ""; } $sourceFormObject = $form_handler->get($sourceFid); list($conditionsfilter, $conditionsfilter_oom, $parentFormFrom) = buildConditionsFilterSQL($ele_value[5], $sourceFid, $entry_id, $owner, $formObject, "t1"); // if there is a restriction in effect, then add some SQL to reject options that have already been selected ?? $restrictSQL = ""; if ($ele_value[9]) { $restrictSQL = " AND (\n\t\t\t\tNOT EXISTS (\n\t\t\t\tSELECT 1 FROM " . $xoopsDB->prefix("formulize_" . $formObject->getVar('form_handle')) . " AS t4 WHERE t4.`" . $element->getVar('ele_handle') . "` LIKE CONCAT( '%,', t1.`entry_id` , ',%' ) AND t4.entry_id != " . intval($entry_id); $restrictSQL .= $renderer->addEntryRestrictionSQL($ele_value[9], $id_form, $groups); // pass in the flag about restriction scope, and the form id, and the groups $restrictSQL .= " ) OR EXISTS (\n\t\t\t\tSELECT 1 FROM " . $xoopsDB->prefix("formulize_" . $formObject->getVar('form_handle')) . " AS t4 WHERE t4.`" . $element->getVar('ele_handle') . "` LIKE CONCAT( '%,', t1.`entry_id` , ',%' ) AND t4.entry_id = " . intval($entry_id); $restrictSQL .= $renderer->addEntryRestrictionSQL($ele_value[9], $id_form, $groups); $restrictSQL .= ") )"; } static $cachedSourceValuesQ = array(); static $cachedSourceValuesAutocompleteFile = array(); static $cachedSourceValuesAutocompleteLength = array(); // setup the sort order based on ele_value[12], which is an element id number $sortOrder = $ele_value[15] == 2 ? " DESC" : "ASC"; if ($ele_value[12] == "none" or !$ele_value[12]) { $sortOrderClause = " ORDER BY t1.`{$sourceHandle}` {$sortOrder}"; } else { list($sortHandle) = convertElementIdsToElementHandles(array($ele_value[12]), $sourceFormObject->getVar('id_form')); $sortOrderClause = " ORDER BY t1.`{$sortHandle}` {$sortOrder}"; } if ($pgroupsfilter) { // if there is a groups filter, then join to the group ownership table $sourceValuesQ = "SELECT t1.entry_id, t1.`" . $sourceHandle . "` FROM " . $xoopsDB->prefix("formulize_" . $sourceFormObject->getVar('form_handle')) . " AS t1, " . $xoopsDB->prefix("formulize_entry_owner_groups") . " AS t2 {$parentFormFrom} WHERE {$pgroupsfilter} {$conditionsfilter} {$conditionsfilter_oom} {$restrictSQL} GROUP BY t1.entry_id {$sortOrderClause}"; } else { // otherwise just query the source table $sourceValuesQ = "SELECT t1.entry_id, t1.`" . $sourceHandle . "` FROM " . $xoopsDB->prefix("formulize_" . $sourceFormObject->getVar('form_handle')) . " AS t1 {$parentFormFrom} WHERE t1.entry_id>0 {$conditionsfilter} {$conditionsfilter_oom} {$restrictSQL} GROUP BY t1.entry_id {$sortOrderClause}"; } //print "$sourceValuesQ<br><br>"; if (!$isDisabled) { // set the default selections, based on the entry_ids that have been selected as the defaults, if applicable $hasNoValues = trim($boxproperties[2]) == "" ? true : false; $useDefaultsWhenEntryHasNoValue = $ele_value[14]; if (($entry_id == "new" or $useDefaultsWhenEntryHasNoValue and $hasNoValues) and (is_array($ele_value[13]) and count($ele_value[13]) > 0 or $ele_value[13])) { $defaultSelected = $ele_value[13]; } else { $defaultSelected = ""; } $form_ele = new XoopsFormSelect($caption, $markupName, $defaultSelected, $ele_value[0], $ele_value[1]); $form_ele->setExtra("onchange=\"javascript:formulizechanged=1;\" jquerytag='{$markupName}'"); if ($ele_value[0] == 1) { // add the initial default entry, singular or plural based on whether the box is one line or not. $form_ele->addOption("none", _AM_FORMLINK_PICK); } } else { $disabledHiddenValue = array(); $disabledOutputText = array(); } if (!isset($cachedSourceValuesQ[$sourceValuesQ])) { $element_handler = xoops_getmodulehandler('elements', 'formulize'); $sourceElementObject = $element_handler->get($boxproperties[1]); if ($sourceElementObject->isLinked) { // need to jump one more level back to get value that this value is pointing at $sourceEleValue = $sourceElementObject->getVar('ele_value'); $originalSource = explode("#*=:*", $sourceEleValue[2]); include_once XOOPS_ROOT_PATH . "/modules/formulize/class/data.php"; $data_handler = new formulizeDataHandler($originalSource[0]); } $reslinkedvaluesq = $xoopsDB->query($sourceValuesQ); if ($reslinkedvaluesq) { while ($rowlinkedvaluesq = $xoopsDB->fetchRow($reslinkedvaluesq)) { if ($rowlinkedvaluesq[1] === "") { continue; } if ($sourceElementObject->isLinked) { $rowlinkedvaluesq[1] = $data_handler->getElementValueInEntry(trim($rowlinkedvaluesq[1], ","), $originalSource[1]); } $linkedElementOptions[$rowlinkedvaluesq[0]] = strip_tags($rowlinkedvaluesq[1]); } } $cachedSourceValuesQ[$sourceValuesQ] = $linkedElementOptions; /* ALTERED - 20100318 - freeform - jeff/julian - start */ if (!$isDisabled and $ele_value[8] == 1) { // write the possible values to a cached file so we can look them up easily when we need them, don't want to actually send them to the browser, since it could be huge, but don't want to replicate all the logic that has already gathered the values for us, each time there's an ajax request $cachedLinkedOptionsFileName = "formulize_linkedOptions_" . str_replace(".", "", microtime(true)); formulize_scandirAndClean(XOOPS_ROOT_PATH . "/cache/", "formulize_linkedOptions_"); $cachedLinkedOptions = fopen(XOOPS_ROOT_PATH . "/cache/{$cachedLinkedOptionsFileName}", "w"); fwrite($cachedLinkedOptions, "<?php\n\r"); $maxLength = 0; foreach ($linkedElementOptions as $id => $text) { $thisTextLength = strlen($text); $maxLength = $thisTextLength > $maxLength ? $thisTextLength : $maxLength; $text = str_replace("\$", "\\\$", $text); $quotedText = "\"" . str_replace("\"", "\\\"", html_entity_decode($text, ENT_QUOTES)) . "\""; $singleQuotedText = str_replace("'", "\\'", "[{$quotedText},{$id}]"); fwrite($cachedLinkedOptions, "if(stristr({$quotedText}, \$term)){ \$found[]='" . $singleQuotedText . "'; }\n"); } fwrite($cachedLinkedOptions, "?>"); fclose($cachedLinkedOptions); $cachedSourceValuesAutocompleteFile[$sourceValuesQ] = $cachedLinkedOptionsFileName; $cachedSourceValuesAutocompleteLength[$sourceValuesQ] = $maxLength; } } // if we're rendering an autocomplete box if (!$isDisabled and $ele_value[8] == 1) { // do autocomplete rendering logic here if ($boxproperties[2]) { $default_value = trim($boxproperties[2], ","); $data_handler_autocomplete = new formulizeDataHandler($boxproperties[0]); $default_value_user = $data_handler_autocomplete->getElementValueInEntry(trim($boxproperties[2], ","), $boxproperties[1]); } $renderedComboBox = $renderer->formulize_renderQuickSelect($markupName, $cachedSourceValuesAutocompleteFile[$sourceValuesQ], $default_value, $default_value_user, $cachedSourceValuesAutocompleteLength[$sourceValuesQ]); $form_ele = new xoopsFormLabel($caption, $renderedComboBox); $form_ele->setDescription(html_entity_decode($ele_desc, ENT_QUOTES)); } // only do this if we're rendering a normal element, that is not disabled if (!$isDisabled and $ele_value[8] == 0) { $form_ele->addOptionArray($cachedSourceValuesQ[$sourceValuesQ]); } // only do this if we're rendering a normal element (may be disabled) if ($ele_value[8] == 0) { foreach ($sourceEntryIds as $thisEntryId) { if (!$isDisabled) { $form_ele->setValue($thisEntryId); } else { $disabledName = $ele_value[1] ? $markupName . "[]" : $markupName; $disabledHiddenValue[] = "<input type=hidden name=\"{$disabledName}\" value=\"{$thisEntryId}\">"; $disabledOutputText[] = $cachedSourceValuesQ[$sourceValuesQ][$thisEntryId]; // the text value of the option(s) that are currently selected } } } if ($isDisabled) { $form_ele = new XoopsFormLabel($caption, implode(", ", $disabledOutputText) . implode("\n", $disabledHiddenValue)); $form_ele->setDescription(html_entity_decode($ele_desc, ENT_QUOTES)); } elseif ($ele_value[8] == 0) { // this is a hack because the size attribute is private and only has a getSize and not a setSize, setting the size can only be done through the constructor $count = count($form_ele->getOptions()); $size = $ele_value[0]; $new_size = $count < $size ? $count : $size; $form_ele->_size = $new_size; } /* ALTERED - 20100318 - freeform - jeff/julian - stop */ } else { // or if we don't have a link... $selected = array(); $options = array(); $disabledOutputText = array(); $disabledHiddenValue = array(); $disabledHiddenValues = ""; // add the initial default entry, singular or plural based on whether the box is one line or not. if ($ele_value[0] == 1) { $options["none"] = _AM_FORMLINK_PICK; } // set opt_count to 1 if the box is NOT a multiple selection box. -- jwe 7/26/04 if ($ele_value[1]) { $opt_count = 0; } else { $opt_count = 1; } $hiddenOutOfRangeValuesToWrite = array(); while ($i = each($ele_value[2])) { // handle requests for full names or usernames -- will only kick in if there is no saved value (otherwise ele_value will have been rewritten by the loadValues function in the form display // note: if the user is about to make a proxy entry, then the list of users displayed will be from their own groups, but not from the groups of the user they are about to make a proxy entry for. ie: until the proxy user is known, the choice of users for this list can only be based on the current user. This could lead to confusing or buggy situations, such as users being selected who are outside the groups of the proxy user (who will become the owner) and so there will be an invalid value stored for this element in the db. if ($i['key'] === "{FULLNAMES}" or $i['key'] === "{USERNAMES}") { // ADDED June 18 2005 to handle pulling in usernames for the user's group(s) if ($i['key'] === "{FULLNAMES}") { $nametype = "name"; } if ($i['key'] === "{USERNAMES}") { $nametype = "uname"; } if (isset($ele_value[2]['{OWNERGROUPS}'])) { $groups = $ele_value[2]['{OWNERGROUPS}']; } else { global $regcode; if ($regcode) { // if we're dealing with a registration code, determine group membership based on the code $reggroupsq = q("SELECT reg_codes_groups FROM " . XOOPS_DB_PREFIX . "_reg_codes WHERE reg_codes_code=\"{$regcode}\""); $groups = explode("&8(%\$", $reggroupsq[0]['reg_codes_groups']); if ($groups[0] === "") { unset($groups); } // if a code has no groups associated with it, then kill the null value that will be in position 0 in the groups array. $groups[] = XOOPS_GROUP_USERS; $groups[] = XOOPS_GROUP_ANONYMOUS; } else { global $xoopsUser; $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); } } $pgroups = array(); if ($ele_value[3]) { $scopegroups = explode(",", $ele_value[3]); if (!in_array("all", $scopegroups)) { if ($ele_value[4]) { // limit by users's groups foreach ($groups as $gid) { // want to loop so we can get rid of reg users group simply if ($gid == XOOPS_GROUP_USERS) { continue; } if (in_array($gid, $scopegroups)) { $pgroups[] = $gid; } } if (count($pgroups) > 0) { unset($groups); $groups = $pgroups; } else { $groups = array(); } } else { // don't limit by user's groups $groups = $scopegroups; } } else { // use all if (!$ele_value[4]) { // really use all (otherwise, we're just going with all user's groups, so existing value of $groups will be okay unset($groups); global $xoopsDB; $allgroupsq = q("SELECT groupid FROM " . $xoopsDB->prefix("groups")); // . " WHERE groupid != " . XOOPS_GROUP_USERS); // removed exclusion of registered users group March 18 2009, since it doesn't make sense in this situation. All groups should mean everyone, period. foreach ($allgroupsq as $thisgid) { $groups[] = $thisgid['groupid']; } } } } $namelist = gatherNames($groups, $nametype, $ele_value[6], $ele_value[5]); foreach ($namelist as $auid => $aname) { $options[$auid] = $aname; } } elseif ($i['key'] === "{SELECTEDNAMES}") { // loadValue in formDisplay will create a second option with this key that contains an array of the selected values $selected = $i['value']; } elseif ($i['key'] === "{OWNERGROUPS}") { // do nothing with this piece of metadata that gets set in loadValue, since it's used above } else { // regular selection list.... $options[$opt_count] = $myts->stripSlashesGPC($i['key']); if (strstr($i['key'], _formulize_OUTOFRANGE_DATA)) { $hiddenOutOfRangeValuesToWrite[$opt_count] = str_replace(_formulize_OUTOFRANGE_DATA, "", $i['key']); // if this is an out of range value, grab the actual value so we can stick it in a hidden element later } if ($i['value'] > 0) { $selected[] = $opt_count; } $opt_count++; } } $count = count($options); $size = $ele_value[0]; $final_size = $count < $size ? $count : $size; $form_ele1 = new XoopsFormSelect($caption, $markupName, $selected, $final_size, $ele_value[1]); $form_ele1->setExtra("onchange=\"javascript:formulizechanged=1;\" jquerytag='{$markupName}'"); // must check the options for uitext before adding to the element -- aug 25, 2007 foreach ($options as $okey => $ovalue) { $options[$okey] = formulize_swapUIText($ovalue, $element->getVar('ele_uitext')); } $form_ele1->addOptionArray($options); if ($selected) { if (is_array($selected)) { $hiddenElementName = $ele_value[1] ? $form_ele1->getName() . "[]" : $form_ele1->getName(); foreach ($selected as $thisSelected) { $disabledOutputText[] = $options[$thisSelected]; $disabledHiddenValue[] = "<input type=hidden name=\"{$hiddenElementName}\" value=\"{$thisSelected}\">"; } } elseif ($ele_value[1]) { // need to keep [] in the hidden element name if multiple values are expected, even if only one is chosen $disabledOutputText[] = $options[$selected]; $disabledHiddenValue[] = "<input type=hidden name=\"" . $form_ele1->getName() . "[]\" value=\"{$selected}\">"; } else { $disabledOutputText[] = $options[$selected]; $disabledHiddenValue[] = "<input type=hidden name=\"" . $form_ele1->getName() . "\" value=\"{$selected}\">"; } } $renderedHoorvs = ""; if (count($hiddenOutOfRangeValuesToWrite) > 0) { foreach ($hiddenOutOfRangeValuesToWrite as $hoorKey => $hoorValue) { $thisHoorv = new xoopsFormHidden('formulize_hoorv_' . $true_ele_id . '_' . $hoorKey, $hoorValue); $renderedHoorvs .= $thisHoorv->render() . "\n"; unset($thisHoorv); } } if ($isDisabled) { $disabledHiddenValues = implode("\n", $disabledHiddenValue); // glue the individual value elements together into a set of values $renderedElement = implode(", ", $disabledOutputText); } elseif ($ele_value[8] == 1) { // autocomplete construction: make sure that $renderedElement is the final output of this chunk of code // write the possible values to a cached file so we can look them up easily when we need them, don't want to actually send them to the browser, since it could be huge, but don't want to replicate all the logic that has already gathered the values for us, each time there's an ajax request $cachedOptionsFileName = "formulize_Options_" . str_replace(".", "", microtime(true)); formulize_scandirAndClean(XOOPS_ROOT_PATH . "/cache/", "formulize_Options_"); $cachedOptions = fopen(XOOPS_ROOT_PATH . "/cache/{$cachedOptionsFileName}", "w"); fwrite($cachedOptions, "<?php\n\r"); $maxLength = 0; foreach ($options as $id => $text) { $thisTextLength = strlen($text); $maxLength = $thisTextLength > $maxLength ? $thisTextLength : $maxLength; //$quotedText = "\"".str_replace("\"", "\\\"", trim($text))."\""; $quotedText = "\"" . str_replace("\"", "\\\"", $text) . "\""; fwrite($cachedOptions, "if(stristr({$quotedText}, \$term)){ \$found[]='[{$quotedText},{$id}]'; }\n\r"); } fwrite($cachedOptions, "?>"); fclose($cachedOptions); //print_r($selected); print_r($options); $defaultSelected = is_array($selected) ? $selected[0] : $selected; $renderedComboBox = $renderer->formulize_renderQuickSelect($markupName, $cachedOptionsFileName, $defaultSelected, $options[$defaultSelected], $maxLength); $form_ele2 = new xoopsFormLabel($caption, $renderedComboBox); $renderedElement = $form_ele2->render(); } else { // normal element $renderedElement = $form_ele1->render(); } $form_ele = new XoopsFormLabel($caption, "<nobr>{$renderedElement}</nobr>\n{$renderedHoorvs}\n{$disabledHiddenValues}\n"); $form_ele->setDescription(html_entity_decode($ele_desc, ENT_QUOTES)); } // end of if we have a link on our hands. -- jwe 7/29/04 return $form_ele; }
function displayEntries($formframe, $mainform = "", $loadview = "", $loadOnlyView = 0, $viewallforms = 0, $screen = null) { formulize_benchmark("start of drawing list"); global $xoopsDB, $xoopsUser; // Set some required variables $mid = getFormulizeModId(); list($fid, $frid) = getFormFramework($formframe, $mainform); $gperm_handler =& xoops_gethandler('groupperm'); $member_handler =& xoops_gethandler('member'); $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); $uid = $xoopsUser ? $xoopsUser->getVar('uid') : "0"; if (!($scheck = security_check($fid, "", $uid, "", $groups, $mid, $gperm_handler))) { print "<p>" . _NO_PERM . "</p>"; return; } // must wrap security check in only the conditions in which it is needed, so we don't interfere with saving data in a form (which independently checks the security token) $formulize_LOESecurityPassed = (isset($GLOBALS['formulize_securityCheckPassed']) and $GLOBALS['formulize_securityCheckPassed']) ? true : false; if (($_POST['delconfirmed'] or $_POST['cloneconfirmed'] or $_POST['delviewid_formulize'] or $_POST['saveid_formulize'] or is_numeric($_POST['caid'])) and !$formulize_LOESecurityPassed) { $module_handler =& xoops_gethandler('module'); $config_handler =& xoops_gethandler('config'); $formulizeModule =& $module_handler->getByDirname("formulize"); $formulizeConfig =& $config_handler->getConfigsByCat(0, $formulizeModule->getVar('mid')); $modulePrefUseToken = $formulizeConfig['useToken']; $useToken = $screen ? $screen->getVar('useToken') : $modulePrefUseToken; if (isset($GLOBALS['xoopsSecurity']) and $useToken) { $formulize_LOESecurityPassed = $GLOBALS['xoopsSecurity']->check(); } else { // if there is no security token, then assume true -- necessary for old versions of XOOPS. $formulize_LOESecurityPassed = true; } } // check for all necessary permissions $add_own_entry = $gperm_handler->checkRight("add_own_entry", $fid, $groups, $mid); $delete_own_reports = $gperm_handler->checkRight("delete_own_reports", $fid, $groups, $mid); $delete_other_reports = $gperm_handler->checkRight("delete_other_reports", $fid, $groups, $mid); $update_other_reports = $gperm_handler->checkRight("update_other_reports", $fid, $groups, $mid); $update_own_reports = $gperm_handler->checkRight("update_own_reports", $fid, $groups, $mid); $view_globalscope = $gperm_handler->checkRight("view_globalscope", $fid, $groups, $mid); $view_groupscope = $gperm_handler->checkRight("view_groupscope", $fid, $groups, $mid); // Question: do we need to add check here to make sure that $loadview is an available report (move function call from the generateViews function) and if it is not, then nullify // we may want to be able to pass in any old report, it's kind of like a way to override the publishing process. Problem is unpublished reports or reports that aren't actually published to the user won't show up in the list of views. // [update: loaded views do not include the list of views, they have no interface at all except quick searches and quick sorts. Since the intention is clearly for them to be accessed through pageworks, we will leave the permission control up to the application designer for now] $currentURL = getCurrentURL(); // get title $displaytitle = getFormTitle($fid); // get default info and info passed to page.... // clear any default search text that has been passed (because the user didn't actually search for anything) foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and $v == _formulize_DE_SEARCH_HELP) { unset($_POST[$k]); break; // assume this is only sent once, since the help text only appears in the first column } } // check for deletion request (set by 'delete selected' button) if ($_POST['delconfirmed'] and $formulize_LOESecurityPassed) { foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "delete_" and $v != "") { $delete_entry_id = substr($k, 7); // confirm user has permission to delete this entry if (formulizePermHandler::user_can_delete_entry($fid, $uid, $delete_entry_id)) { $GLOBALS['formulize_deletionRequested'] = true; // new syntax for deleteEntry, Sept 18 2005 -- used to handle deleting all unified display entries that are linked to this entry. if ($frid) { deleteEntry($delete_entry_id, $frid, $fid, $gperm_handler, $member_handler, $mid); } else { deleteEntry($delete_entry_id, "", $fid); } } } } } // check for cloning request and if present then clone entries if ($_POST['cloneconfirmed'] and $formulize_LOESecurityPassed and $add_own_entry) { foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "delete_" and $v != "") { $thisentry = substr($k, 7); cloneEntry($thisentry, $frid, $fid, $_POST['cloneconfirmed']); // cloneconfirmed is the number of copies required } } } // handle deletion of view...reset currentView if ($_POST['delview'] and $formulize_LOESecurityPassed and ($delete_other_reports or $delete_own_reports)) { if (substr($_POST['delviewid_formulize'], 1, 4) == "old_") { $delviewid_formulize = substr($_POST['delviewid_formulize'], 5); } else { $delviewid_formulize = substr($_POST['delviewid_formulize'], 1); } if ($delete_other_reports or $xoopsUser->getVar('uid') == getSavedViewOwner($delviewid_formulize)) { // "get saved view owner" only works with new saved view format in 2.0 or greater, but since that is 2.5 years old now, should be good to go! if (substr($_POST['delviewid_formulize'], 1, 4) == "old_") { $sql = "DELETE FROM " . $xoopsDB->prefix("formulize_reports") . " WHERE report_id='" . $delviewid_formulize . "'"; } else { $sql = "DELETE FROM " . $xoopsDB->prefix("formulize_saved_views") . " WHERE sv_id='" . $delviewid_formulize . "'"; } if (!($res = $xoopsDB->query($sql))) { exit("Error deleting report: " . $_POST['delviewid_formulize']); } unset($_POST['currentview']); $_POST['resetview'] = 1; } } // if resetview is set, then unset POST and then set currentview to resetview // intended for when a user switches from a locked view back to a basic view. In that case we want all settings to be cleared and everything to work like the basic view, rather than remembering, for instance, that the previous view had a calculation or a search of something. // users who view reports (views) that aren't locked can switch back to a basic view and retain settings. This is so they can make changes to a view and then save the updates. It is also a little confusing to switch from a predefined view to a basic one but have the predefined view's settings still hanging around. // recommendation to users should be to lock the controls for all published views. // (this routine also invoked when a view has been deleted) $resetview = false; if ($_POST['resetview']) { $resetview = $_POST['currentview']; foreach ($_POST as $k => $v) { unset($_POST[$k]); } $_POST['currentview'] = $resetview; } // handle saving of the view if that has been requested // only do this if there's a saveid_formulize and they passed the security check, and any one of these: they can update other reports, or this is a "new" view, or this is not a new view, and it belongs to them and they have update own reports permission if ($_POST['saveid_formulize'] and $formulize_LOESecurityPassed and ($update_other_reports or (is_numeric($_POST['saveid_formulize']) and ($update_own_reports and $xoopsUser->getVar('uid') == getSavedViewOwner($_POST['saveid_formulize'])) or $_POST['saveid_formulize'] == "new"))) { // gather all values //$_POST['currentview'] -- from save (they might have updated/changed the scope) //possible situations: // user replaced a report, so we need to set that report as the name of the dropdown, value is currentview // user made a new report, so we need to set that report as the name and the value is currentview // so name of the report gets sent to $loadedView, which also gets assigned to settings array // report is either newid or newname if newid is "new" // newscope goes to $_POST['currentview'] //$_POST['oldcols'] -- from page //$_POST['asearch'] -- from page //$_POST['calc_cols'] -- from page //$_POST['calc_calcs'] -- from page //$_POST['calc_blanks'] -- from page //$_POST['calc_grouping'] -- from page //$_POST['sort'] -- from page //$_POST['order'] -- from page //$_POST['hlist'] -- passed from page //$_POST['hcalc'] -- passed from page //$_POST['lockcontrols'] -- passed from save //and quicksearches -- passed with the page // pubgroups -- passed from save $_POST['currentview'] = $_POST['savescope']; $saveid_formulize = $_POST['saveid_formulize']; $_POST['lockcontrols'] = $_POST['savelock']; $savegroups = $_POST['savegroups']; // put name into loadview if ($saveid_formulize != "new") { if (!strstr($saveid_formulize, "old_")) { // if it's not a legacy report... $sname = q("SELECT sv_name, sv_owner_uid FROM " . $xoopsDB->prefix("formulize_saved_views") . " WHERE sv_id = \"" . substr($saveid_formulize, 1) . "\""); if ($sname[0]['sv_owner_uid'] == $uid) { $loadedView = $saveid_formulize; } else { $loadedView = "p" . substr($saveid_formulize, 1); } } } $savename = $_POST['savename']; if (get_magic_quotes_gpc()) { $savename = stripslashes($savename); } // flatten quicksearches -- one value in the array for every column in the view $allcols = explode(",", $_POST['oldcols']); foreach ($allcols as $thiscol) { $allquicksearches[] = $_POST['search_' . $thiscol]; } // need to grab all hidden quick searches and then add any hidden columns to the column list...need to reverse this process when loading views foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and $v != "") { if (!in_array(substr($k, 7), $allcols) and substr($v, 0, 1) == "!" and substr($v, -1) == "!") { $_POST['oldcols'] .= ",hiddencolumn_" . substr($k, 7); $allquicksearches[] = $v; } } } $qsearches = implode("&*=%4#", $allquicksearches); $savename = formulize_db_escape($savename); $savesearches = formulize_db_escape($_POST['asearch']); //print $_POST['asearch'] . "<br>"; //print "$savesearches<br>"; $qsearches = formulize_db_escape($qsearches); if ($frid) { $saveformframe = $frid; $savemainform = $fid; } else { $saveformframe = $fid; $savemainform = ""; } if ($saveid_formulize == "new" or strstr($saveid_formulize, "old_")) { if ($saveid_formulize == "new") { $owneruid = $uid; $moduid = $uid; } else { // get existing uid $olduid = q("SELECT report_uid FROM " . $xoopsDB->prefix("formulize_reports") . " WHERE report_id = '" . substr($saveid_formulize, 5) . "'"); $owneruid = $olduid[0]['report_uid']; $moduid = $uid; } $savesql = "INSERT INTO " . $xoopsDB->prefix("formulize_saved_views") . " (" . "sv_name, " . "sv_pubgroups, " . "sv_owner_uid, " . "sv_mod_uid, " . "sv_formframe, " . "sv_mainform, " . "sv_lockcontrols, " . "sv_hidelist, " . "sv_hidecalc, " . "sv_asearch, " . "sv_sort, " . "sv_order, " . "sv_oldcols, " . "sv_currentview, " . "sv_calc_cols, " . "sv_calc_calcs, " . "sv_calc_blanks, " . "sv_calc_grouping, " . "sv_quicksearches, " . "sv_global_search" . ") VALUES (" . "\"" . formulize_db_escape($savename) . "\", " . "\"" . formulize_db_escape($savegroups) . "\", " . "\"" . formulize_db_escape($owneruid) . "\", " . "\"" . formulize_db_escape($moduid) . "\", " . "\"" . formulize_db_escape($saveformframe) . "\", " . "\"" . formulize_db_escape($savemainform) . "\", " . "\"" . formulize_db_escape($_POST['savelock']) . "\", " . "\"" . formulize_db_escape($_POST['hlist']) . "\", " . "\"" . formulize_db_escape($_POST['hcalc']) . "\", " . "\"" . formulize_db_escape($savesearches) . "\", " . "\"" . formulize_db_escape($_POST['sort']) . "\", " . "\"" . formulize_db_escape($_POST['order']) . "\", " . "\"" . formulize_db_escape($_POST['oldcols']) . "\", " . "\"" . formulize_db_escape($_POST['savescope']) . "\", " . "\"" . formulize_db_escape($_POST['calc_cols']) . "\", " . "\"" . formulize_db_escape($_POST['calc_calcs']) . "\", " . "\"" . formulize_db_escape($_POST['calc_blanks']) . "\", " . "\"" . formulize_db_escape($_POST['calc_grouping']) . "\", " . "\"" . formulize_db_escape($qsearches) . "\", " . "\"" . formulize_db_escape($_POST['global_search']) . "\" " . ")"; } else { // print "UPDATE " . $xoopsDB->prefix("formulize_saved_views") . " SET sv_pubgroups=\"$savegroups\", sv_mod_uid=\"$uid\", sv_lockcontrols=\"{$_POST['savelock']}\", sv_hidelist=\"{$_POST['hlist']}\", sv_hidecalc=\"{$_POST['hcalc']}\", sv_asearch=\"$savesearches\", sv_sort=\"{$_POST['sort']}\", sv_order=\"{$_POST['order']}\", sv_oldcols=\"{$_POST['oldcols']}\", sv_currentview=\"{$_POST['savescope']}\", sv_calc_cols=\"{$_POST['calc_cols']}\", sv_calc_calcs=\"{$_POST['calc_calcs']}\", sv_calc_blanks=\"{$_POST['calc_blanks']}\", sv_calc_grouping=\"{$_POST['calc_grouping']}\", sv_quicksearches=\"$qsearches\" WHERE sv_id = \"" . substr($saveid_formulize, 1) . "\""; $savesql = "UPDATE " . $xoopsDB->prefix("formulize_saved_views") . " SET " . "sv_name \t\t\t= \"" . formulize_db_escape($savename) . "\", " . "sv_pubgroups \t\t= \"" . formulize_db_escape($savegroups) . "\", " . "sv_mod_uid \t\t= \"" . formulize_db_escape($uid) . "\", " . "sv_lockcontrols \t= \"" . formulize_db_escape($_POST['savelock']) . "\", " . "sv_hidelist \t\t= \"" . formulize_db_escape($_POST['hlist']) . "\", " . "sv_hidecalc \t\t= \"" . formulize_db_escape($_POST['hcalc']) . "\", " . "sv_asearch \t\t= \"" . formulize_db_escape($savesearches) . "\", " . "sv_sort \t\t\t= \"" . formulize_db_escape($_POST['sort']) . "\", " . "sv_order \t\t\t= \"" . formulize_db_escape($_POST['order']) . "\", " . "sv_oldcols \t\t= \"" . formulize_db_escape($_POST['oldcols']) . "\", " . "sv_currentview \t= \"" . formulize_db_escape($_POST['savescope']) . "\", " . "sv_calc_cols \t\t= \"" . formulize_db_escape($_POST['calc_cols']) . "\", " . "sv_calc_calcs \t\t= \"" . formulize_db_escape($_POST['calc_calcs']) . "\", " . "sv_calc_blanks \t= \"" . formulize_db_escape($_POST['calc_blanks']) . "\", " . "sv_calc_grouping \t= \"" . formulize_db_escape($_POST['calc_grouping']) . "\", " . "sv_quicksearches \t= \"" . formulize_db_escape($qsearches) . "\", " . "sv_global_search = \"" . formulize_db_escape($_POST['global_search']) . "\" " . " WHERE " . "sv_id = \"" . substr($saveid_formulize, 1) . "\""; } // save the report if (!($result = $xoopsDB->query($savesql))) { exit("Error: unable to save the current view settings. SQL dump: {$savesql}"); } if ($saveid_formulize == "new" or strstr($saveid_formulize, "old_")) { if ($owneruid == $uid) { $loadedView = "s" . $xoopsDB->getInsertId(); } else { $loadedView = "p" . $xoopsDB->getInsertId(); } } $settings['loadedview'] = $loadedView; // delete legacy report if necessary if (strstr($saveid_formulize, "old_")) { $dellegacysql = "DELETE FROM " . $xoopsDB->prefix("formulize_reports") . " WHERE report_id=\"" . substr($saveid_formulize, 5) . "\""; if (!($result = $xoopsDB->query($dellegacysql))) { exit("Error: unable to delete legacy report: " . substr($saveid_formulize, 5)); } } } $forceLoadView = false; if ($screen) { $loadview = is_numeric($loadview) ? $loadview : $screen->getVar('defaultview'); // flag the screen default for loading if no specific view has been requested if ($loadview == "mine" or $loadview == "group" or $loadview == "all" or $loadview == "blank" and (!isset($_POST['hlist']) and !isset($_POST['hcalc']))) { // only pay attention to the "blank" default list if we are on an initial page load, ie: no hcalc or hlist is set yet, and one of those is set on each page load hereafter $currentView = $loadview; // if the default is a standard view, then use that instead and don't load anything unset($loadview); } elseif ($_POST['userClickedReset']) { // only set if the user actually clicked that button, and in that case, we want to be sure we load the default as specified for the screen $forceLoadView = true; } } // set currentView to group if they have groupscope permission (overridden below by value sent from form) // override with loadview if that is specified if ($loadview and (!$_POST['currentview'] and $_POST['advscope'] == "" or $forceLoadView)) { if (substr($loadview, 0, 4) == "old_") { // this is a legacy view $loadview = "p" . $loadview; } elseif (is_numeric($loadview)) { // new view id $loadview = "p" . $loadview; } else { // new view name -- loading view by name -- note if two reports have the same name, then the first one created will be returned $viewnameq = q("SELECT sv_id FROM " . $xoopsDB->prefix("formulize_saved_views") . " WHERE sv_name='{$loadview}' ORDER BY sv_id"); $loadview = "p" . $viewnameq[0]['sv_id']; } $_POST['currentview'] = $loadview; $_POST['loadreport'] = 1; } elseif ($view_globalscope and !$currentView) { $currentView = "all"; } elseif ($view_groupscope and !$currentView) { $currentView = "group"; } elseif (!$currentView) { $currentView = "mine"; } // debug block to show key settings being passed back to the page /* if($uid == 1) { print "delview: " . $_POST['delview'] . "<br>"; print "advscope: " . $_POST['advscope'] . "<br>"; print "asearch: " . $_POST['asearch'] . "<br>"; print "Hidelist: " . $_POST['hlist'] . "<br>"; print "Hidecalc: " . $_POST['hcalc'] . "<br>"; print "Lock Controls: " . $_POST['lockcontrols'] . "<br>"; print "Sort: " . $_POST['sort'] . "<br>"; print "Order: " . $_POST['order'] . "<br>"; print "Cols: " . $_POST['oldcols'] . "<br>"; print "Curview: " . $_POST['currentview'] . "<br>"; print "Calculation columns: " . $_POST['calc_cols'] . "<br>"; print "Calculation calcs: " . $_POST['calc_calcs'] . "<br>"; print "Calculation blanks: " . $_POST['calc_blanks'] . "<br>"; print "Calculation grouping: " . $_POST['calc_grouping'] . "<br>"; foreach($_POST as $k=>$v) { if(substr($k, 0, 7) == "search_" AND $v != "") { print "$k: $v<br>"; } } }*/ // set flag to indicate whether we let the user's scope setting expand beyond their normal permission level (happens when unlocked published views are in effect) $currentViewCanExpand = false; // handling change in view, and loading reports/saved views if necessary if ($_POST['loadreport']) { if (substr($_POST['currentview'], 1, 4) == "old_") { // legacy report // load old report values and then assign them to the correct $_POST keys in order to present the view $loadedView = $_POST['currentview']; $settings['loadedview'] = $loadedView; // kill the quicksearches foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and $v != "") { unset($_POST[$k]); } } list($_POST['currentview'], $_POST['oldcols'], $_POST['asearch'], $_POST['calc_cols'], $_POST['calc_calcs'], $_POST['calc_blanks'], $_POST['calc_grouping'], $_POST['sort'], $_POST['order'], $_POST['hlist'], $_POST['hcalc'], $_POST['lockcontrols']) = loadOldReport(substr($_POST['currentview'], 5), $fid, $view_groupscope); } elseif (is_numeric(substr($_POST['currentview'], 1))) { // saved or published view $loadedView = $_POST['currentview']; $settings['loadedview'] = $loadedView; // kill the quicksearches, unless we've found a special flag that will cause them to be preserved if (!isset($_POST['formulize_preserveQuickSearches']) and !isset($_GET['formulize_preserveQuickSearches'])) { foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and $v != "") { unset($_POST[$k]); } } } list($_POST['currentview'], $_POST['oldcols'], $_POST['asearch'], $_POST['calc_cols'], $_POST['calc_calcs'], $_POST['calc_blanks'], $_POST['calc_grouping'], $_POST['sort'], $_POST['order'], $savedViewHList, $savedViewHCalc, $_POST['lockcontrols'], $quicksearches, $_POST['global_search']) = loadReport(substr($_POST['currentview'], 1), $fid, $frid); if (!isset($_POST['formulize_preserveListCalcPage']) and !isset($_GET['formulize_preserveListCalcPage'])) { $_POST['hlist'] = $savedViewHList; $_POST['hcalc'] = $savedViewHCalc; } // explode quicksearches into the search_ values $allqsearches = explode("&*=%4#", $quicksearches); $colsforsearches = explode(",", $_POST['oldcols']); for ($i = 0; $i < count($allqsearches); $i++) { if ($allqsearches[$i] != "") { $_POST["search_" . str_replace("hiddencolumn_", "", dealWithDeprecatedFrameworkHandles($colsforsearches[$i], $frid))] = $allqsearches[$i]; // need to remove the hiddencolumn indicator if it is present if (strstr($colsforsearches[$i], "hiddencolumn_")) { unset($colsforsearches[$i]); // remove columns that were added to the column list just so we would know the name of the hidden searches } } } $_POST['oldcols'] = implode(",", $colsforsearches); // need to reconstruct this in case any columns were removed because of persistent searches on a hidden column } $currentView = $_POST['currentview']; // need to check that the user is allowed to have this scope, unless the view is unlocked // only works for the default levels of views, not specific group selections that a view might have...that would be more complicated and could be built in later if ($_POST['lockcontrols']) { if ($currentView == "all" and !$view_globalscope) { $currentView = "group"; } if ($currentView == "group" and !$view_groupscope and !$view_globalscope) { $currentView = "mine"; } } // must check for this and set it here, inside this section, where we know for sure that $_POST['lockcontrols'] has been set based on the database value for the saved view, and not anything else sent from the user!!! Otherwise the user might be injecting a greater scope for themselves than they should have! $currentViewCanExpand = $_POST['lockcontrols'] ? false : true; // if the controls are not locked, then we can expand the view for the user so they can see things they wouldn't normally see // if there is a screen with a top template in effect, then do not lock the controls even if the saved view says we should. Assume that the screen author has compensated for any permission issues. // we need to do this after rachetting down the visibility controls. Fact is, controlling UI for users is one thing that we can trust the screen author to do, so we don't need to indicate that the controls are locked. But we don't want the visibility to override what people can normally see, so we rachet that down above. if ($screen and $_POST['lockcontrols']) { if ($screen->getTemplate('toptemplate') != "") { $_POST['lockcontrols'] = 0; } } } elseif ($_POST['advscope'] and strstr($_POST['advscope'], ",")) { // looking for comma sort of means that we're checking that a valid advanced scope is being sent $currentView = $_POST['advscope']; } elseif ($_POST['currentview']) { // could have been unset by deletion of a view or something else, so we must check to make sure it exists before we override the default that was determined above if (is_numeric(substr($_POST['currentview'], 1))) { // a saved view was requested as the current view, but we don't want to load the entire thing....this means that we just want to use the view to generate the scope, we don't want to load all settings. So we have to load the view, but discard everything but the view's currentview value // if we were supposed to load the whole thing, loadreport would have been set in post and the above code would have kicked in $loadedViewSettings = loadReport(substr($_POST['currentview'], 1), $fid, $frid); $currentview = $loadedViewSettings[0]; } else { $currentView = $_POST['currentview']; } } elseif ($loadview) { $currentView = $loadview; } // get columns for this form/framework or use columns sent from interface // ele_handles for a form, handles for a framework, includes handles of all unified display forms if ($_POST['oldcols']) { $showcols = explode(",", $_POST['oldcols']); } else { // or use the defaults $showcols = getDefaultCols($fid, $frid); } if ($_POST['newcols']) { $temp_showcols = $_POST['newcols']; $showcols = explode(",", $temp_showcols); } // convert framework handles to element handles if necessary $showcols = dealWithDeprecatedFrameworkHandles($showcols, $frid); $showcols = removeNotAllowedCols($fid, $frid, $showcols, $groups); // converts old format metadata fields to new ones too if necessary // Create settings array to pass to form page or to other functions $settings['title'] = $displaytitle; // get export options if ($_POST['xport']) { $settings['xport'] = $_POST['xport']; if ($_POST['xport'] == "custom") { $settings['xport_cust'] = $_POST['xport_cust']; } } list($scope, $currentView) = buildScope($currentView, $member_handler, $gperm_handler, $uid, $groups, $fid, $mid, $currentViewCanExpand); // generate the available views // pubstart used to indicate to the delete button where the list of published views begins in the current view drop down (since you cannot delete published views) list($settings['viewoptions'], $settings['pubstart'], $settings['endstandard'], $settings['pickgroups'], $settings['loadviewname'], $settings['curviewid'], $settings['publishedviewnames']) = generateViews($fid, $uid, $groups, $frid, $currentView, $loadedView, $view_groupscope, $view_globalscope, $_POST['curviewid'], $loadOnlyView, $screen, $_POST['lastloaded']); // this param only used in case of loading of reports via passing in the report id or name through $loadview if ($_POST['loadviewname']) { $settings['loadviewname'] = $_POST['loadviewname']; } // if a view was loaded, then update the lastloaded value, otherwise preserve the previous value if ($settings['curviewid']) { $settings['lastloaded'] = $settings['curviewid']; } else { $settings['lastloaded'] = $_POST['lastloaded']; } // clear quick searches for any columns not included now // also, convert any { } terms to literal values for users who can't update other reports, if the last loaded report doesn't belong to them (they're presumably just report consumers, so they don't need to preserve the abstract terms) $hiddenQuickSearches = array(); // array used to indicate quick searches that should be present even if the column is not displayed to the user foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and !in_array(substr($k, 7), $showcols)) { if (substr($v, 0, 1) == "!" and substr($v, -1) == "!") { // don't strip searches that have ! at front and back $hiddenQuickSearches[] = substr($k, 7); continue; // since the { } replacement is meant for the ease of use of non-admin users, and hiddenQuickSearches never show up to users on screen, we can skip the potentially expensive operations below in this loop } else { unset($_POST[$k]); } } // if this is not a report/view that was created by the user, and they don't have update permission, then convert any { } terms to literals // remove any { } terms that don't have a passed in value (so they appear as "" to users) // only deal with terms that start and end with { } and not ones where the { } terms is not the entire term if (is_string($v) and substr($v, 0, 1) == "{" and substr($v, -1) == "}" and substr($k, 0, 7) == "search_" and in_array(substr($k, 7), $showcols)) { $requestKeyToUse = substr($v, 1, -1); if (!strstr($requestKeyToUse, "}") and !strstr($requestKeyToUse, "{")) { // double check that there's no other { } in the term! $activeViewId = substr($settings['lastloaded'], 1); // will have a p in front of the number, to show it's a published view (or an s, but that's unlikely to ever happen in this case) $ownerOfLastLoadedViewData = q("SELECT sv_owner_uid FROM " . $xoopsDB->prefix("formulize_saved_views") . " WHERE sv_id=" . intval($activeViewId)); $ownerOfLastLoadedView = $ownerOfLastLoadedViewData[0]['sv_owner_uid']; if (!$update_other_reports and $uid != $ownerOfLastLoadedView) { if (isset($_POST[$requestKeyToUse])) { $_POST[$k] = htmlspecialchars(strip_tags(trim($_POST[$requestKeyToUse]))); } elseif (isset($_GET[$requestKeyToUse])) { $_POST[$k] = htmlspecialchars(strip_tags(trim($_GET[$requestKeyToUse]))); } elseif ($v == "{USER}" and $xoopsUser) { $_POST[$k] = $xoopsUser->getVar('name') ? $xoopsUser->getVar('name') : $xoopsUser->getVar('uname'); } elseif (!strstr($v, "{BLANK}") and !strstr($v, "{TODAY") and !strstr($v, "{PERGROUPFILTER}") and !strstr($v, "{USER")) { unset($_POST[$k]); // clear terms where no match was found, because this term is not active on the current page, so don't confuse users by showing it } } } } } $settings['currentview'] = $currentView; $settings['currentURL'] = $currentURL; // no need for both these values now, since framework handles are deprecated $settings['columns'] = $showcols; $settings['columnhandles'] = $showcols; $settings['hlist'] = $_POST['hlist']; $settings['hcalc'] = $_POST['hcalc']; // determine if the controls should really be locked... if ($_POST['lockcontrols']) { // if a view locks the controls // only lock the controls when the user is not a member of the currentview groups AND has no globalscope // OR if they are a member of the currentview groups AND has no groupscope or no globalscope switch ($currentView) { case "mine": $settings['lockcontrols'] = ""; break; case "all": if ($view_globalscope) { $settings['lockcontrols'] = ""; } else { $settings['lockcontrols'] = "1"; } break; case "group": if ($view_groupscope or $view_globalscope) { $settings['lockcontrols'] = ""; } else { $settings['lockcontrols'] = "1"; } break; default: $viewgroups = explode(",", trim($currentView, ",")); // get the groups that the current user has specified scope for, and if none, then look at view form $formulize_permHandler = new formulizePermHandler($fid); $groupsWithAccess = $formulize_permHandler->getGroupScopeGroupIds($groups); if ($groupsWithAccess === false) { $groupsWithAccess = $gperm_handler->getGroupIds("view_form", $fid, $mid); $groupsWithAccess = array_intersect($groups, $groupsWithAccess); // limit to just the user's own groups that have this permission, since what we're checking of below is whether the user's groups with view form meet the condition or not } $diff = array_diff($viewgroups, $groupsWithAccess); if (!isset($diff[0]) and $view_groupscope) { // if the scopegroups are completely included in the user's groups that have access to the form, and they have groupscope (ie: they would be allowed to see all these entries anyway) $settings['lockcontrols'] = ""; } elseif ($view_globalscope) { // if they have global scope $settings['lockcontrols'] = ""; } else { // no globalscope and even if they're a member of the scope for this view, they don't have groupscope $settings['lockcontrols'] = "1"; } } } else { $settings['lockcontrols'] = ""; } $settings['asearch'] = $_POST['asearch']; if ($_POST['asearch']) { $as_array = explode("/,%^&2", $_POST['asearch']); foreach ($as_array as $k => $one_as) { $settings['as_' . $k] = $one_as; } } $settings['oldcols'] = implode(",", $showcols); $settings['ventry'] = $_POST['ventry']; // get sort and order options $_POST['sort'] = dealWithDeprecatedFrameworkHandles($_POST['sort'], $frid); $settings['sort'] = $_POST['sort']; $settings['order'] = $_POST['order']; //get all submitted search text foreach ($_POST as $k => $v) { if (substr($k, 0, 7) == "search_" and $v != "") { $thiscol = substr($k, 7); $searches[$thiscol] = $v; $temp_key = "search_" . $thiscol; $settings[$temp_key] = $v; } } // get the submitted global search text $settings['global_search'] = $_POST['global_search']; // get all requested calculations...assign to settings array. $settings['calc_cols'] = $_POST['calc_cols']; $settings['calc_calcs'] = $_POST['calc_calcs']; $settings['calc_blanks'] = $_POST['calc_blanks']; $settings['calc_grouping'] = $_POST['calc_grouping']; // grab all the locked columns so we can persist them if (strstr($_POST['formulize_lockedColumns'], ",")) { $settings['lockedColumns'] = array_unique(explode(",", trim($_POST['formulize_lockedColumns'], ","))); } elseif (strlen($_POST['formulize_lockedColumns']) > 0) { $settings['lockedColumns'] = array(intval($_POST['formulize_lockedColumns'])); } else { $settings['lockedColumns'] = array(); } // set the requested procedure, if any $settings['advcalc_acid'] = strip_tags(htmlspecialchars($_POST['advcalc_acid'])); formulize_addProcedureChoicesToPost($settings['advcalc_acid']); // gather id of the cached data, if any $settings['formulize_cacheddata'] = strip_tags($_POST['formulize_cacheddata']); // process a clicked custom button // must do this before gathering the data! $messageText = ""; if (isset($_POST['caid']) and $screen and $formulize_LOESecurityPassed) { $customButtonDetails = $screen->getVar('customactions'); if (is_numeric($_POST['caid']) and isset($customButtonDetails[$_POST['caid']])) { list($caCode, $caElements, $caActions, $caValues, $caMessageText, $caApplyTo, $caPHP, $caInline) = processCustomButton($_POST['caid'], $customButtonDetails[$_POST['caid']]); // just processing to get the info so we can process the click. Actual output of this button happens lower down $messageText = processClickedCustomButton($caElements, $caValues, $caActions, $caMessageText, $caApplyTo, $caPHP, $caInline); } } if ($_POST['ventry']) { // user clicked on a view this entry link include_once XOOPS_ROOT_PATH . '/modules/formulize/include/formdisplay.php'; if ($_POST['ventry'] == "addnew" or $_POST['ventry'] == "single") { $this_ent = ""; } elseif ($_POST['ventry'] == "proxy") { $this_ent = "proxy"; } else { $this_ent = $_POST['ventry']; } if ($screen and $screen->getVar("viewentryscreen") != "none" and $screen->getVar("viewentryscreen") or $_POST['overridescreen']) { if (strstr($screen->getVar("viewentryscreen"), "p")) { // if there's a p in the specified viewentryscreen, then it's a pageworks page -- added April 16 2009 by jwe $page = intval(substr($screen->getVar("viewentryscreen"), 1)); include XOOPS_ROOT_PATH . "/modules/pageworks/index.php"; return; } else { $screen_handler = xoops_getmodulehandler('screen', 'formulize'); if ($_POST['overridescreen']) { $screenToLoad = intval($_POST['overridescreen']); } else { $screenToLoad = intval($screen->getVar('viewentryscreen')); } $viewEntryScreenObject = $screen_handler->get($screenToLoad); if ($viewEntryScreenObject->getVar('type') == "listOfEntries") { exit("You're sending the user to a list of entries screen instead of some kind of form screen, when they're editing an entry. Check what screen is defined as the screen to use for editing an entry, or what screen id you're using in the viewEntryLink or viewEntryButton functions in the template."); } $viewEntryScreen_handler = xoops_getmodulehandler($viewEntryScreenObject->getVar('type') . 'Screen', 'formulize'); $displayScreen = $viewEntryScreen_handler->get($viewEntryScreenObject->getVar('sid')); if ($displayScreen->getVar('type') == "form") { if ($_POST['ventry'] != "single") { $displayScreen->setVar('reloadblank', 1); // if the user clicked the add multiple button, then specifically override that screen setting so they can make multiple entries } else { $displayScreen->setVar('reloadblank', 0); // otherwise, if they did click the single button, make sure the form reloads with their entry } } $viewEntryScreen_handler->render($displayScreen, $this_ent, $settings); global $renderedFormulizeScreen; // picked up at the end of initialize.php so we set the right info in the template when the whole page is rendered $renderedFormulizeScreen = $displayScreen; return; } } else { if ($_POST['ventry'] != "single") { if ($frid) { displayForm($frid, $this_ent, $fid, $currentURL, "", $settings, "", "", "", "", $viewallforms); // "" is the done text return; } else { displayForm($fid, $this_ent, "", $currentURL, "", $settings, "", "", "", "", $viewallforms); // "" is the done text return; } } else { // if a single entry was requested for a form that can have multiple entries, then specifically override the multiple entry UI (which causes a blank form to appear on save) if ($frid) { displayForm($frid, $this_ent, $fid, $currentURL, "", $settings, "", "", "1", "", $viewallforms); // "" is the done text return; } else { displayForm($fid, $this_ent, "", $currentURL, "", $settings, "", "", "1", "", $viewallforms); // "" is the done text return; } } } // end of "if there's a viewentryscreen, then show that" } // check if we're coming back from a page where a form entry was saved, and if so, synch any subform blanks that might have been written on this page load, synch them with the mainform entry that was written $formToSynch = isset($_POST['primaryfid']) ? intval($_POST['primaryfid']) : 0; if ($formToSynch) { if (isset($_POST['entry' . $formToSynch]) and $enryToSynch = $_POST['entry' . $formToSynch]) { synchSubformBlankDefaults($formToSynch, $entryToSynch); } } include_once XOOPS_ROOT_PATH . "/modules/formulize/include/extract.php"; // create $data and $wq (writable query) formulize_benchmark("before gathering dataset"); list($data, $wq, $regeneratePageNumbers) = formulize_gatherDataSet($settings, $searches, strip_tags($_POST['sort']), strip_tags($_POST['order']), $frid, $fid, $scope, $screen, $currentURL, intval($_POST['forcequery'])); formulize_benchmark("after gathering dataset/before generating calcs"); if ($settings['calc_cols'] and !$settings['hcalc']) { //formulize_benchmark("before performing calcs"); $ccols = explode("/", $settings['calc_cols']); $ccalcs = explode("/", $settings['calc_calcs']); $cblanks = explode("/", $settings['calc_blanks']); $cgrouping = explode("/", $settings['calc_grouping']); $cResults = performCalcs($ccols, $ccalcs, $cblanks, $cgrouping, $frid, $fid); } //formulize_benchmark("after performing calcs"); formulize_benchmark("after generating calcs/before creating pagenav"); $formulize_LOEPageNav = formulize_LOEbuildPageNav($data, $screen, $regeneratePageNumbers); formulize_benchmark("after nav/before interface"); $formulize_buttonCodeArray = array(); list($formulize_buttonCodeArray) = drawInterface($settings, $fid, $frid, $groups, $mid, $gperm_handler, $loadview, $loadOnlyView, $screen, $searches, $formulize_LOEPageNav, $messageText, $hiddenQuickSearches); // if there is messageText and no custom top template, and no messageText variable in the bottom template, then we have to output the message text here if ($screen and $messageText) { if (trim($screen->getTemplate('toptemplate')) == "" and !strstr($screen->getTemplate('bottomtemplate'), 'messageText')) { print "<p><center><b>{$messageText}</b></center></p>\n"; } } formulize_benchmark("before entries"); drawEntries($fid, $showcols, $searches, $frid, $scope, "", $currentURL, $gperm_handler, $uid, $mid, $groups, $settings, $member_handler, $screen, $data, $wq, $regeneratePageNumbers, $hiddenQuickSearches, $cResults); // , $loadview); // -- loadview not passed any longer since the lockcontrols indicator is used to handle whether things should appear or not. formulize_benchmark("after entries"); if ($screen) { formulize_screenLOETemplate($screen, "bottom", $formulize_buttonCodeArray, $settings); } else { print $formulize_LOEPageNav; // redraw page numbers if there is no screen in effect } if (isset($formulize_buttonCodeArray['submitButton'])) { // if a custom top template was in effect, this will have been sent back, so now we display it at the very bottom of the form so it doesn't take up a visible amount of space above (the submitButton is invisible, but does take up space) print "<p class=\"formulize_customTemplateSubmitButton\">" . $formulize_buttonCodeArray['submitButton'] . "</p>"; } print "</form>\n"; // end of the form started in drawInterface print "</div>\n"; // end of the listofentries div, used to call up the working message when the page is reloading, started in drawInterface }
function saveMenuEntryAndPermissionsSQL($formid, $appid, $i, $menuText) { global $xoopsDB; $gperm_handler = xoops_gethandler('groupperm'); $permissionsql = ""; $groupsThatCanView = $gperm_handler->getGroupIds("view_form", $formid, getFormulizeModId()); $menuText = html_entity_decode($menuText, ENT_QUOTES) == "Use the form's title" ? '' : $menuText; $thissql = "INSERT INTO `" . $xoopsDB->prefix("formulize_menu_links") . "` VALUES (null," . $appid . ",'fid=" . $formid . "'," . $i . ",null,'" . $menuText . "');"; //.$permissionsql.";"; if (!($result = $xoopsDB->query($thissql))) { exit("Error inserting Menus. SQL dump:<br>" . $thissql . "<br>" . $xoopsDB->error() . "<br>Please contact <a href=mailto:formulize@freeformsolutions.ca>Freeform Solutions</a> for assistance."); } else { foreach ($groupsThatCanView as $groupid) { if ($permissionsql != "") { $permissionsql .= ",(null," . $xoopsDB->getInsertId() . "," . $groupid . ",0)"; } else { $permissionsql = "INSERT INTO `" . $xoopsDB->prefix("formulize_menu_permissions") . "` VALUES (null," . $xoopsDB->getInsertId() . "," . $groupid . ",0)"; } } if ($permissionsql) { if (!($result = $xoopsDB->query($permissionsql))) { exit("Error inserting Menu permissions. SQL dump:<br>" . $permissionsql . "<br>" . $xoopsDB->error() . "<br>Please contact <a href=mailto:formulize@freeformsolutions.ca>Freeform Solutions</a> for assistance."); } } } }
function displayGrid($fid, $entry = "", $rowcaps, $colcaps, $title = "", $orientation = "horizontal", $startID = "first", $finalCell = "", $finalRow = "", $calledInternal = false, $screen = null, $headingAtSide = "") { include_once XOOPS_ROOT_PATH . '/modules/formulize/include/functions.php'; include_once XOOPS_ROOT_PATH . '/modules/formulize/include/elementdisplay.php'; include_once XOOPS_ROOT_PATH . '/modules/formulize/class/data.php'; global $xoopsUser, $xoopsDB; $numcols = count($colcaps); if (is_array($finalCell)) { $numcols = $numcols + 2; } else { $numcols = $numcols + 1; } $numrows = count($rowcaps); $actual_numrows = count(array_filter($rowcaps)); # count non-null row captions if ($title == "{FORMTITLE}") { $title = trans(getFormTitle($fid)); } else { $title = trans($title); } $currentURL = getCurrentURL(); $uid = $xoopsUser ? $xoopsUser->getVar('uid') : '0'; $mid = getFormulizeModId(); $gperm_handler =& xoops_gethandler('groupperm'); $owner = getEntryOwner($entry, $fid); $member_handler =& xoops_gethandler('member'); //$owner_groups = $owner ? $member_handler->getGroupsByUser($owner, FALSE) : array(0=>XOOPS_GROUP_ANONYMOUS); $data_handler = new formulizeDataHandler($fid); $owner_groups = $owner ? $data_handler->getEntryOwnerGroups($entry) : array(0 => XOOPS_GROUP_ANONYMOUS); $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); if (!$calledInternal) { if (!($scheck = security_check($fid, $entry, $uid, $owner, $groups, $mid, $gperm_handler))) { print "<p>" . _NO_PERM . "</p>"; return; } } // determine if the form is a single entry form and so whether an entry already exists for this form... $single_result = getSingle($fid, $uid, $groups, $member_handler, $gperm_handler, $mid); $single = $single_result['flag']; if ($single and !$entry) { $entry = $single_result['entry']; } if (!$entry) { $entry = "new"; } // figure out where we are supposed to start in the form if (!is_numeric($startID) and $startID !== "first") { $order_query = q("SELECT ele_order FROM " . $xoopsDB->prefix("formulize") . " WHERE ele_caption = \"{$startID}\" AND id_form=\"{$fid}\""); } elseif ($startID === "first") { // get the ele_id of the element with the lowest weight $order_query = q("SELECT ele_order FROM " . $xoopsDB->prefix("formulize") . " WHERE id_form=\"{$fid}\" ORDER BY ele_order LIMIT 0,1"); } else { $order_query = q("SELECT ele_order FROM " . $xoopsDB->prefix("formulize") . " WHERE id_form=\"{$fid}\" AND ele_id =\"{$startID}\""); } $starting_order = $order_query[0]['ele_order']; // gather the element IDs that are to be displayed, in order (include to the end of the form, whereas we actually only will display until we run out of cells) $element_ids_query = q("SELECT ele_id FROM " . $xoopsDB->prefix("formulize") . " WHERE ele_order >= '{$starting_order}' AND id_form='{$fid}' AND ele_type != 'subform' ORDER BY ele_order"); // initialize form if (!$calledInternal) { print $GLOBALS['xoopsSecurity']->getTokenHTML(); } // start buffering the output ob_start(); // set the title row if ($headingAtSide) { $gridContents[0] = $title; $class = "even"; print "<table class='outer'>\n<tr>"; if ($actual_numrows > 0) { echo "<td class=head></td>"; } } else { print "<table class=outer>\n"; $class = "head"; if ($title) { print "<tr><th colspan='{$numcols}'>{$title}</th></tr>\n"; } print "<tr>\n<td class=\"head\"> </td>\n"; } // draw top row foreach ($colcaps as $thiscap) { if ($headingAtSide) { print "<td class=head>{$thiscap}</td>\n"; } else { if ($orientation == "vertical" and $class == "even" and !$headingAtSide) { // only alternate rows $class = "odd"; } elseif ($orientation == "vertical") { $class = "even"; } print "<td class={$class}>{$thiscap}</td>\n"; } } if (is_array($finalCell)) { // draw blank header for last column if there is such a thing print "<td class=head> </td>\n"; } print "</tr>\n"; // draw regular rows $class = "head"; $row_index = 0; $ele_index = 0; foreach ($rowcaps as $thiscap) { if ($orientation == "horizontal" and $class == "even") { $class = "odd"; } elseif ($orientation == "horizontal") { $class = "even"; } else { $class = "head"; } print "<tr>\n"; if ($headingAtSide) { if ($actual_numrows > 0) { print "<td class=\"head\">{$thiscap}</td>\n"; } } else { print "<td class={$class}>{$thiscap}</td>\n"; } foreach ($colcaps as $thiscolcap) { if ($orientation == "vertical" and $class == "even") { $class = "odd"; } elseif ($orientation == "vertical") { $class = "even"; } print "<td class={$class}>\n"; // display the element starting with the initial one. Keep trying to display something until we're successful (displaying the element might fail if the user does not have permission to view (based on which groups are allowed to view this element) $rendered = "start"; while ($rendered != "rendered" and $rendered != "rendered-disabled" and isset($element_ids_query[$ele_index])) { $rendered = displayElement("", $element_ids_query[$ele_index]['ele_id'], $entry, false, $screen); $ele_index++; } if ($rendered != "rendered" and $rendered != "rendered-disabled") { print " "; } print "</td>\n"; } if (is_array($finalCell)) { // draw final cell values if they exist if ($orientation == "vertical") { $class = "head"; } if ($finalCell[$row_index]) { print "<td class={$class}>" . $finalCell[$row_index] . "</td>\n"; } else { print "<td class={$class}> </td>\n"; } } print "</tr>\n"; $row_index++; } // draw final row if necessary if ($finalRow) { print "<tr>{$finalRow}</tr>\n"; } print "</table>"; $gridContents[1] = trans(ob_get_clean()); if ($headingAtSide === "") { // if $headingAtSide is "" (not false) then we print out the grid contents here. Only pass back contents if $headingAtSide is specified as true or false (presumably by the formdisplay.php file), since otherwise for backwards compatibility we need to printout contents here because that's what the behaviour used to be. print $gridContents[1]; } elseif ($headingAtSide) { return $gridContents; } else { return $gridContents[1]; } }
## Project: Formulize ## ############################################################################### // this file handles saving of submissions from the form_permissions page of the new admin UI // if we aren't coming from what appears to be save.php, then return nothing if (!isset($processedValues)) { return; } // CHECK IF THE FORM IS LOCKED DOWN AND SCOOT IF SO $form_handler = xoops_getmodulehandler('forms', 'formulize'); $formObject = $form_handler->get($_POST['formulize_admin_key']); $form_id = $formObject->getVar('id_form'); if ($formObject->getVar('lockedform')) { return; } // If the user doesn't have edit form permission, then do nothing $formulize_module_id = getFormulizeModId(); if (!$gperm_handler->checkRight("edit_form", $form_id, $xoopsUser->getGroups(), $formulize_module_id)) { return; } global $xoopsDB; // check to see if we're dealing with a grouplist save or deletion if ($_POST['grouplistname']) { $groupListId = intval($_POST['grouplistid']); $groupListGroups = formulize_db_escape(implode(",", $_POST['groups'])); $name = formulize_db_escape($_POST['grouplistname']); // are we inserting or updating? $newList = $groupListId == 0 ? true : false; if (!$newList) { // Get exisitng name to see if we update, or create new. $result = $xoopsDB->query("SELECT gl_name FROM " . $xoopsDB->prefix("group_lists") . " WHERE gl_id='" . intval($groupListId) . "'"); if ($xoopsDB->getRowsNum($result) > 0) {
} $listScreenHandler = xoops_getmodulehandler('listOfEntriesScreen', 'formulize'); $screen = $listScreenHandler->create(); $listScreenHandler->setDefaultListScreenVars($screen, $defaultFormScreenId, $formObject->getVar('title'), $fid); if (!($defaultListScreenId = $listScreenHandler->insert($screen))) { print "Error: could not create default list screen"; } $formObject->setVar('defaultform', $defaultFormScreenId); $formObject->setVar('defaultlist', $defaultListScreenId); if (!$form_handler->insert($formObject)) { print "Error: could not update form object with default screen ids: " . $xoopsDB->error(); } // add edit permissions for the selected groups $gperm_handler = xoops_gethandler('groupperm'); foreach ($_POST['groups_can_edit'] as $thisGroupId) { $gperm_handler->addRight('edit_form', $fid, intval($thisGroupId), getFormulizeModId()); } } else { if ($old_form_handle && $formObject->getVar("form_handle") != $old_form_handle) { //print "rename from $old_form_handle to " . $formObject->getVar( "form_handle" ); if (!($renameResult = $form_handler->renameDataTable($old_form_handle, $formObject->getVar("form_handle"), $formObject))) { exit("Error: could not rename the data table in the database."); } } } $selectedAppIds = array(); if ($newAppObject) { // assign the form id to this new application $processedValues['applications']['forms'] = serialize(array($fid)); foreach ($processedValues['applications'] as $property => $value) { $newAppObject->setVar($property, $value);
/** * Obtain a list of the available screen names * @param limitUser boolean Whether to limit the list of screens to those * viewable by the current user * @return Array An array of screens (or an empty array if none are retrieved) */ static function getScreens($limitUser = false) { global $xoopsUser; self::init(); $options = array(); $form_table = self::$db->prefix('formulize_id'); $screen_table = self::$db->prefix('formulize_screen'); //Getting all screens is straightforward if (!$limitUser) { $sql = ' SELECT fi.desc_form, fs.title, fs.sid FROM ' . $form_table . ' AS fi, ' . $screen_table . ' AS fs WHERE fi.id_form = fs.fid ORDER BY fi.desc_form, fs.title '; //If only screens available to the current user are desired } else { if (!$xoopsUser) { $options[0] = 'No Formulize Screens Found'; return $options; } $members = xoops_gethandler('member'); $group_perms = xoops_gethandler('icms_member_groupperm'); $accessible_forms = array(); //Get the groups this member belongs to $groups = $members->getGroupsByUser($xoopsUser->getVar('uid')); //Get the forms visible to each of those groups, and unite them foreach ($groups as $group) { $group_forms = $group_perms->getItemIds('view_form', $group, getFormulizeModId()); $accessible_forms = array_merge($accessible_forms, $group_forms); } //Get the unique IDs of the accessible forms as integers $form_IDs = array_map(intval, array_unique($accessible_forms)); $in_clause = implode(',', $form_IDs); $sql = ' SELECT fi.desc_form, fs.title, fs.sid FROM ' . $form_table . ' AS fi, ' . $screen_table . ' AS fs WHERE fi.id_form = fs.fid AND fi.id_form IN (' . $in_clause . ') ORDER BY fi.desc_form, fs.title '; } //Run the query and assemble/return the results if ($result = self::$db->query($sql)) { while ($row = self::$db->fetchArray($result)) { $options[$row['sid']] = $row['desc_form'] . ' - ' . $row['title']; } } if (count($options) == 0 || !$xoopsUser) { $options[0] = 'No Formulize Screens Found'; } return $options; }
function displayElement($formframe = "", $ele, $entry = "new", $noSave = false, $screen = null, $prevEntry = null, $renderElement = true, $profileForm = null, $groups = "") { static $cachedPrevEntries = array(); static $lockedEntries = array(); // keep track of the entries we have determined are locked global $entriesThatHaveBeenLockedThisPageLoad; if (!is_array($entriesThatHaveBeenLockedThisPageLoad)) { // which entries we have locked as part of this page load, so we don't waste time setting locks again on entries we've already locked, and so we can ignore locks that were set by ourselves! $entriesThatHaveBeenLockedThisPageLoad = array(); } $subformCreateEntry = strstr($entry, "subformCreateEntry") ? true : false; // check for this special flag, which is mostly like a "new" situation, except for the deh hidden flag that gets passed back, since we don't want the standard readelements logic to pickup these elements! if ($subformCreateEntry) { $subformMetaData = explode("_", $entry); $subformEntryIndex = $subformMetaData[1]; $subformElementId = $subformMetaData[2]; } if ($entry == "" or $subformCreateEntry) { $entry = "new"; } $element = _formulize_returnElement($ele, $formframe); if (!is_object($element)) { return "invalid_element"; } $form_id = $element->getVar('id_form'); $deprefix = $noSave ? "denosave_" : "de_"; $deprefix = $subformCreateEntry ? "desubform" . $subformEntryIndex . "x" . $subformElementId . "_" : $deprefix; // need to pass in an entry index so that all fields in the same element can be collected if ($noSave and !is_bool($noSave)) { $renderedElementName = $noSave; // if we've passed a specific string with $noSave, then we want to use that to override the name of the element, because the developer wants to pick up that form value later after submission $noSave = true; } else { $renderedElementName = $deprefix . $form_id . '_' . $entry . '_' . $element->getVar('ele_id'); } global $xoopsUser; if (!$groups) { // groups might be passed in, which covers the case of the registration form and getting the groups from the registration code $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); } $user_id = $xoopsUser ? $xoopsUser->getVar('uid') : 0; $username = $xoopsUser ? $xoopsUser->getVar('uname') : "unknown user"; static $cachedEntryOwners = array(); if (!isset($cachedEntryOwners[$form_id][$entry])) { $cachedEntryOwners[$form_id][$entry] = getEntryOwner($entry, $form_id); } $owner = $cachedEntryOwners[$form_id][$entry]; $mid = getFormulizeModId(); static $cachedViewPrivate = array(); static $cachedUpdateOwnEntry = array(); $gperm_handler = xoops_gethandler('groupperm'); if (!isset($cachedViewPrivate[$form_id])) { $cachedViewPrivate[$form_id] = $gperm_handler->checkRight("view_private_elements", $form_id, $groups, $mid); $cachedUpdateOwnEntry[$form_id] = $gperm_handler->checkRight("update_own_entry", $form_id, $groups, $mid); } $view_private_elements = $cachedViewPrivate[$form_id]; $update_own_entry = $cachedUpdateOwnEntry[$form_id]; // check if the user is normally able to view this element or not, by checking their groups against the display groups -- added Nov 7 2005 // messed up. Private should not override the display settings. And the $entry should be checked against the security check first to determine whether the user should even see this entry in the first place. $display = $element->getVar('ele_display'); $private = $element->getVar('ele_private'); $member_handler = xoops_gethandler('member'); $single_result = getSingle($form_id, $user_id, $groups, $member_handler, $gperm_handler, $mid); $groupEntryWithUpdateRights = ($single_result['flag'] == "group" and $update_own_entry and $entry == $single_result['entry']) ? true : false; // need to test whether the display setting should be checked first?! Order of checks here looks wrong. JWE Nov 25 2010 if ($private and $user_id != $owner and !$groupEntryWithUpdateRights and $entry != "new") { $allowed = $view_private_elements ? 1 : 0; } elseif (strstr($display, ",")) { $display_groups = explode(",", $display); $allowed = array_intersect($groups, $display_groups) ? 1 : 0; } elseif ($display == 1) { $allowed = 1; } else { $allowed = 0; } if ($prevEntry == null) { // preferable to pass in prevEntry! $prevEntry = getEntryValues($entry, "", $groups, $form_id, "", $mid, $user_id, $owner, $groupEntryWithUpdateRights); } // record the list of elements that are allowed in principle for a form (regardless of conditional status) if ($allowed) { $GLOBALS['formulize_renderedElementsForForm'][$form_id][$entry][$renderedElementName] = $element->getVar('ele_handle'); } $elementFilterSettings = $element->getVar('ele_filtersettings'); if ($allowed and count($elementFilterSettings[0]) > 0) { // cache the filterElements for this element, so we can build the right stuff with them later in javascript, to make dynamically appearing elements $GLOBALS['formulize_renderedElementHasConditions'][$renderedElementName] = $elementFilterSettings[0]; // need to check if there's a condition on this element that is met or not static $cachedEntries = array(); if ($entry != "new") { if (!isset($cachedEntries[$form_id][$entry])) { $cachedEntries[$form_id][$entry] = getData("", $form_id, $entry); } $entryData = $cachedEntries[$form_id][$entry]; } $filterElements = $elementFilterSettings[0]; $filterOps = $elementFilterSettings[1]; $filterTerms = $elementFilterSettings[2]; /* ALTERED - 20100316 - freeform - jeff/julian - start */ $filterTypes = $elementFilterSettings[3]; // find the filter indexes for 'match all' and 'match one or more' $filterElementsAll = array(); $filterElementsOOM = array(); for ($i = 0; $i < count($filterTypes); $i++) { if ($filterTypes[$i] == "all") { $filterElementsAll[] = $i; } else { $filterElementsOOM[] = $i; } } /* ALTERED - 20100316 - freeform - jeff/julian - stop */ // setup evaluation condition as PHP and then eval it so we know if we should include this element or not $evaluationCondition = "\$passedCondition = false;\n"; $evaluationCondition .= "if("; /* ALTERED - 20100316 - freeform - jeff/julian - start */ $evaluationConditionAND = buildEvaluationCondition("AND", $filterElementsAll, $filterElements, $filterOps, $filterTerms, $entry, $entryData); $evaluationConditionOR = buildEvaluationCondition("OR", $filterElementsOOM, $filterElements, $filterOps, $filterTerms, $entry, $entryData); $evaluationCondition .= $evaluationConditionAND; if ($evaluationConditionOR) { if ($evaluationConditionAND) { $evaluationCondition .= " AND (" . $evaluationConditionOR . ")"; //$evaluationCondition .= " OR (" . $evaluationConditionOR . ")"; } else { $evaluationCondition .= $evaluationConditionOR; } } /* ALTERED - 20100316 - freeform - jeff/julian - stop */ $evaluationCondition .= ") {\n"; $evaluationCondition .= " \$passedCondition = true;\n"; $evaluationCondition .= "}\n"; //print( $evaluationCondition ); eval($evaluationCondition); if (!$passedCondition) { $allowed = 0; } } if ($allowed) { if ($element->getVar('ele_type') == "subform") { return array("", $isDisabled); } if (isset($GLOBALS['formulize_forceElementsDisabled']) and $GLOBALS['formulize_forceElementsDisabled'] == true) { $isDisabled = true; } else { $ele_disabled = $element->getVar('ele_disabled'); $isDisabled = false; if ($ele_disabled == 1) { $isDisabled = true; } elseif (!is_numeric($ele_disabled)) { $disabled_groups = explode(",", $ele_disabled); if (array_intersect($groups, $disabled_groups) and !array_diff($groups, $disabled_groups)) { $isDisabled = true; } } } // Another check to see if this element is disabled, for the case where the user can view the form, but not edit it. if (!$isDisabled) { // note that we're using the OPPOSITE of the permission because we want to know if the element should be disabled $isDisabled = !formulizePermHandler::user_can_edit_entry($form_id, $user_id, $entry); } // check whether the entry is locked, and if so, then the element is not allowed. Set a message to say that elements were disabled due to entries being edited elsewhere (first time only). // groups with ignore lock permission bypass this, and therefore can save entries even when locked, and saving an entry removes the lock, so that gets you out of a jam if the lock is in place when it shouldn't be. // locks are only valid for the session time, so if a lock is older than that, it is ignored and cleared // Do this last, since locking overrides other permissions! $lockFileName = "entry_" . $entry . "_in_form_" . $form_id . "_is_locked_for_editing"; // if we haven't found a lock for this entry, check if there is one...(as long as it's not an entry that we locked ourselves on this page load) if ($entry != "new" and !isset($lockedEntries[$form_id][$entry]) and !isset($entriesThatHaveBeenLockedThisPageLoad[$form_id][$entry]) and file_exists(XOOPS_ROOT_PATH . "/modules/formulize/temp/{$lockFileName}") and !$gperm_handler->checkRight("ignore_editing_lock", $form_id, $groups, $mid)) { $maxSessionLifeTime = ini_get("session.gc_maxlifetime"); $fileCreationTime = filectime(XOOPS_ROOT_PATH . "/modules/formulize/temp/{$lockFileName}"); if ($fileCreationTime + $maxSessionLifeTime > time()) { list($lockUid, $lockUsername) = explode(",", file_get_contents(XOOPS_ROOT_PATH . "/modules/formulize/temp/{$lockFileName}")); if ($lockUid != $user_id) { // lock is still valid, hasn't expired yet. if (count($lockedEntries) == 0) { $label = json_encode(sprintf(_formulize_ENTRY_IS_LOCKED, $lockUsername)); print <<<EOF <script type='text/javascript'> \$(document).ready(function() { jQuery("<div id=\\"formulize-entry-lock-message\\"><i id=\\"formulize-entry-lock-icon\\" class=\\"icon-lock\\"></i><p>"+{$label}+"</p></div>").insertBefore("#formulize .xo-theme-form table"); }); </script> EOF; } $lockedEntries[$form_id][$entry] = true; } } else { // clean up expired locks formulize_scandirAndClean(XOOPS_ROOT_PATH . "/modules/formulize/temp/", "_" . $entry . "_in_form_" . $form_id . "_", $maxSessionLifeTime); } } // if we've ever found a lock for this entry as part of this pageload... if (isset($lockedEntries[$form_id][$entry])) { $isDisabled = true; } $renderer = new formulizeElementRenderer($element); $ele_value = $element->getVar('ele_value'); $ele_type = $element->getVar('ele_type'); if (($prevEntry or $profileForm === "new") and $ele_type != 'subform' and $ele_type != 'grid') { $data_handler = new formulizeDataHandler($form_id); $ele_value = loadValue($prevEntry, $element, $ele_value, $data_handler->getEntryOwnerGroups($entry), $groups, $entry, $profileForm); // get the value of this element for this entry as stored in the DB -- and unset any defaults if we are looking at an existing entry } formulize_benchmark("About to render element " . $element->getVar('ele_caption') . "."); $form_ele =& $renderer->constructElement($renderedElementName, $ele_value, $entry, $isDisabled, $screen); if (strstr($_SERVER['PHP_SELF'], "formulize/printview.php") and is_object($form_ele)) { $form_ele->setDescription(''); } formulize_benchmark("Done rendering element."); // put a lock on this entry in this form, so we know that the element is being edited. Lock will be removed next time the entry is saved. if ($entry > 0 and !isset($lockedEntries[$form_id][$entry]) and !isset($entriesThatHaveBeenLockedThisPageLoad[$form_id][$entry])) { if (is_writable(XOOPS_ROOT_PATH . "/modules/formulize/temp/")) { $lockFile = fopen(XOOPS_ROOT_PATH . "/modules/formulize/temp/{$lockFileName}", "w"); if (false !== $lockFile) { fwrite($lockFile, "{$user_id},{$username}"); fclose($lockFile); $entriesThatHaveBeenLockedThisPageLoad[$form_id][$entry] = true; } } else { if (defined("ICMS_ERROR_LOG_SEVERITY") and ICMS_ERROR_LOG_SEVERITY >= E_WARNING) { static $lock_file_warning_issued = false; if (!$lock_file_warning_issued) { // cannot write to Formulize temp folder to create lock entries error_log("Notice: Formulize temp folder does not exist or is not writeable, so lock file cannot be created in " . XOOPS_ROOT_PATH . "/modules/formulize/temp/"); $lock_file_warning_issued = true; } } } } if (!$renderElement) { return array(0 => $form_ele, 1 => $isDisabled); } else { if ($element->getVar('ele_type') == "ib") { print $form_ele[0]; return "rendered"; } elseif (is_object($form_ele)) { print $form_ele->render(); if (!empty($form_ele->customValidationCode) and !$isDisabled) { $GLOBALS['formulize_renderedElementsValidationJS'][$GLOBALS['formulize_thisRendering']][$form_ele->getName()] = $form_ele->renderValidationJS(); } elseif ($element->getVar('ele_req') and ($element->getVar('ele_type') == "text" or $element->getVar('ele_type') == "textarea") and !$isDisabled) { $eltname = $form_ele->getName(); $eltcaption = $form_ele->getCaption(); $eltmsg = empty($eltcaption) ? sprintf(_FORM_ENTER, $eltname) : sprintf(_FORM_ENTER, $eltcaption); $eltmsg = str_replace('"', '\\"', stripslashes($eltmsg)); $GLOBALS['formulize_renderedElementsValidationJS'][$GLOBALS['formulize_thisRendering']][$eltname] = "if ( myform." . $eltname . ".value == \"\" ) { window.alert(\"" . $eltmsg . "\"); myform." . $eltname . ".focus(); return false; }"; } if ($isDisabled) { return "rendered-disabled"; } else { return "rendered"; } } } // or, even if the user is not supposed to see the element, put in a hidden element with its default value (only on new entries for elements with the forcehidden flag on) // NOTE: YOU CANNOT HAVE DEFAULT VALUES ON A LINKED FIELD CURRENTLY // So, no handling of linked values is included here. } elseif ($forcehidden = $element->getVar('ele_forcehidden') and $entry == "new" and !$noSave) { // hiddenElements keys will be the element ids $hiddenElements = generateHiddenElements(array($element), $entry); $thisHiddenElement = isset($hiddenElements[$element->getVar('ele_id')]) ? $hiddenElements[$element->getVar('ele_id')] : ""; if (!$renderElement) { return array("hidden", $isDisabled, $thisHiddenElement); // if the element is hidden, then return an array, but with hidden as the first key, so that logic that was not expecting an element back, will still function as is. This is a backwards compatibility thing. For hidden elements, the element is in the third key, if in fact you need it/are looking for it in the user land code...note that in the case of checkboxes, the elements returned will be in an array } else { $cueElement = new xoopsFormHidden("decue_" . $fid . "_" . $entry . "_" . $element_id, 1); print $cueElement->render(); if (is_array($thisHiddenElement)) { // could happen for checkboxes foreach ($thisHiddenElement as $thisIndividualHiddenElement) { if (is_object($thisIndividualHiddenElement)) { print $thisIndividualHiddenElement->render() . "\n"; } } } elseif (is_object($thisHiddenElement)) { print $thisHiddenElement->render() . "\n"; } return "hidden"; } } else { return "not_allowed"; } }
} if ($orderGroups == "alpha") { ksort($groups); } $options['listsofscreenoptions'] = $forms; $screen_handler = xoops_getmodulehandler('screen', 'formulize'); $gperm_handler = xoops_gethandler('groupperm'); global $xoopsUser; foreach ($formObjects as $thisFormObject) { if (!$gperm_handler->checkRight("edit_form", $thisFormObject->getVar('id_form'), $xoopsUser->getGroups(), getFormulizeModId())) { continue; } $formsInApp[$thisFormObject->getVar('id_form')]['name'] = $thisFormObject->getVar('title'); $formsInApp[$thisFormObject->getVar('id_form')]['fid'] = $thisFormObject->getVar('id_form'); // forms tab uses fid $hasDelete = $gperm_handler->checkRight("delete_form", $thisFormObject->getVar('id_form'), $xoopsUser->getGroups(), getFormulizeModId()); $formsInApp[$thisFormObject->getVar('id_form')]['hasdelete'] = $hasDelete; // get the default screens for each form too $defaultFormScreen = $thisFormObject->getVar('defaultform'); $defaultListScreen = $thisFormObject->getVar('defaultlist'); $defaultFormObject = $screen_handler->get($defaultFormScreen); if (is_object($defaultFormObject)) { $defaultFormName = $defaultFormObject->getVar('title'); } $defaultListObject = $screen_handler->get($defaultListScreen); if (is_object($defaultListObject)) { $defaultListName = $defaultListObject->getVar('title'); } $formsInApp[$thisFormObject->getVar('id_form')]['defaultformscreenid'] = $defaultFormScreen; $formsInApp[$thisFormObject->getVar('id_form')]['defaultlistscreenid'] = $defaultListScreen; $formsInApp[$thisFormObject->getVar('id_form')]['defaultformscreenname'] = $defaultFormName;
private static function user_can_modify_entry($action, $form_id, $user_id, $entry_id) { if (!in_array($action, array("update", "delete"))) { throw new Exception("Error: specify either update or delete when calling user_can_modify_entry();"); } $cache_key = "{$action} {$form_id} {$user_id} {$entry_id}"; if (!isset(self::$cached_permissions[$cache_key])) { self::$cached_permissions[$cache_key] = false; if (null == self::$formulize_module_id) { self::$formulize_module_id = getFormulizeModId(); } $gperm_handler =& xoops_gethandler('groupperm'); $member_handler =& xoops_gethandler('member'); $groups = $member_handler->getGroupsByUser($user_id); if ("new" == $entry_id or "" == $entry_id) { if ("update" == $action) { // user has permission to add new entries self::$cached_permissions[$cache_key] = $gperm_handler->checkRight("add_own_entry", $form_id, $groups, self::$formulize_module_id); if (!self::$cached_permissions[$cache_key]) { self::$cached_permissions[$cache_key] = $gperm_handler->checkRight("add_proxy_entries", $form_id, $groups, self::$formulize_module_id); } } else { self::$cached_permissions[$cache_key] = false; // cannot delete an entry which has not been saved } } else { // first check if this an entry by current user and they can edit their own entries if (getEntryOwner($entry_id, $form_id) == $user_id) { // user can update entry because it is their own and they have permission to update their own entries self::$cached_permissions[$cache_key] = $gperm_handler->checkRight("{$action}_own_entry", $form_id, $groups, self::$formulize_module_id); } // next, check group and other permissions, even for own entries if (!self::$cached_permissions[$cache_key]) { // user can update entry because they have permission to update entries by others self::$cached_permissions[$cache_key] = $gperm_handler->checkRight("{$action}_other_entries", $form_id, $groups, self::$formulize_module_id); if (!self::$cached_permissions[$cache_key]) { // check if the user belongs to a group with group-edit permission if ($gperm_handler->checkRight("{$action}_group_entries", $form_id, $groups, self::$formulize_module_id)) { // sometimes users can have a special group scope set, so use that if available $formulize_permHandler = new formulizePermHandler($form_id); $view_form_groups = $formulize_permHandler->getGroupScopeGroupIds($groups); if ($view_form_groups === false) { // no special group scope, so use normal view-form permissions $view_form_groups = $gperm_handler->getGroupIds("view_form", $form_id, self::$formulize_module_id); // need the groups the user is a member of, that have view form permission $view_form_groups = array_intersect($view_form_groups, $groups); } // get the owner groups for the entry $data_handler = new formulizeDataHandler($form_id); $owner_groups = $data_handler->getEntryOwnerGroups($entry_id); // check if the entry belongs to a group that is part of the scope that the user is permitted to interact with self::$cached_permissions[$cache_key] = count(array_intersect($owner_groups, $view_form_groups)); } } } } //Second update to include custom edit check code if ("update" == $action && $entry_id > 0) { $formHandler = xoops_getmodulehandler('forms', 'formulize'); $formObject = $formHandler->get($form_id); self::$cached_permissions[$cache_key] = $formObject->customEditCheck($form_id, $entry_id, $user_id, self::$cached_permissions[$cache_key]); } } return self::$cached_permissions[$cache_key]; }
function displayForm($formframe, $entry = "", $mainform = "", $done_dest = "", $button_text = "", $settings = "", $titleOverride = "", $overrideValue = "", $overrideMulti = "", $overrideSubMulti = "", $viewallforms = 0, $profileForm = 0, $printall = 0, $screen = null) { include_once XOOPS_ROOT_PATH . '/modules/formulize/include/functions.php'; include_once XOOPS_ROOT_PATH . '/modules/formulize/include/extract.php'; formulize_benchmark("Start of formDisplay."); if ($titleOverride == "formElementsOnly") { $titleOverride = "all"; $formElementsOnly = true; } if (!is_numeric($titleOverride) and $titleOverride != "" and $titleOverride != "all") { // we can pass in a text title for the form, and that will cause the $titleOverride "all" behaviour to be invoked, and meanwhile we will use this title for the top of the form $passedInTitle = $titleOverride; $titleOverride = "all"; } //syntax: //displayform($formframe, $entry, $mainform) //$formframe is the id of the form OR title of the form OR name of the framework. Can also be an array. If it is an array, then flag 'formframe' is the $formframe variable, and flag 'elements' is an array of all the elements that are to be displayed. //the array option is intended for displaying only part of a form at a time //$entry is the numeric entry to display in the form -- if $entry is the word 'proxy' then it is meant to force a new form entry when the form is a single-entry form that the user already may have an entry in //$mainform is the starting form to use, if this is a framework (can be specified by form id or by handle) //$done_dest is the URL to go to after the form has been submitted //Steps: //1. identify form or framework //2. if framework, check for unified display options //3. if entry specified, then get data for that entry //4. drawform with data if necessary global $xoopsDB, $xoopsUser, $myts; global $sfidsDrawn; if (!is_array($sfidsDrawn)) { $sfidsDrawn = array(); } $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); $original_entry = $entry; // flag used to tell whether the function was called with an actual entry specified, ie: we're supposed to be editing this entry, versus the entry being set by coming back form a sub_form or other situation. $mid = getFormulizeModId(); $currentURL = getCurrentURL(); /* Alter currentURL if necessary. * Display list of entries screen on-click of form buttons "Save and Leave" and "Leave Page". */ if (isset($_GET['sid'])) { $curr_screen = xoops_getmodulehandler('screen', 'formulize')->get($_GET['sid']); if ($curr_screen->getVar('type') == 'form') { $currentURL = $_SERVER['PHP_SELF'] . "?fid=" . $curr_screen->form_id(); } } elseif (isset($_GET['ve']) && isset($_GET['fid'])) { $currentURL = $_SERVER['PHP_SELF'] . "?fid=" . $_GET['fid']; } // identify form or framework $elements_allowed = ""; // if a screen object is passed in, select the elements for display based on the screen's settings if ($screen and is_a($screen, "formulizeFormScreen")) { $elements_allowed = $screen->getVar("formelements"); } if (is_array($formframe)) { $elements_allowed = $formframe['elements']; $printViewPages = isset($formframe['pages']) ? $formframe['pages'] : ""; $printViewPageTitles = isset($formframe['pagetitles']) ? $formframe['pagetitles'] : ""; $formframetemp = $formframe['formframe']; unset($formframe); $formframe = $formframetemp; } list($fid, $frid) = getFormFramework($formframe, $mainform); if ($_POST['deletesubsflag']) { // if deletion of sub entries requested foreach ($_POST as $k => $v) { if (strstr($k, "delbox")) { $subs_to_del[] = $v; } } if (count($subs_to_del) > 0) { deleteFormEntries($subs_to_del, intval($_POST['deletesubsflag'])); // deletesubsflag will be the sub form id sendNotifications($_POST['deletesubsflag'], "delete_entry", $subs_to_del, $mid, $groups); } } if ($_POST['parent_form']) { // if we're coming back from a subform $entry = $_POST['parent_entry']; $fid = $_POST['parent_form']; } if ($_POST['go_back_form']) { // we just received a subform submission $entry = $_POST['sub_submitted']; $fid = $_POST['sub_fid']; $go_back['form'] = $_POST['go_back_form']; $go_back['entry'] = $_POST['go_back_entry']; } // set $entry in the case of a form_submission where we were editing an entry (just in case that entry is not what is used to call this function in the first place -- ie: we're on a subform and the mainform has no entry specified, or we're clicking submit over again on a single-entry form where we started with no entry) $entrykey = "entry" . $fid; if ((!$entry or $entry == "proxy") and $_POST[$entrykey]) { // $entrykey will only be set when *editing* an entry, not on new saves $entry = $_POST[$entrykey]; } // this is probably not necessary any more, due to architecture changes in Formulize 3 // formulize_newEntryIds is set when saving data if (!$entry and isset($GLOBALS['formulize_newEntryIds'][$fid])) { $entry = $GLOBALS['formulize_newEntryIds'][$fid][0]; } $member_handler =& xoops_gethandler('member'); $gperm_handler =& xoops_gethandler('groupperm'); if ($profileForm === "new") { // spoof the $groups array based on the settings for the regcode that has been validated by register.php $reggroupsq = q("SELECT reg_codes_groups FROM " . XOOPS_DB_PREFIX . "_reg_codes WHERE reg_codes_code=\"" . $GLOBALS['regcode'] . "\""); $groups = explode("&8(%\$", $reggroupsq[0]['reg_codes_groups']); if ($groups[0] === "") { unset($groups); } // if a code has no groups associated with it, then kill the null value that will be in position 0 in the groups array. $groups[] = XOOPS_GROUP_USERS; $groups[] = XOOPS_GROUP_ANONYMOUS; } $uid = $xoopsUser ? $xoopsUser->getVar('uid') : '0'; $single_result = getSingle($fid, $uid, $groups, $member_handler, $gperm_handler, $mid); $single = $single_result['flag']; // if we're looking at a single entry form with no entry specified and where the user has no entry of their own, or it's an anonymous user, then set the entry based on a cookie if one is present // want to do this check here and override $entry prior to the security check since we don't like trusting cookies! $cookie_entry = (isset($_COOKIE['entryid_' . $fid]) and !$entry and $single and ($single_result['entry'] == "" or intval($uid) === 0)) ? $_COOKIE['entryid_' . $fid] : ""; include_once XOOPS_ROOT_PATH . "/modules/formulize/class/data.php"; $data_handler = new formulizeDataHandler($fid); if ($cookie_entry) { // check to make sure the cookie_entry exists... //$check_cookie_entry = q("SELECT id_req FROM " . $xoopsDB->prefix("formulize_form") . " WHERE id_req=" . intval($cookie_entry)); //if($check_cookie_entry[0]['id_req'] > 0) { if ($data_handler->entryExists(intval($cookie_entry))) { $entry = $cookie_entry; } else { $cookie_entry = ""; } } $owner = ($cookie_entry and $uid) ? $uid : getEntryOwner($entry, $fid); // if we're pulling a cookie value and there is a valid UID in effect, then assume this user owns the entry, otherwise, figure out who does own the entry $owner_groups = $data_handler->getEntryOwnerGroups($entry); if ($single and !$entry and !$overrideMulti and $profileForm !== "new") { // only adjust the active entry if we're not already looking at an entry, and there is no overrideMulti which can be used to display a new blank form even on a single entry form -- useful for when multiple anonymous users need to be able to enter information in a form that is "one per user" for registered users. -- the pressence of a cookie on the hard drive of a user will override other settings $entry = $single_result['entry']; $owner = getEntryOwner($entry, $fid); unset($owner_groups); //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE); $owner_groups = $data_handler->getEntryOwnerGroups($entry); } if ($entry == "proxy") { $entry = ""; } // convert the proxy flag to the actual null value expected for new entry situations (do this after the single check!) $editing = is_numeric($entry); // will be true if there is an entry we're looking at already if (!($scheck = security_check($fid, $entry, $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms and !$profileForm) { print "<p>" . _NO_PERM . "</p>"; return; } // main security check passed, so let's initialize flags $go_back['url'] = substr($done_dest, 0, 1) == "/" ? XOOPS_URL . $done_dest : $done_dest; // set these arrays for the one form, and they are added to by the framework if it is in effect $fids[0] = $fid; if ($entry) { $entries[$fid][0] = $entry; } else { $entries[$fid][0] = ""; } if ($frid) { $linkResults = checkForLinks($frid, $fids, $fid, $entries, $gperm_handler, $owner_groups, $mid, $member_handler, $owner, true); // final true means only include entries from unified display linkages unset($entries); unset($fids); $fids = $linkResults['fids']; $entries = $linkResults['entries']; $sub_fids = $linkResults['sub_fids']; $sub_entries = $linkResults['sub_entries']; } // need to handle submission of entries $formulize_mgr =& xoops_getmodulehandler('elements', 'formulize'); $info_received_msg = 0; $info_continue = 0; if ($entries[$fid][0]) { $info_continue = 1; } $add_own_entry = $gperm_handler->checkRight("add_own_entry", $fid, $groups, $mid); $add_proxy_entries = $gperm_handler->checkRight("add_proxy_entries", $fid, $groups, $mid); if ($_POST['form_submitted'] and $profileForm !== "new" and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $info_received_msg = "1"; // flag for display of info received message if (!isset($GLOBALS['formulize_readElementsWasRun'])) { include_once XOOPS_ROOT_PATH . "/modules/formulize/include/readelements.php"; } $temp_entries = $GLOBALS['formulize_allWrittenEntryIds']; // set in readelements.php if (!$formElementsOnly and ($single or $_POST['target_sub'] or $entries[$fid][0] and ($original_entry or $_POST[$entrykey] and !$_POST['back_from_sub']) or $overrideMulti or $_POST['go_back_form'] and $overrideSubMulti)) { // if we just did a submission on a single form, or we just edited a multi, then assume the identity of the new entry. Can be overridden by values passed to this function, to force multi forms to redisplay the just-saved entry. Back_from_sub is used to override the override, when we're saving after returning from a multi-which is like editing an entry since entries are saved prior to going to a sub. -- Sept 4 2006: adding an entry in a subform forces us to stay on the same page too! -- Dec 21 2011: added check for !$formElementsOnly so that when we're getting just the elements in the form, we ignore any possible overriding, since that is an API driven situation where the called entry is the only one we want to display, period. $entry = $temp_entries[$fid][0]; unset($entries); foreach ($fids as $thisWrittenFid) { $entries[$thisWrittenFid] = $temp_entries[$thisWrittenFid]; } // also remove any fids that aren't part of the $temp_entries...added Oct 26 2011...checkforlinks now can return the mainform when we're on a sub! It's smarter, but displayForm (and possibly other places) were not built to assume it was that smart. $writtenFids = array_keys($temp_entries); $fids = array_intersect($fids, $writtenFids); $owner = getEntryOwner($entry, $fid); unset($owner_groups); $owner_groups = $data_handler->getEntryOwnerGroups($entry); //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE); $info_continue = 1; } elseif (!$_POST['target_sub']) { // as long as the form was submitted and we're not going to a sub form, then display the info received message and carry on with a blank form if (!$original_entry) { // if we're on a multi-form where the display form function was called without an entry, then clear the entries and behave as if we're doing a new add unset($entries); unset($sub_entries); $entries[$fid][0] = ""; $sub_entries[$sub_fids[0]][0] = ""; } $info_continue = 2; } } $sub_entries_synched = synchSubformBlankDefaults($fid, $entry); foreach ($sub_entries_synched as $synched_sfid => $synched_ids) { foreach ($synched_ids as $synched_id) { $sub_entries[$synched_sfid][] = $synched_id; } } if (count($sub_entries_synched) > 0) { formulize_updateDerivedValues($entry, $fid, $frid); } // special use of $settings added August 2 2006 -- jwe -- break out of form if $settings so indicates // used to allow saving of information when you don't want the form itself to reappear if ($settings == "{RETURNAFTERSAVE}" and $_POST['form_submitted']) { return "returning_after_save"; } // need to add code here to switch some things around if we're on a subform for the first time (add) // note: double nested sub forms will not work currently, since on the way back to the intermediate level, the go_back values will not be set correctly // target_sub is only set when adding a sub entry, and adding sub entries is now down by the subform ui //if($_POST['target_sub'] OR $_POST['goto_sfid']) { if ($_POST['goto_sfid']) { $info_continue = 0; if ($_POST['goto_sfid']) { $new_fid = $_POST['goto_sfid']; } else { $new_fid = $_POST['target_sub']; } $go_back['form'] = $fid; $go_back['entry'] = $temp_entries[$fid][0]; unset($entries); unset($fids); unset($sub_fids); unset($sub_entries); $fid = $new_fid; $fids[0] = $new_fid; if ($_POST['target_sub']) { // if we're adding a new entry $entries[$new_fid][0] = ""; } else { // if we're going to an existing entry $entries[$new_fid][0] = $_POST['goto_sub']; } $entry = $entries[$new_fid][0]; $single_result = getSingle($fid, $uid, $groups, $member_handler, $gperm_handler, $mid); $single = $single_result['flag']; if ($single and !$entry) { $entry = $single_result['entry']; unset($entries); $entries[$fid][0] = $entry; } unset($owner); $owner = getEntryOwner($entries[$new_fid][0], $new_fid); $editing = is_numeric($entry); unset($owner_groups); //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE); $newFidData_handler = new formulizeDataHandler($new_fid); $owner_groups = $newFidData_handler->getEntryOwnerGroups($entries[$new_fid][0]); $info_received_msg = 0; // never display this message when a subform is displayed the first time. if ($entry) { $info_continue = 1; } if (!($scheck = security_check($fid, $entries[$fid][0], $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms) { print "<p>" . _NO_PERM . "</p>"; return; } } // there are several points above where $entry is set, and now that we have a final value, store in ventry if ($entry > 0 and (!isset($settings['ventry']) or "addnew" != $settings['ventry'])) { $settings['ventry'] = $entry; } // set the alldoneoverride if necessary -- August 22 2006 $config_handler =& xoops_gethandler('config'); $formulizeConfig = $config_handler->getConfigsByCat(0, $mid); // remove the all done button if the config option says 'no', and we're on a single-entry form, or the function was called to look at an existing entry, or we're on an overridden Multi-entry form $allDoneOverride = (!$formulizeConfig['all_done_singles'] and !$profileForm and (($single or $overrideMulti or $original_entry) and !$_POST['target_sub'] and !$_POST['goto_sfid'] and !$_POST['deletesubsflag'] and !$_POST['parent_form'])) ? true : false; if (($allDoneOverride or isset($_POST['save_and_leave']) and $_POST['save_and_leave']) and $_POST['form_submitted']) { drawGoBackForm($go_back, $currentURL, $settings, $entry); print "<script type=\"text/javascript\">window.document.go_parent.submit();</script>\n"; return; } else { // only do all this stuff below, the normal form displaying stuff, if we are not leaving this page now due to the all done button being overridden // we cannot have the back logic above invoked when dealing with a subform, but if the override is supposed to be in place, then we need to invoke it if (!$allDoneOverride and !$formulizeConfig['all_done_singles'] and !$profileForm and ($_POST['target_sub'] or $_POST['goto_sfid'] or $_POST['deletesubsflag'] or $_POST['parent_form']) and ($single or $original_entry or $overrideMulti)) { $allDoneOverride = true; } /*if($uid==1) { print "Forms: "; print_r($fids); print "<br>Entries: "; print_r($entries); print "<br>Subforms: "; print_r($sub_fids); print "<br>Subentries: "; print_r($sub_entries); // debug block - ONLY VISIBLE TO USER 1 RIGHT NOW } */ formulize_benchmark("Ready to start building form."); $title = ""; foreach ($fids as $this_fid) { if (!($scheck = security_check($this_fid, $entries[$this_fid][0], $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms) { continue; } // if there is more than one form, try to make the 1-1 links // and if we made any, then include the newly linked up entries // in the index of entries that we're keeping track of if (count($fids) > 1) { list($form1s, $form2s, $form1EntryIds, $form2EntryIds) = formulize_makeOneToOneLinks($frid, $this_fid); foreach ($form1EntryIds as $i => $form1EntryId) { // $form1EntryId set above, now set other values for this iteration based on the key $form2EntryId = $form2EntryIds[$i]; $form1 = $form1s[$i]; $form2 = $form2s[$i]; if ($form1EntryId) { $entries[$form1][0] = $form1EntryId; } if ($form2EntryId) { $entries[$form2][0] = $form2EntryId; } } } unset($prevEntry); // if there is an entry, then get the data for that entry if ($entries[$this_fid]) { $groupEntryWithUpdateRights = ($single == "group" and $gperm_handler->checkRight("update_own_entry", $fid, $groups, $mid) and $entry == $single_result['entry']); $prevEntry = getEntryValues($entries[$this_fid][0], $formulize_mgr, $groups, $this_fid, $elements_allowed, $mid, $uid, $owner, $groupEntryWithUpdateRights); } // display the form //get the form title: (do only once) $firstform = 0; if (!$form) { $firstform = 1; $title = isset($passedInTitle) ? $passedInTitle : trans(getFormTitle($this_fid)); if ($screen) { $title = trans($screen->getVar('title')); } unset($form); if ($formElementsOnly) { $form = new formulize_elementsOnlyForm($title, 'formulize', "{$currentURL}", "post", true); } else { // extended class that puts formulize element names into the tr tags for the table, so we can show/hide them as required $form = new formulize_themeForm($title, 'formulize', "{$currentURL}", "post", true); // necessary to trigger the proper reloading of the form page, until Done is called and that form does not have this flag. if (!isset($settings['ventry'])) { $settings['ventry'] = 'new'; } $form->addElement(new XoopsFormHidden('ventry', $settings['ventry'])); } $form->setExtra("enctype='multipart/form-data'"); // impératif! if (is_array($settings)) { $form = writeHiddenSettings($settings, $form); } // include who the entry belongs to and the date // include acknowledgement that information has been updated if we have just done a submit // form_meta includes: last_update, created, last_update_by, created_by $breakHTML = ""; if (!$profileForm and $titleOverride != "all") { // build the break HTML and then add the break to the form if (!strstr($currentURL, "printview.php")) { $breakHTML .= "<center class=\"no-print\">"; $breakHTML .= "<p><b>"; if ($info_received_msg) { $breakHTML .= _formulize_INFO_SAVED . " "; } if ($info_continue == 1 and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $breakHTML .= "<p class=\"no-print\">" . _formulize_INFO_CONTINUE1 . "</p>"; } elseif ($info_continue == 2) { $breakHTML .= "<p class=\"no-print\">" . _formulize_INFO_CONTINUE2 . "</p>"; } elseif (!$entry and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $breakHTML .= "<p class=\"no-print\">" . _formulize_INFO_MAKENEW . "</p>"; } $breakHTML .= "</b></p>"; $breakHTML .= "</center>"; } $breakHTML .= "<table cellpadding=5 width=100%><tr><td width=50% style=\"vertical-align: bottom;\">"; $breakHTML .= "<p><b>" . _formulize_FD_ABOUT . "</b><br>"; if ($entries[$this_fid][0]) { $form_meta = getMetaData($entries[$this_fid][0], $member_handler, $this_fid); $breakHTML .= _formulize_FD_CREATED . $form_meta['created_by'] . " " . formulize_formatDateTime($form_meta['created']) . "<br>" . _formulize_FD_MODIFIED . $form_meta['last_update_by'] . " " . formulize_formatDateTime($form_meta['last_update']) . "</p>"; } else { $breakHTML .= _formulize_FD_NEWENTRY . "</p>"; } $breakHTML .= "</td><td width=50% style=\"vertical-align: bottom;\">"; if (strstr($currentURL, "printview.php") or !formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $breakHTML .= "<p>"; } else { // get save and button button options $save_button_text = ""; $done_button_text = ""; if (is_array($button_text)) { $save_button_text = $button_text[1]; $done_button_text = $button_text[0]; } else { $done_button_text = $button_text; } if (!$done_button_text and !$allDoneOverride) { $done_button_text = _formulize_INFO_DONE1 . _formulize_DONE . _formulize_INFO_DONE2; } elseif ($done_button_text != "{NOBUTTON}" and !$allDoneOverride) { $done_button_text = _formulize_INFO_DONE1 . $done_button_text . _formulize_INFO_DONE2; // check to see if the user is allowed to modify the existing entry, and if they're not, then we have to draw in the all done button so they have a way of getting back where they're going } elseif ($entry and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry) or !$entry) { $done_button_text = ""; } else { $done_button_text = _formulize_INFO_DONE1 . _formulize_DONE . _formulize_INFO_DONE2; } $nosave = false; if (!$save_button_text and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $save_button_text = _formulize_INFO_SAVEBUTTON; } elseif ($save_button_text != "{NOBUTTON}" and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $save_button_text = _formulize_INFO_SAVE1 . $save_button_text . _formulize_INFO_SAVE2; } else { $save_button_text = _formulize_INFO_NOSAVE; $nosave = true; } $breakHTML .= "<p class='no-print'>" . $save_button_text; if ($done_button_text) { $breakHTML .= "<br>" . $done_button_text; } } $breakHTML .= "</p></td></tr></table>"; $form->insertBreak($breakHTML, "even"); } elseif ($profileForm) { // if we have a profile form, put the profile fields at the top of the form, populated based on the DB values from the _users table $form = addProfileFields($form, $profileForm); } } if ($titleOverride == "1" and !$firstform) { // set onetooneTitle flag to 1 when function invoked to force drawing of the form title over again $title = trans(getFormTitle($this_fid)); $form->insertBreak("<table><th>{$title}</th></table>", ""); } // if this form has a parent, then determine the $parentLinks if ($go_back['form'] and !$parentLinks[$this_fid]) { $parentLinks[$this_fid] = getParentLinks($this_fid, $frid); } formulize_benchmark("Before Compile Elements."); $form = compileElements($this_fid, $form, $formulize_mgr, $prevEntry, $entries[$this_fid][0], $go_back, $parentLinks[$this_fid], $owner_groups, $groups, $overrideValue, $elements_allowed, $profileForm, $frid, $mid, $sub_entries, $sub_fids, $member_handler, $gperm_handler, $title, $screen, $printViewPages, $printViewPageTitles); formulize_benchmark("After Compile Elements."); } // end of for each fids if (!is_object($form)) { exit("Error: the form cannot be displayed. Does the current group have permission to access the form?"); } // DRAW IN THE SPECIAL UI FOR A SUBFORM LINK (ONE TO MANY) if (count($sub_fids) > 0) { // if there are subforms, then draw them in...only once we have a bonafide entry in place already // draw in special params for this form, but only once per page global $formulize_subformHiddenFieldsDrawn; if ($formulize_subformHiddenFieldsDrawn != true) { $formulize_subformHiddenFieldsDrawn = true; $form->addElement(new XoopsFormHidden('target_sub', '')); $form->addElement(new XoopsFormHidden('target_sub_instance', '')); $form->addElement(new XoopsFormHidden('numsubents', 1)); $form->addElement(new XoopsFormHidden('del_subs', '')); $form->addElement(new XoopsFormHidden('goto_sub', '')); $form->addElement(new XoopsFormHidden('goto_sfid', '')); } foreach ($sub_fids as $subform_id) { // only draw in the subform UI if the subform hasn't been drawn in previously, courtesy of a subform element in the form. // Subform elements are recommended since they provide 1. specific placement, 2. custom captions, 3. direct choice of form elements to include if (in_array($subform_id, $sfidsDrawn) or $elements_allowed or !($scheck = security_check($subform_id, "", $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms) { // no entry passed so this will simply check whether they have permission for the form or not continue; } $subUICols = drawSubLinks($subform_id, $sub_entries, $uid, $groups, $frid, $mid, $fid, $entry); unset($subLinkUI); if (isset($subUICols['single'])) { $form->insertBreak($subUICols['single'], "even"); } else { $subLinkUI = new XoopsFormLabel($subUICols['c1'], $subUICols['c2']); $form->addElement($subLinkUI); } } } // draw in proxy box if necessary (only if they have permission and only on new entries, not on edits) if (!strstr($_SERVER['PHP_SELF'], "formulize/printview.php")) { if ($gperm_handler->checkRight("add_proxy_entries", $fid, $groups, $mid) and !$entries[$fid][0]) { $form = addOwnershipList($form, $groups, $member_handler, $gperm_handler, $fid, $mid); } elseif ($entries[$fid][0] and $gperm_handler->checkRight("update_entry_ownership", $fid, $groups, $mid)) { $form = addOwnershipList($form, $groups, $member_handler, $gperm_handler, $fid, $mid, $entries[$fid][0]); } } // draw in the submitbutton if necessary if (!$formElementsOnly and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) { $form = addSubmitButton($form, _formulize_SAVE, $go_back, $currentURL, $button_text, $settings, $temp_entries[$this_fid][0], $fids, $formframe, $mainform, $entry, $profileForm, $elements_allowed, $allDoneOverride, $printall, $screen); } if (!$formElementsOnly) { // add flag to indicate that the form has been submitted $form->addElement(new XoopsFormHidden('form_submitted', "1")); if ($go_back['form']) { // if this is set, then we're doing a subform, so put in a flag to prevent the parent from being drawn again on submission $form->addElement(new XoopsFormHidden('sub_fid', $fid)); $form->addElement(new XoopsFormHidden('sub_submitted', $entries[$fid][0])); $form->addElement(new XoopsFormHidden('go_back_form', $go_back['form'])); $form->addElement(new XoopsFormHidden('go_back_entry', $go_back['entry'])); } else { // drawing a main form...put in the scroll position flag $form->addElement(new XoopsFormHidden('yposition', 0)); } // saving message print "<div id=savingmessage style=\"display: none; position: absolute; width: 100%; right: 0px; text-align: center; padding-top: 50px;\">\n"; global $xoopsConfig; if (file_exists(XOOPS_ROOT_PATH . "/modules/formulize/images/saving-" . $xoopsConfig['language'] . ".gif")) { print "<img src=\"" . XOOPS_URL . "/modules/formulize/images/saving-" . $xoopsConfig['language'] . ".gif\">\n"; } else { print "<img src=\"" . XOOPS_URL . "/modules/formulize/images/saving-english.gif\">\n"; } print "</div>\n"; drawJavascript($nosave); if (count($GLOBALS['formulize_renderedElementHasConditions']) > 0) { drawJavascriptForConditionalElements($GLOBALS['formulize_renderedElementHasConditions'], $entries, $sub_entries); } print $form->addElement(new xoopsFormHidden('save_and_leave', 0)); // lastly, put in a hidden element, that will tell us what the first, primary form was that we were working with on this form submission $form->addElement(new XoopsFormHidden('primaryfid', $fids[0])); } global $formulize_governingElements; global $formulize_oneToOneElements; global $formulize_oneToOneMetaData; if (!is_array($formulize_governingElements)) { $formulize_governingElements = array(); } if (!is_array($formulize_oneToOneElements)) { $oneToOneElements = array(); } if (!is_array($oneToOneMetaData)) { $oneToOneMetaData = array(); } if (count($GLOBALS['formulize_renderedElementHasConditions']) > 0) { $governingElements1 = compileGoverningElementsForConditionalElements($GLOBALS['formulize_renderedElementHasConditions'], $entries, $sub_entries); foreach ($governingElements1 as $key => $value) { $oneToOneElements[$key] = false; } $formulize_governingElements = mergeGoverningElements($formulize_governingElements, $governingElements1); } // add in any onetoone elements that we need to deal with at the same time (in case their joining key value changes on the fly) if (count($fids) > 1) { $i = 1; while ($i <= count($fids)) { $relationship_handler = xoops_getmodulehandler('frameworks', 'formulize'); $relationship = $relationship_handler->get($frid); foreach ($relationship->getVar('links') as $thisLink) { if ($thisLink->getVar('form1') == $fids[$i]) { $keyElement = $thisLink->getVar('key2'); break; } elseif ($thisLink->getVar('form2') == $fids[$i]) { $keyElement = $thisLink->getVar('key1'); break; } } // prepare to loop through elements for the rendered entry, or 'new', if there is no rendered entry $entryToLoop = isset($entries[$fids[$i]][0]) ? $entries[$fids[$i]][0] : null; if (!$entryToLoop and isset($GLOBALS['formulize_renderedElementsForForm'][$fids[$i]]['new'])) { $entryToLoop = 'new'; } foreach ($GLOBALS['formulize_renderedElementsForForm'][$fids[$i]][$entryToLoop] as $renderedMarkupName => $thisElement) { $GLOBALS['formulize_renderedElementHasConditions'][$renderedMarkupName] = $thisElement; $governingElements2 = _compileGoverningElements($entries, _getElementObject($keyElement), $renderedMarkupName); foreach ($governingElements2 as $key => $value) { $formulize_oneToOneElements[$key] = true; $formulize_oneToOneMetaData[$key] = array('onetoonefrid' => $frid, 'onetoonefid' => $fid, 'onetooneentries' => urlencode(serialize($entries)), 'onetoonefids' => urlencode(serialize($fids))); } $formulize_governingElements = mergeGoverningElements($formulize_governingElements, $governingElements2); } $i++; } } if (count($formulize_governingElements) > 0 and !$formElementsOnly) { // render this once at the end of rendering the main form! drawJavascriptForConditionalElements($GLOBALS['formulize_renderedElementHasConditions'], $formulize_governingElements, $formulize_oneToOneElements, $formulize_oneToOneMetaData); } $idForForm = $formElementsOnly ? "" : "id=\"formulizeform\""; // when rendering disembodied forms, don't use the master id! print "<div {$idForForm}>" . $form->render() . "</div><!-- end of formulizeform -->"; // note, security token is included in the form by the xoops themeform render method, that's why there's no explicity references to the token in the compiling/generation of the main form object // floating save button if ($printall != 2 and $formulizeConfig['floatSave'] and !strstr($currentURL, "printview.php") and !$formElementsOnly) { print "<div id=floattest></div>"; if ($done_text != "{NOBUTTON}" or $save_text != "{NOBUTTON}") { print "<div id=floatingsave>"; if ($subButtonText == _formulize_SAVE) { if ($save_text) { $subButtonText = $save_text; } if ($subButtonText != "{NOBUTTON}") { print "<input type='button' name='submitx' id='submitx' class=floatingsavebuttons onclick=javascript:validateAndSubmit(); value='" . _formulize_SAVE . "' >"; print "<input type='button' name='submit_save_and_leave' id='submit_save_and_leave' class=floatingsavebuttons onclick=javascript:validateAndSubmit('leave'); value='" . _formulize_SAVE_AND_LEAVE . "' >"; } } if (($button_text != "{NOBUTTON}" and !$done_text or isset($done_text) and $done_text != "{NOBUTTON}") and !$allDoneOverride) { if ($done_text) { $button_text = $done_text_temp; } print "<input type='button' class=floatingsavebuttons onclick=javascript:verifyDone(); value='" . _formulize_DONE . "' >"; } print "</div>"; } } // end floating save button // if we're in Drupal, include the main XOOPS js file, so the calendar will work if present... // assumption is that the calendar javascript has already been included by the datebox due to no // $xoopsTpl being in effect in Drupal -- this assumption will fail if Drupal is displaying a pageworks // page that uses the $xoopsTpl, for instance. (Date select box file itself checks for $xoopsTpl) global $user; static $includedXoopsJs = false; if (is_object($user) and !$includedXoopsJs) { print "<script type=\"text/javascript\" src=\"" . XOOPS_URL . "/include/xoops.js\"></script>\n"; $includedXoopsJs = true; } } // end of if we're not going back to the prev page because of an all done button override }
function readApplicationData($aid, $apps) { static $i = 1; global $form_handler, $application_handler, $gperm_handler, $screen_handler, $xoopsUser; $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); if ($aid == 0) { $apps[$i]['name'] = _AM_APP_FORMWITHNOAPP; $apps[$i]['content']['description'] = ""; } else { $thisAppObject = $application_handler->get($aid); $apps[$i]['name'] = "Application: " . $thisAppObject->getVar('name'); $apps[$i]['content']['description'] = $thisAppObject->getVar('description'); } $apps[$i]['content']['aid'] = $aid; $formObjects = $form_handler->getFormsByApplication($aid); $x = 0; foreach ($formObjects as $thisFormObject) { $fid = $thisFormObject->getVar('id_form'); // check if the user has edit permission on this form if (!$gperm_handler->checkRight("edit_form", $fid, $groups, getFormulizeModId())) { continue; } $hasDelete = $gperm_handler->checkRight("delete_form", $fid, $groups, getFormulizeModId()); $apps[$i]['content']['forms'][$x]['fid'] = $fid; $apps[$i]['content']['forms'][$x]['name'] = $thisFormObject->getVar('title'); $apps[$i]['content']['forms'][$x]['hasdelete'] = $hasDelete; $apps[$i]['content']['forms'][$x]['lockedform'] = $thisFormObject->getVar('lockedform'); $apps[$i]['content']['forms'][$x]['istableform'] = $thisFormObject->getVar('tableform'); $defaultFormScreen = $thisFormObject->getVar('defaultform'); $defaultListScreen = $thisFormObject->getVar('defaultlist'); $defaultFormObject = $screen_handler->get($defaultFormScreen); $defaultListObject = $screen_handler->get($defaultListScreen); if (is_object($defaultFormObject)) { $defaultFormName = $defaultFormObject->getVar('title'); $apps[$i]['content']['forms'][$x]['defaultformscreenid'] = $defaultFormScreen; $apps[$i]['content']['forms'][$x]['defaultformscreenname'] = $defaultFormName; } if (is_object($defaultListObject)) { $defaultListName = $defaultListObject->getVar('title'); $apps[$i]['content']['forms'][$x]['defaultlistscreenid'] = $defaultListScreen; $apps[$i]['content']['forms'][$x]['defaultlistscreenname'] = $defaultListName; } $apps[$i]['content']['forms'][$x]['form'] = $thisFormObject; $x++; } $apps[$i]['header'] = '<span class="formulize-toolbar right-toolbar">'; if ($aid > 0) { $apps[$i]['header'] .= '<a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=application&aid=' . $aid . '&tab=settings"><i class="icon-config"></i> Settings</a>'; } // menu entries link does not work!! can't pass names with spaces? $apps[$i]['header'] .= '<a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=application&aid=' . $aid . '&tab=forms"><i class="icon-form"></i> Forms</a> <a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=application&aid=' . $aid . '&tab=screens"><i class="icon-screen"></i> Screens</a> <a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=application&aid=' . $aid . '&tab=relationships"><i class="icon-connection"></i> Relationships</a> <a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=application&aid=' . $aid . '&tab=menu%20entries"><i class="icon-menu"></i> Menu Entries</a> <a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=export&aid=' . $aid . '"><i class="icon-download"></i> Export (beta!)</a> <a href="' . XOOPS_URL . '/modules/formulize/admin/ui.php?page=form&aid=' . $aid . '&tab=settings&fid=new"><i class="icon-add"></i> Add a Form</a>'; if ($aid > 0) { $apps[$i]['header'] .= '<a href="" class="deleteapplink" target="' . $aid . '"><i class="icon-delete"></i> Delete</a>'; } $apps[$i]['header'] .= '</span>'; $i++; return $apps; }
function dataExtraction($frame = "", $form, $filter, $andor, $scope, $limitStart, $limitSize, $sortField, $sortOrder, $forceQuery, $mainFormOnly, $includeArchived = false, $id_reqsOnly = false, $resultOnly = false, $filterElements = null) { global $xoopsDB; $limitStart = intval($limitStart); $limitSize = intval($limitSize); $sortField = formulize_db_escape($sortField); if (isset($_GET['debug'])) { $time_start = microtime_float(); } if ($scope == "uid=\"blankscope\"") { return array(); } if (is_numeric($frame)) { $frid = $frame; } elseif ($frame != "") { $frameid = go("SELECT frame_id FROM " . DBPRE . "formulize_frameworks WHERE frame_name='{$frame}'"); $frid = $frameid[0]['frame_id']; unset($frameid); } else { $frid = ""; } if (is_numeric($form)) { $fid = $form; } elseif ($GLOBALS['formulize_versionFourOrHigher'] == false) { $formcheck = go("SELECT ff_form_id FROM " . DBPRE . "formulize_framework_forms WHERE ff_frame_id='{$frid}' AND ff_handle='{$form}'"); $fid = $formcheck[0]['ff_form_id']; unset($formcheck); } if (!$fid) { print "Form Name: " . $form . "<br>"; print "Form id: " . $fid . "<br>"; print "Frame Name: " . $frame . "<br>"; print "Frame id: " . $frid . "<br>"; exit("selected form does not exist in framework"); } $form_handler = xoops_getmodulehandler('forms', 'formulize'); $formObject = $form_handler->get($fid); if ($frid and !$mainFormOnly) { // GET THE LINK INFORMATION FOR THE CURRENT FRAMEWORK BASED ON THE REQUESTED FORM $linklist1 = go("SELECT fl_form2_id, fl_key1, fl_key2, fl_relationship, fl_unified_display, fl_common_value FROM " . DBPRE . "formulize_framework_links WHERE fl_frame_id = '{$frid}' AND fl_form1_id = '{$fid}'"); $linklist2 = go("SELECT fl_form1_id, fl_key1, fl_key2, fl_relationship, fl_unified_display, fl_common_value FROM " . DBPRE . "formulize_framework_links WHERE fl_frame_id = '{$frid}' AND fl_form2_id = '{$fid}'"); } // link list 1 is the list of form2s that the requested form links to // link list 2 is the list of form1s that the requested form links to // ie: the link list number denotes the position of the requested form in the pair // print "Frame: $frame ($frid)<br>"; // print "Form: $form ($fid)<br>"; // generate the list of key fields in the current form, so we can use the values in these fields to filter the linked forms. -- sept 27 2005 $linkkeys1 = array(); $linkisparent1 = array(); $linkformids1 = array(); $linktargetids1 = array(); $linkselfids1 = array(); $linkcommonvalue1 = array(); $linkkeys2 = array(); $linkisparent2 = array(); $linkformids2 = array(); $linktargetids2 = array(); $linkselfids2 = array(); $linkcommonvalue2 = array(); if ($frid and !$mainFormOnly) { if (count($linklist1) > 0) { foreach ($linklist1 as $theselinks) { $linkformids1[] = $theselinks['fl_form2_id']; if ($theselinks['fl_key1'] != 0) { $handleforlink = formulize_getElementHandleFromID($theselinks['fl_key1']); $linkkeys1[] = $handleforlink; $linktargetids1[] = $theselinks['fl_key2']; $linkselfids1[] = $theselinks['fl_key1']; } else { $linkkeys1[] = ""; $linktargetids1[] = ""; } if ($theselinks['fl_relationship'] == 2) { // 2 is one to many relationship...this does not appear to be referenced anywhere in the extraction layer! $linkisparent1[] = 1; } else { $linkisparent1[] = 0; } $linkcommonvalue1[] = $theselinks['fl_common_value']; } } if (count($linklist2) > 0) { foreach ($linklist2 as $theselinks) { $linkformids2[] = $theselinks['fl_form1_id']; if ($theselinks['fl_key2'] != 0) { $handleforlink = formulize_getElementHandleFromID($theselinks['fl_key2']); $linkkeys2[] = $handleforlink; $linktargetids2[] = $theselinks['fl_key1']; $linkselfids2[] = $theselinks['fl_key2']; } else { $linkkeys2[] = ""; $linktargetids2[] = ""; } if ($theselinks['fl_relationship'] == 3) { // 3 is many to one relationship...this does not appear to be referenced anywhere in the extraction layer! $linkisparent2[] = 1; } else { $linkisparent2[] = 0; } $linkcommonvalue2[] = $theselinks['fl_common_value']; } } $linkkeys = array_merge($linkkeys1, $linkkeys2); $linkisparent = array_merge($linkisparent1, $linkisparent2); $linkformids = array_merge($linkformids1, $linkformids2); $linktargetids = array_merge($linktargetids1, $linktargetids2); $linkselfids = array_merge($linkselfids1, $linkselfids2); $linkcommonvalue = array_merge($linkcommonvalue1, $linkcommonvalue2); } else { $linkkeys = ""; $linkisparent = ""; $linkformids = array(); $linktargetids = ""; $linkselfids = ""; $linkcommonvalue = ""; } //print_r( $linkformids ); $GLOBALS['formulize_linkformidsForCalcs'] = $linkformids; // now that we have the full details from the framework, figure out the full SQL necessary to get the entire dataset // This whole approach is predicated on being able to do reliable joins between the key fields of each form // Structure of the SQL should be... // SELECT main.entry_id, main.creation_uid, main.mod_uid, main.creation_datetime, main.mod_datetime, main.handle1...main.handleN, f2.entry_id, f2.1..f2.n, etc FROM formulize_A AS main [join syntax] WHERE main.handle1 = "whatever" AND/OR f2.handle1 = "whatever" // Join syntax: if there are query terms on the f2 or subsequent forms, then use INNER JOIN formulize_B AS f2 ON main.1 LIKE CONCAT('%,', f2.entry_id, ',%') -- or no %, ,% if only one value is allowed // If there are no query terms on the f2 or subsequent forms, then use LEFT JOIN // establish the join type and all that $joinText = ""; $linkSelect = ""; $exportOverrideQueries = array(); $limitClause = ""; if ($limitSize) { $limitClause = " LIMIT {$limitStart}, {$limitSize} "; } if (is_array($filter) or substr($filter, 0, 6) != "SELECT" and substr($filter, 0, 6) != "INSERT") { // if the filter is not itself a fully formed SQL statement... $scopeFilter = ""; if (is_array($scope)) { // assume any arrays are groupid arrays, and so make a valid scope string based on this. Use the new entry owner table. if (count($scope) > 0) { $start = true; foreach ($scope as $groupid) { // need to loop through the array, and not use implode, so we can sanitize the values if (!$start) { $scopeFilter .= " OR scope.groupid=" . intval($groupid); } else { $start = false; $scopeFilter = " AND EXISTS(SELECT 1 FROM " . DBPRE . "formulize_entry_owner_groups AS scope WHERE (scope.entry_id=main.entry_id AND scope.fid=" . intval($fid) . ") AND (scope.groupid=" . intval($groupid); } } $scopeFilter .= ")) "; // need two closing brackets for the exists statement and its where clause } else { // no valid entries found, so show no entries $scopeFilter = " AND main.entry_id<0 "; } } elseif ($scope) { // need to handle old "uid = X OR..." syntax $scopeFilter = " AND (" . str_replace("uid", "main.creation_uid", $scope) . ") "; } formulize_getElementMetaData("", false, $fid); // initialize the element metadata for this form...serious performance gain from this list($formFieldFilterMap, $whereClause, $orderByClause, $oneSideFilters, $otherPerGroupFilterJoins, $otherPerGroupFilterWhereClause) = formulize_parseFilter($filter, $andor, $linkformids, $fid, $frid); // *********************** // NOTE: the oneSideFilters are divided into two sections, the AND filters and OR filters for a given form // These will need to be constructed differently if we are ever to support OR filters that are spread across forms. // Right now, oneSideFilters get rendered with all other filters for their form, which is fine if the OR filters all belong to the same form // But if there are OR filters on two different forms, then we will need to do some kind of much more complex handling of the OR filters, or else the count query, and the queries for calculations, will be screwed up // The proper approach to this would be to have the AND oneSideFilters divided by form, like now, but for the ORs, we would need to loop through all ORs on all forms at once, and concatenate them somehow, ie: // foreach($oneSideFilters as $thisOneSideFid=>$oneSideFilterData) { // foreach($oneSideFilterData as $oneSideAndOr=>$thisOneSideFilter) { // if($oneSideAndOr == "and") { // note, it's forced to lowercase in the parseFilter function // // then add this filter to the exists/other construction/whatever for this particular form // } else { // // then add this filter to a more complex exists/other construction/whatever that contains all the ORs, grouped by form, with ORs in between them // // ie, the final output would be like: AND ( exists(select 1 from table1 where field11=x or field12=y) OR exists(select 1 from table2 where field21 LIKE '%t%') OR (exists(select 1 from table3 where field31 > 23) ) // // And this entire construction would be then added to queries, to account properly for all the OR operators that had been requested // } // } // } // NOTE: Oct 17 2011 -- since we are now splitting multiform queries into may different individual collections of entries, it may be possible to do what's suggested above more easily. However, we still need the full where clause at our disposal in the main query that gets the main form entry ids, or else we'll have an incorrect master list of entry ids to return. :-( // *********************** if (isset($oneSideFilters[$fid])) { foreach ($oneSideFilters[$fid] as $thisOneSideFilter) { $mainFormWhereClause .= " AND ( {$thisOneSideFilter} ) "; } } else { $mainFormWhereClause = ""; } if ($whereClause) { $whereClause = "AND {$whereClause}"; } // create the per-group filters, if any, that apply to this user...only available when all XOOPS is invoked, not available when extract.php is being direct included global $xoopsDB; $perGroupFilter = ""; $perGroupFiltersPerForms = array(); // used with exists clauses and other per-form situations if ($xoopsDB) { $form_handler = xoops_getmodulehandler('forms', 'formulize'); $perGroupFilter = $form_handler->getPerGroupFilterWhereClause($fid, "main"); $perGroupFiltersPerForms[$fid] = $perGroupFilter; if ($frid) { foreach ($linkformids as $id => $thisLinkFid) { $perGroupFiltersPerForms[$thisLinkFid] = $form_handler->getPerGroupFilterWhereClause($thisLinkFid, "f" . $id); } } } if ($frid) { $joinHandles = formulize_getJoinHandles(array(0 => $linkselfids, 1 => $linktargetids)); // get the element handles for these elements, since we need those to properly construct the join clauses $newJoinText = ""; // "new" variables initilized in each loop $joinTextIndex = array(); $joinTextTableRef = array(); $linkSelectIndex = array(); $newexistsJoinText = ""; $joinText = ""; // not "new" variables persist (with .= operator) $existsJoinText = ""; foreach ($linkformids as $id => $linkedFid) { // validate that the join conditions are valid...either both must have a value, or neither must have a value (match on user id)...otherwise the join is not possible if ($joinHandles[$linkselfids[$id]] and $joinHandles[$linktargetids[$id]] or $linkselfids[$id] == '' and $linktargetids[$id] == '') { formulize_getElementMetaData("", false, $linkedFid); // initialize the element metadata for this form...serious performance gain from this $linkSelectIndex[$linkedFid] = "f{$id}.entry_id AS f" . $id . "_entry_id, f{$id}.creation_uid AS f" . $id . "_creation_uid, f{$id}.mod_uid AS f" . $id . "_mod_uid, f{$id}.creation_datetime AS f" . $id . "_creation_datetime, f{$id}.mod_datetime AS f" . $id . "_mod_datetime, f{$id}.*"; $linkSelect .= ", f{$id}.entry_id AS f" . $id . "_entry_id, f{$id}.creation_uid AS f" . $id . "_creation_uid, f{$id}.mod_uid AS f" . $id . "_mod_uid, f{$id}.creation_datetime AS f" . $id . "_creation_datetime, f{$id}.mod_datetime AS f" . $id . "_mod_datetime, f{$id}.*"; $joinType = isset($formFieldFilterMap[$linkedFid]) ? "INNER" : "LEFT"; $linkedFormObject = $form_handler->get($linkedFid); $joinTextTableRef[$linkedFid] = DBPRE . "formulize_" . $linkedFormObject->getVar('form_handle') . " AS f{$id} ON "; $joinText .= " {$joinType} JOIN " . DBPRE . "formulize_" . $linkedFormObject->getVar('form_handle') . " AS f{$id} ON"; // NOTE: we are aliasing the linked form tables to f$id where $id is the key of the position in the linked form metadata arrays where that form's info is stored $newexistsJoinText = $existsJoinText ? " {$andor} " : ""; $newexistsJoinText .= " EXISTS(SELECT 1 FROM " . DBPRE . "formulize_" . $linkedFormObject->getVar('form_handle') . " AS f{$id} WHERE "; // set this up also so we have it available for one to many/many to one calculations that require it if ($linkcommonvalue[$id]) { // common value $newJoinText = " main.`" . $joinHandles[$linkselfids[$id]] . "`=f{$id}.`" . $joinHandles[$linktargetids[$id]] . "`"; } elseif ($linktargetids[$id]) { // linked selectbox if ($target_ele_value = formulize_isLinkedSelectBox($linktargetids[$id])) { if ($target_ele_value[1]) { // multiple values allowed $newJoinText = " f{$id}.`" . $joinHandles[$linktargetids[$id]] . "` LIKE CONCAT('%,',main.entry_id,',%')"; } else { // single value only $newJoinText = " f{$id}.`" . $joinHandles[$linktargetids[$id]] . "` = main.entry_id"; } } else { $main_ele_value = formulize_isLinkedSelectBox($linkselfids[$id]); // we know it's linked because this is a linked selectbox join, we just need the ele_value properties if ($main_ele_value[1]) { // multiple values allowed $newJoinText = " main.`" . $joinHandles[$linkselfids[$id]] . "` LIKE CONCAT('%,',f{$id}.entry_id,',%')"; } else { // single value only $newJoinText = " main.`" . $joinHandles[$linkselfids[$id]] . "` = f{$id}.entry_id"; } } } else { // join by uid $newJoinText = " main.creation_uid=f{$id}.creation_uid"; } if (isset($perGroupFiltersPerForms[$linkedFid])) { $newJoinText .= $perGroupFiltersPerForms[$linkedFid]; } $joinTextIndex[$linkedFid] = $newJoinText; $joinText .= $newJoinText; if (count($oneSideFilters[$linkedFid]) > 0) { // only setup the existsJoinText when there is a where clause that applies to this form...otherwise, we don't care, this form is not relevant to the query that the calculations will do (except maybe when the mainform is not the one-side form...but that's another story) $existsJoinText .= $newexistsJoinText . $newJoinText; foreach ($oneSideFilters[$linkedFid] as $thisOneSideFilter) { $thisLinkedFidPerGroupFilter = isset($perGroupFiltersPerForms[$linkedFid]) ? $perGroupFiltersPerForms[$linkedFid] : ""; $existsJoinText .= " AND ( {$thisOneSideFilter} {$thisLinkedFidPerGroupFilter}) "; } $existsJoinText .= ") "; // close the exists clause itself } } } } // specify the join info for user table (depending whether there's a query on creator_email or not) $userJoinType = $formFieldFilterMap['creator_email'] ? "INNER" : "LEFT"; $userJoinText = " {$userJoinType} JOIN " . DBPRE . "users AS usertable ON main.creation_uid=usertable.uid"; $sortIsOnMain = true; if (!$orderByClause and $sortField) { if ($sortField == "creation_uid" or $sortField == "mod_uid" or $sortField == "creation_datetime" or $sortField == "mod_datetime") { $elementMetaData['id_form'] = $fid; } elseif ($sortField == "uid") { $sortField = "creation_uid"; $elementMetaData['id_form'] = $fid; } elseif ($sortField == "proxyid") { $sortField = "mod_uid"; $elementMetaData['id_form'] = $fid; } elseif ($sortField == "creation_date") { $sortField = "creation_datetime"; $elementMetaData['id_form'] = $fid; } elseif ($sortField == "mod_date") { $sortField = "mod_datetime"; $elementMetaData['id_form'] = $fid; } elseif ($sortField == "entry_id") { $sortField = "entry_id"; $elementMetaData['id_form'] = $fid; } else { $elementMetaData = formulize_getElementMetaData($sortField, true); // need to get form that sort field is part of... } $sortFid = $elementMetaData['id_form']; if ($sortFid == $fid) { $sortFidAlias = "main"; } else { $sortFidAlias = array_keys($linkformids, $sortFid); // position of this form in the linking relationships is important for identifying which form alias to use $sortFidAlias = "f" . $sortFidAlias[0]; $sortIsOnMain = false; } $sortFieldMetaData = formulize_getElementMetaData($sortField, true); if ($sortFieldMetaData['ele_encrypt']) { $sortFieldFullValue = "AES_DECRYPT({$sortFidAlias}.`{$sortField}`, '" . getAESPassword() . "')"; // sorts as text, which will screw up number fields } elseif (formulize_isLinkedSelectBox($sortField, true)) { $ele_value = unserialize($sortFieldMetaData['ele_value']); $boxproperties = explode("#*=:*", $ele_value[2]); $target_fid = $boxproperties[0]; $target_element_handle = $boxproperties[1]; $form_handler = xoops_getmodulehandler('forms', 'formulize'); $targetFormObject = $form_handler->get($target_fid); // note you cannot sort by multi select boxes! $sortFieldFullValue = "(SELECT sourceSortForm.`" . $target_element_handle . "` FROM " . DBPRE . "formulize_" . $targetFormObject->getVar('form_handle') . " as sourceSortForm WHERE sourceSortForm.`entry_id` = " . $sortFidAlias . ".`" . $sortField . "`)"; } else { $sortFieldFullValue = "{$sortFidAlias}.`{$sortField}`"; } $orderByClause = " ORDER BY {$sortFieldFullValue} {$sortOrder} "; } elseif (!$orderByClause) { $orderByClause = "ORDER BY main.entry_id"; } debug_memory("Before retrieving mainresults"); //$beforeQueryTime = microtime_float(); $countMasterResults = "SELECT COUNT(main.entry_id) FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main "; $countMasterResults .= "{$userJoinText} {$otherPerGroupFilterJoins} WHERE main.entry_id>0 {$mainFormWhereClause} {$scopeFilter} {$otherPerGroupFilterWhereClause} "; $countMasterResults .= $existsJoinText ? " AND ({$existsJoinText}) " : ""; $countMasterResults .= isset($perGroupFiltersPerForms[$fid]) ? $perGroupFiltersPerForms[$fid] : ""; if (isset($GLOBALS['formulize_getCountForPageNumbers'])) { // If there's an LOE Limit in place, check that we're not over it first global $formulize_LOE_limit; if ($countMasterResultsRes = $xoopsDB->query($countMasterResults)) { $countMasterResultsRow = $xoopsDB->fetchRow($countMasterResultsRes); if ($countMasterResultsRow[0] > $formulize_LOE_limit and $formulize_LOE_limit > 0 and !$forceQuery and !$limitClause) { return $countMasterResultsRow[0]; } else { // if we're in a getData call from displayEntries, put the count in a special place for use in generating page numbers $GLOBALS['formulize_countMasterResultsForPageNumbers'] = $countMasterResultsRow[0]; } } else { exit("Error: could not count master results.<br>" . $xoopsDB->error() . "<br>SQL:{$countMasterResults}<br>"); } unset($GLOBALS['formulize_getCountForPageNumbers']); } // now, if there's framework in effect, get the entry ids of the entries in the main form that match the criteria, so we can use a specific query for them instead of the order clause in the master query $limitByEntryId = ""; $useAsSortSubQuery = ""; if ($frid) { $limitByEntryId = " AND ("; $entryIdQuery = str_replace("COUNT(main.entry_id)", "main.entry_id as main_entry_id", $countMasterResults); // don't count the entries, select their id numbers if (!$sortIsOnMain) { $sortFieldMetaData = formulize_getElementMetaData($sortField, true); $sortFormObject = $form_handler->get($sortFid); if ($sortFieldMetaData['ele_encrypt']) { $useAsSortSubQuery = "(SELECT max(AES_DECRYPT(`{$sortField}`, '" . getAESPassword() . "')) as subsort FROM " . DBPRE . "formulize_" . $sortFormObject->getVar('form_handle') . " as {$sortFidAlias} WHERE " . $joinTextIndex[$sortFid] . " ORDER BY subsort {$sortOrder}) as usethissort"; } else { $useAsSortSubQuery = "(SELECT max(`{$sortField}`) as subsort FROM " . DBPRE . "formulize_" . $sortFormObject->getVar('form_handle') . " as {$sortFidAlias} WHERE " . $joinTextIndex[$sortFid] . " ORDER BY subsort {$sortOrder}) as usethissort"; } $entryIdQuery = str_replace("SELECT main.entry_id as main_entry_id ", "SELECT {$useAsSortSubQuery}, main.entry_id as main_entry_id ", $entryIdQuery); // sorts as text which will screw up number fields $thisOrderByClause = " ORDER BY usethissort {$sortOrder} "; } else { $thisOrderByClause = $orderByClause; } $entryIdQuery .= " {$thisOrderByClause} {$limitClause}"; $entryIdResult = $xoopsDB->query($entryIdQuery); $start = true; while ($entryIdValue = $xoopsDB->fetchArray($entryIdResult)) { $limitByEntryId .= !$start ? " OR " : ""; $limitByEntryId .= "main.entry_id = " . $entryIdValue['main_entry_id']; $start = false; } $limitByEntryId .= ") "; if (!$start) { $limitClause = ""; // nullify the existing limitClause since we don't want to use it in the actual query } else { $limitByEntryId = ""; } } $selectClause = ""; $sqlFilterElements = array(); if ($filterElements) { // THIS IS HIGHLY EXPERIMENTAL...BECAUSE THE PROCESSING OF DATASETS RELIES RIGHT NOW ON METADATA BEING PRESENT AT THE FRONT OF EACH SET OF FIELDS, THERE IS FURTHER WORK REQUIRED TO MAKE THIS FUNCTION WITH THE CODE THAT PROCESSES ENTRIES //print_r( $filterElements ); //print_r( $linkformids ); foreach ($filterElements as $passedForm => $passedElements) { if ($passedForm == $fid) { $formAlias = "main"; } else { $keys = array_keys($linkformids, $passedForm); //print_r( $keys ); $formAlias = "f" . $keys[0]; } foreach ($passedElements as $thisPassedElement) { $sqlFilterElements[] = $formAlias . ".`" . formulize_db_escape($thisPassedElement) . "`"; } } } if (count($sqlFilterElements) > 0) { $selectClause = implode(",", $sqlFilterElements); } else { $selectClause = "main.entry_id AS main_entry_id, main.creation_uid AS main_creation_uid, main.mod_uid AS main_mod_uid, main.creation_datetime AS main_creation_datetime, main.mod_datetime AS main_mod_datetime, main.* {$linkSelect}"; } // if this is being done for gathering calculations, and the calculation is requested on the one side of a one to many/many to one relationship, then we will need to use different SQL to avoid duplicate values being returned by the database // note: when the main form is on the many side of the relationship, then we need to do something rather different...not sure what it is yet...the SQL as prepared is based on the calculation field and the main form being the one side (and so both are called main), but when field is on one side and main form is many side, then the aliases don't match, and scopefilter issues abound. // NOTE: Oct 17 2011 - the $oneSideSQL is also used when there are multiple linked subforms, since the exists structure is efficient compared to multiple joins $oneSideSQL = " FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main {$userJoinText} WHERE main.entry_id>0 {$scopeFilter} "; // does the mainFormWhereClause need to be used here too? Needs to be tested. -- further note: Oct 17 2011 -- appears oneSideFilters[fid] is the same as the mainformwhereclause $oneSideSQL .= $existsJoinText ? " AND ({$existsJoinText}) " : ""; if (count($oneSideFilters[$fid]) > 0) { foreach ($oneSideFilters[$fid] as $thisOneSideFilter) { $oneSideSQL .= " {$andor} ( {$thisOneSideFilter} ) "; // properly introduce these filters...need to move $andor to a higher level and put this inside ( ) ?? or maybe this just all gets redone if/when the OR bug is fixed (see big note up where oneSideFilters are first received from parseFilter function) } } $oneSideSQL .= isset($perGroupFiltersPerForms[$fid]) ? $perGroupFiltersPerForms[$fid] : ""; $restOfTheSQL = " FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main {$userJoinText} {$joinText} {$otherPerGroupFilterJoins} WHERE main.entry_id>0 {$whereClause} {$scopeFilter} {$perGroupFilter} {$otherPerGroupFilterWhereClause} {$limitByEntryId} {$orderByClause} "; $restOfTheSQLForExport = " FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main {$userJoinText} {$joinText} {$otherPerGroupFilterJoins} WHERE main.entry_id>0 {$whereClause} {$scopeFilter} {$perGroupFilter} {$otherPerGroupFilterWhereClause} {$orderByClause} "; // don't use limitByEntryId since exports include all entries if (count($linkformids) > 1) { // AND $dummy == "never") { // when there is more than 1 joined form, we can get an exponential explosion of records returned, because SQL will give you all combinations of the joins if (!$sortIsOnMain) { $orderByToUse = " ORDER BY usethissort {$sortOrder} "; $useAsSortSubQuery = " @rownum:=@rownum+1, {$useAsSortSubQuery},"; // need to add a counter as the first field, used as the master sorting key } else { $orderByToUse = $orderByClause; $useAsSortSubQuery = " @rownum:=@rownum+1, "; // need to add a counter as the first field, used as the master sorting key } $oneSideSQLToUse = str_replace(" AS main {$userJoinText}", " AS main JOIN (SELECT @rownum := 0) as r {$userJoinText}", $oneSideSQL); // need to add the initialization of the rownum, which is what we use as the master sorting key $masterQuerySQL = "SELECT {$useAsSortSubQuery} main.entry_id {$oneSideSQLToUse} {$limitByEntryId} {$orderByToUse} "; $masterQuerySQLForExport = "SELECT {$useAsSortSubQuery} main.entry_id {$oneSideSQLToUse} {$orderByToUse} "; // no limit by entry id, since all entries should be included in exports if (!$resultOnly) { // so let's build a temp table with the unique entry ids in the forms that we care about, and then query each linked form separately for its records, so that we end up processing as few result rows as possible $masterQuerySQL = "INSERT INTO " . DBPRE . "formulize_temp_extract_REPLACEWITHTIMESTAMP {$masterQuerySQL} "; $masterQuerySQLForExport = "INSERT INTO " . DBPRE . "formulize_temp_extract_REPLACEWITHTIMESTAMP {$masterQuerySQLForExport} "; } } else { $masterQuerySQL = "SELECT {$selectClause}, usertable.email AS main_email, usertable.user_viewemail AS main_user_viewemail {$restOfTheSQL} "; $masterQuerySQLForExport = "SELECT {$selectClause}, usertable.email AS main_email, usertable.user_viewemail AS main_user_viewemail {$restOfTheSQLForExport} "; } $GLOBALS['formulize_queryForCalcs'] = " FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main {$userJoinText} {$joinText} WHERE main.entry_id>0 {$whereClause} {$scopeFilter} "; $GLOBALS['formulize_queryForCalcs'] .= isset($perGroupFiltersPerForms[$fid]) ? $perGroupFiltersPerForms[$fid] : ""; $GLOBALS['formulize_queryForOneSideCalcs'] = $oneSideSQL; if ($GLOBALS['formulize_returnAfterSettingBaseQuery']) { return true; } // if we are only setting up calculations, then return now that the base query is built $sortIsOnMainFlag = $sortIsOnMain ? 1 : 0; // need to include the query first, so the SELECT or INSERT is the first thing in the string, so we catch it properly when coming back through the export process $GLOBALS['formulize_queryForExport'] = $masterQuerySQLForExport . " -- SEPARATOR FOR EXPORT QUERIES -- " . $sortIsOnMainFlag; // "$selectClauseToUse FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main $userJoinText $joinText $otherPerGroupFilterJoins WHERE main.entry_id>0 $whereClause $scopeFilter $perGroupFilter $otherPerGroupFilterWhereClause $limitByEntryId $orderByClause $limitClause"; } else { // end of if the filter has a SELECT in it if (strstr($filter, " -- SEPARATOR FOR EXPORT QUERIES -- ")) { $exportOverrideQueries = explode(" -- SEPARATOR FOR EXPORT QUERIES -- ", $filter); $masterQuerySQL = $exportOverrideQueries[0]; $sortIsOnMain = $exportOverrideQueries[1]; } else { $masterQuerySQL = $filter; // need to split this based on some separator, because export ends up passing in a series of statements } } // after the export query has been generated, then let's put the limit on: $masterQuerySQL .= $limitClause; /*global $xoopsUser; if($xoopsUser->getVar('uid') == 4613) { $queryTime = $afterQueryTime - $beforeQueryTime; print "Query time: " . $queryTime . "<br>"; }*/ debug_memory("After retrieving mainresults"); // Debug Code //global $xoopsUser; //if($xoopsUser->getVar('uid') == 1) { // print "<br>Count query: $countMasterResults<br><br>"; // print "Master query: $masterQuerySQL<br>"; //} formulize_benchmark("Before query"); if (count($linkformids) > 1) { // AND $dummy=="never") { // when there is more than 1 joined form, we can get an exponential explosion of records returned, because SQL will give you all combinations of the joins, so we create a series of queries that will each handle the main form plus one of the linked forms, then we put all the data together into a single result set below if ($resultOnly) { $masterQueryRes = $xoopsDB->query($masterQuerySQL); } else { $timestamp = str_replace(".", "", microtime(true)); if (!$sortIsOnMain) { $creatTableSQL = "CREATE TABLE " . DBPRE . "formulize_temp_extract_{$timestamp} ( `mastersort` BIGINT(11), `throwaway_sort_values` BIGINT(11), `entry_id` BIGINT(11), PRIMARY KEY (`mastersort`), INDEX i_entry_id (`entry_id`) ) ENGINE=MyISAM;"; // when the sort is not on the main form, then we are including a special field in the select statement that we sort it by, so that the order is correct, and so it has to have a place to get inserted here } else { $creatTableSQL = "CREATE TABLE " . DBPRE . "formulize_temp_extract_{$timestamp} ( `mastersort` BIGINT(11), `entry_id` BIGINT(11), PRIMARY KEY (`mastersort`), INDEX i_entry_id (`entry_id`) ) ENGINE=MyISAM;"; } $createTableRes = $xoopsDB->queryF($creatTableSQL); $gatherIdsRes = $xoopsDB->queryF(str_replace("REPLACEWITHTIMESTAMP", $timestamp, $masterQuerySQL)); $linkQueryRes = array(); if (isset($exportOverrideQueries[2])) { for ($i = 2; $i < count($exportOverrideQueries); $i++) { $sql = str_replace("REPLACEWITHTIMESTAMP", $timestamp, $exportOverrideQueries[$i]); $linkQueryRes[] = $xoopsDB->query($sql); } } else { // FURTHER OPTIMIZATIONS ARE POSSIBLE HERE...WE COULD NOT INCLUDE THE MAIN FORM AGAIN IN ALL THE SELECTS, THAT WOULD IMPROVE THE PROCESSING TIME A BIT, BUT WE WOULD HAVE TO CAREFULLY REFACTOR MORE OF THE LOOPING CODE BELOW THAT PARSES THE ENTRIES, BECAUSE RIGHT NOW IT'S ASSUMING THE FULL MAIN ENTRY IS PRESENT. AT LEAST THE MAIN ENTRY ID WOULD NEED TO STILL BE USED, SINCE WE USE THAT TO SYNCH UP ALL THE ENTRIES FROM THE OTHER FORMS. foreach ($linkformids as $linkId => $thisLinkFid) { $linkQuery = "SELECT\r\n main.entry_id AS main_entry_id, main.creation_uid AS main_creation_uid, main.mod_uid AS main_mod_uid, main.creation_datetime AS main_creation_datetime, main.mod_datetime AS main_mod_datetime, main.*, " . $linkSelectIndex[$thisLinkFid] . ", usertable.email AS main_email, usertable.user_viewemail AS main_user_viewemail FROM " . DBPRE . "formulize_" . $formObject->getVar('form_handle') . " AS main\r\n LEFT JOIN " . DBPRE . "users AS usertable ON main.creation_uid=usertable.uid\r\n LEFT JOIN " . $joinTextTableRef[$thisLinkFid] . $joinTextIndex[$thisLinkFid] . "\r\n INNER JOIN " . DBPRE . "formulize_temp_extract_REPLACEWITHTIMESTAMP as sort_and_limit_table ON main.entry_id = sort_and_limit_table.entry_id "; if (isset($oneSideFilters[$thisLinkFid]) and is_array($oneSideFilters[$thisLinkFid])) { $start = true; foreach ($oneSideFilters[$thisLinkFid] as $thisOneSideFilter) { if (!$start) { $linkQuery .= " AND ( {$thisOneSideFilter} ) "; } else { $linkQuery .= " WHERE ( {$thisOneSideFilter} ) "; $start = false; } } } $linkQuery .= " ORDER BY sort_and_limit_table.mastersort"; $linkQueryRes[] = $xoopsDB->query(str_replace("REPLACEWITHTIMESTAMP", $timestamp, $linkQuery)); $GLOBALS['formulize_queryForExport'] .= " -- SEPARATOR FOR EXPORT QUERIES -- " . $linkQuery; } } $dropRes = $xoopsDB->queryF("DROP TABLE " . DBPRE . "formulize_temp_extract_{$timestamp}"); } } else { $masterQueryRes = $xoopsDB->query($masterQuerySQL); } if ($resultOnly) { if ($masterQueryRes) { if ($xoopsDB->getRowsNum($masterQueryRes) > 0) { return $masterQueryRes; } else { return false; } } } formulize_benchmark("After query"); // need to calculate the derived value metadata // 1. figure out which fields in the included forms have derived values // 2. setup the metadata for those fields, according to the order they appear // -- metadata should be: formhandle (title or framework formhandle), formula, handle (element handle or framework handle) // 3. call the derived value function from inside the main loop $linkFormIdsFilter = ""; if ($frid) { $linkFormIdsFilter = (is_array($linkformids) and count($linkformids) > 0) ? " OR t1.id_form IN (" . implode(",", $linkformids) . ") " : ""; } $sql = "SELECT t1.ele_value, t2.desc_form, t1.ele_handle, t2.id_form FROM " . DBPRE . "formulize as t1, " . DBPRE . "formulize_id as t2 WHERE t1.ele_type='derived' AND (t1.id_form='{$fid}' {$linkFormIdsFilter} ) AND t1.id_form=t2.id_form ORDER BY t1.ele_order"; $derivedFieldMetadata = array(); if ($res = $xoopsDB->query($sql)) { if ($xoopsDB->getRowsNum($res) > 0) { $multipleIndexer = array(); while ($row = $xoopsDB->fetchRow($res)) { $ele_value = unserialize($row[0]); // derived fields have ele_value as an array with only one element (that was done to future proof the data model, so we could add other things to ele_value if necessary) if (!isset($multipleIndexer[$row[1]])) { $multipleIndexer[$row[1]] = 0; } $derivedFieldMetadata[$row[1]][$multipleIndexer[$row[1]]]['formula'] = $ele_value[0]; // use row[1] (the form handle) as the key, so we can eliminate some looping later on $derivedFieldMetadata[$row[1]][$multipleIndexer[$row[1]]]['handle'] = $row[2]; $derivedFieldMetadata[$row[1]][$multipleIndexer[$row[1]]]['form_id'] = $row[3]; $multipleIndexer[$row[1]]++; } } } else { print "Error: could not check to see if there were derived value elements in one or more forms. SQL:<br>{$sql}"; } if (count($linkformids) > 1) { // AND $dummy == "never") { // this is a refactoring of the original code that is in the else part of this structure. // it's virtually the same, except for the part that sets the $masterIndexer, since we will need to reuse masterindex positions when parsing subsequent queries, so we don't just increment the $masterIndexer // Also, derived value formulas are processed all at the end, because until we've parsed the last query, we don't have a complete set of data for any record in the masterResults array // once this is proven stable, we should refactor this into a function and have a more unified/common way of parsing query results, but for now we'll keep it split out since we know the old way works intact in its current form and this new one is a little bit experimental // we need to loop through all the query results that were generated above, and gradually build up the same full results array out of them // then we also need to loop through all main entries one more time once we're done building, and set all the derived values // this is done to avoid an exponential explosion of results in the SQL, and instead we only have a linear progression of results to parse $masterResults = array(); $masterIndexer = -1; $writtenMains = array(); $masterQueryArrayIndex = array(); foreach ($linkQueryRes as $thisRes) { // loop through the found data and create the dataset array in "getData" format $prevFieldNotMeta = true; $prevFormAlias = ""; $prevMainId = ""; while ($masterQueryArray = $xoopsDB->fetchArray($thisRes)) { foreach ($masterQueryArray as $field => $value) { if ($field == "entry_id" or $field == "creation_uid" or $field == "mod_uid" or $field == "creation_datetime" or $field == "mod_datetime" or $field == "main_email" or $field == "main_user_viewemail") { continue; } // ignore those plain fields, since we can only work with the ones that are properly aliased to their respective tables. More details....Must refer to metadata fields by aliases only! since * is included in SQL syntax, fetch_assoc will return plain column names from all forms with the values from those columns.....Also want to ignore the email fields, since the fact they're prefixed with "main" can throwoff the calculation of which entry we're currently writing if (strstr($field, "creation_uid") or strstr($field, "creation_datetime") or strstr($field, "mod_uid") or strstr($field, "mod_datetime") or strstr($field, "entry_id")) { // dealing with a new metadata field $fieldNameParts = explode("_", $field); // We account for a mainform entry appearing multiple times in the list, because when there are multiple entries in a subform, and SQL returns one row per subform, we need to not change the main form and internal record until we pass to a new mainform entry if ($prevFieldNotMeta) { // only do once for each form $curFormId = $fieldNameParts[0] == "main" ? $fid : $linkformids[substr($fieldNameParts[0], 1)]; // the table aliases are based on the keys of the linked forms in the linkformids array, so if we get the number out of the table alias, that key will give us the form id of the linked form as stored in the linkformids array $prevFormAlias = $curFormAlias; $curFormAlias = $fieldNameParts[0]; if ($prevFormAlias == "main") { // if we just finished up a main form entry, then log that $writtenMains[$prevMainId] = true; } //print "curFormAlias: $curFormAlias<br>prevMainId: $prevMainId<br>current main id: ". $masterQueryArray['main_entry_id'] . "<br><br>"; if ($curFormAlias == "main" and $prevMainId != $masterQueryArray['main_entry_id']) { if ($writtenMains[$masterQueryArray['main_entry_id']]) { $masterIndexer = $masterQueryArrayIndex[$masterQueryArray['main_entry_id']]; // use the master index value for this main entry id if we've already logged it } else { $masterIndexer = count($masterResults); // use the next available number for the master indexer $masterQueryArrayIndex[$masterQueryArray['main_entry_id']] = $masterIndexer; // log it so we can reuse it for this entry when it comes up in another query } $prevMainId = $masterQueryArray['main_entry_id']; // if the current form is a main, then store it's ID for use later when we're on a new form } } $prevFieldNotMeta = false; // setup handles to use for metadata fields if ($curFormAlias == "main") { if ($field == "main_creation_uid" or $field == "main_mod_uid" or $field == "main_creation_datetime" or $field == "main_mod_datetime" or $field == "main_entry_id") { $elementHandle = $fieldNameParts[1] . "_" . $fieldNameParts[2]; } } else { continue; // do not include metadata from the linked forms, or anything else (such as email, etc) } } elseif (!strstr($field, "main_email") and !strstr($field, "main_user_viewemail")) { // dealing with a regular element field $prevFieldNotMeta = true; $elementHandle = $field; } else { // it's some other field... continue; } // Check to see if this is a main entry that has already been catalogued, and if so, then skip it if ($curFormAlias == "main" and isset($writtenMains[$masterQueryArray['main_entry_id']])) { continue; } //print "<br>$curFormAlias - $field: $value<br>"; // debug line formulize_benchmark("preping value..."); $valueArray = prepvalues($value, $elementHandle, $masterQueryArray[$curFormAlias . "_entry_id"]); // note...metadata fields must not be in an array for compatibility with the 'display' function...not all values returned will actually be arrays, but if there are multiple values in a cell, then those will be arrays formulize_benchmark("done preping value"); $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]][$elementHandle] = $valueArray; if ($elementHandle == "creation_uid" or $elementHandle == "mod_uid" or $elementHandle == "creation_datetime" or $elementHandle == "mod_datetime" or $elementHandle == "entry_id") { // add in the creator_email when we have done the creation_uid if ($elementHandle == "creation_uid") { if (!isset($is_webmaster)) { global $xoopsUser; if (is_object($xoopsUser)) { // determine if the user is a webmaster, in order to control whether the e-mail addresses should be shown or not $is_webmaster = in_array(XOOPS_GROUP_ADMIN, $xoopsUser->getGroups()) ? true : false; $gperm_handler =& xoops_gethandler('groupperm'); $view_private_fields = $gperm_handler->checkRight("view_private_elements", $fid, $xoopsUser->getGroups(), getFormulizeModId()); $this_userid = $xoopsUser->getVar('uid'); } else { $view_private_fields = false; $is_webmaster = false; $this_userid = 0; } } if ($is_webmaster or $view_private_fields or $masterQueryArray['main_user_viewemail'] or $masterQueryArray['main_creation_uid'] == $this_userid) { $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]]['creator_email'] = $masterQueryArray['main_email']; } else { $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]]['creator_email'] = ""; } } // for backwards compatibility, replicate the old metadata fields switch ($elementHandle) { case "creation_uid": $old_meta = "uid"; break; case "mod_uid": $old_meta = "proxyid"; break; case "creation_datetime": $old_meta = "creation_date"; break; case "mod_datetime": $old_meta = "mod_date"; break; } $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]][$old_meta] = $valueArray; } } // end of foreach field loop within a record } // end of main while loop for all records } // end of foreach linked query result if (count($derivedFieldMetadata) > 0 and $masterIndexer > -1) { // if there is derived value info for this data set and we have started to create values...need to do this one more time for the last value that we would have gathered data for... foreach ($masterResults as $masterIndex => $thisRecord) { $masterResults[$masterIndex] = formulize_calcDerivedColumns($thisRecord, $derivedFieldMetadata, $frid, $fid); } } } else { // loop through the found data and create the dataset array in "getData" format $prevFieldNotMeta = true; $masterIndexer = -1; $writtenMains = array(); $prevFormAlias = ""; $prevMainId = ""; //formulize_benchmark("About to prepare results."); while ($masterQueryArray = $xoopsDB->fetchArray($masterQueryRes)) { set_time_limit(120); //formulize_benchmark("Starting to process one entry."); foreach ($masterQueryArray as $field => $value) { //formulize_benchmark("Starting to process one value"); if ($field == "entry_id" or $field == "creation_uid" or $field == "mod_uid" or $field == "creation_datetime" or $field == "mod_datetime" or $field == "main_email" or $field == "main_user_viewemail") { continue; } // ignore those plain fields, since we can only work with the ones that are properly aliased to their respective tables. More details....Must refer to metadata fields by aliases only! since * is included in SQL syntax, fetch_assoc will return plain column names from all forms with the values from those columns.....Also want to ignore the email fields, since the fact they're prefixed with "main" can throwoff the calculation of which entry we're currently writing if (strstr($field, "creation_uid") or strstr($field, "creation_datetime") or strstr($field, "mod_uid") or strstr($field, "mod_datetime") or strstr($field, "entry_id")) { //formulize_benchmark("Starting to process metadata"); // dealing with a new metadata field $fieldNameParts = explode("_", $field); // We account for a mainform entry appearing multiple times in the list, because when there are multiple entries in a subform, and SQL returns one row per subform, we need to not change the main form and internal record until we pass to a new mainform entry if ($prevFieldNotMeta) { // only do once for each form $curFormId = $fieldNameParts[0] == "main" ? $fid : $linkformids[substr($fieldNameParts[0], 1)]; // the table aliases are based on the keys of the linked forms in the linkformids array, so if we get the number out of the table alias, that key will give us the form id of the linked form as stored in the linkformids array $prevFormAlias = $curFormAlias; $curFormAlias = $fieldNameParts[0]; if ($prevFormAlias == "main") { // if we just finished up a main form entry, then log that $writtenMains[$prevMainId] = true; } //print "curFormAlias: $curFormAlias<br>prevMainId: $prevMainId<br>current main id: ". $masterQueryArray['main_entry_id'] . "<br><br>"; if ($curFormAlias == "main" and $prevMainId != $masterQueryArray['main_entry_id']) { //formulize_benchmark("Done entry, ready to do derived values."); // now that the entire entry has been processed, do the derived values for it if (count($derivedFieldMetadata) > 0 and $masterIndexer > -1) { // if there is derived value info for this data set and we have started to create values... //print "fid: $fid<br>"; //print "frid: $frid<br>"; formulize_benchmark("before doing derived..."); $masterResults[$masterIndexer] = formulize_calcDerivedColumns($masterResults[$masterIndexer], $derivedFieldMetadata, $frid, $fid); formulize_benchmark("after doing derived"); } $masterIndexer++; // If this is a new main entry, then increment the masterIndexer, since the masterIndexer is used to uniquely identify each main entry $prevMainId = $masterQueryArray['main_entry_id']; // if the current form is a main, then store it's ID for use later when we're on a new form } } $prevFieldNotMeta = false; // setup handles to use for metadata fields if ($curFormAlias == "main") { if ($field == "main_creation_uid" or $field == "main_mod_uid" or $field == "main_creation_datetime" or $field == "main_mod_datetime" or $field == "main_entry_id") { $elementHandle = $fieldNameParts[1] . "_" . $fieldNameParts[2]; } else { continue; // do not include main_entry_id as a value in the array...though it should not be in here anyway now that we're checking with strstr for metadata field names above } } else { continue; // do not include metadata from the linked forms, or anything else (such as email, etc) } } elseif (!strstr($field, "main_email") and !strstr($field, "main_user_viewemail")) { // dealing with a regular element field $prevFieldNotMeta = true; $elementHandle = $field; } else { // it's some other field continue; } // Check to see if this is a main entry that has already been catalogued, and if so, then skip it if ($curFormAlias == "main" and isset($writtenMains[$masterQueryArray['main_entry_id']])) { continue; } //print "<br>$curFormAlias - $field: $value<br>"; // debug line formulize_benchmark("preping value..."); $valueArray = prepvalues($value, $elementHandle, $masterQueryArray[$curFormAlias . "_entry_id"]); // note...metadata fields must not be in an array for compatibility with the 'display' function...not all values returned will actually be arrays, but if there are multiple values in a cell, then those will be arrays formulize_benchmark("done preping value"); $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]][$elementHandle] = $valueArray; if ($elementHandle == "creation_uid" or $elementHandle == "mod_uid" or $elementHandle == "creation_datetime" or $elementHandle == "mod_datetime" or $elementHandle == "entry_id") { // add in the creator_email when we have done the creation_uid if ($elementHandle == "creation_uid") { if (!isset($is_webmaster)) { global $xoopsUser; if (is_object($xoopsUser)) { // determine if the user is a webmaster, in order to control whether the e-mail addresses should be shown or not $is_webmaster = in_array(XOOPS_GROUP_ADMIN, $xoopsUser->getGroups()) ? true : false; $gperm_handler =& xoops_gethandler('groupperm'); $view_private_fields = $gperm_handler->checkRight("view_private_elements", $fid, $xoopsUser->getGroups(), getFormulizeModId()); $this_userid = $xoopsUser->getVar('uid'); } else { $view_private_fields = false; $is_webmaster = false; $this_userid = 0; } } if ($is_webmaster or $view_private_fields or $masterQueryArray['main_user_viewemail'] or $masterQueryArray['main_creation_uid'] == $this_userid) { $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]]['creator_email'] = $masterQueryArray['main_email']; } else { $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]]['creator_email'] = ""; } } // for backwards compatibility, replicate the old metadata fields switch ($elementHandle) { case "creation_uid": $old_meta = "uid"; break; case "mod_uid": $old_meta = "proxyid"; break; case "creation_datetime": $old_meta = "creation_date"; break; case "mod_datetime": $old_meta = "mod_date"; break; } $masterResults[$masterIndexer][getFormTitle($curFormId)][$masterQueryArray[$curFormAlias . "_entry_id"]][$old_meta] = $valueArray; } } // end of foreach field loop within a record } // end of main while loop for all records if (count($derivedFieldMetadata) > 0 and $masterIndexer > -1) { // if there is derived value info for this data set and we have started to create values...need to do this one more time for the last value that we would have gathered data for... //print "fid: $fid<br>"; //print "frid: $frid<br>"; $masterResults[$masterIndexer] = formulize_calcDerivedColumns($masterResults[$masterIndexer], $derivedFieldMetadata, $frid, $fid); } } // end if if there's more the 1 linked fid return $masterResults; }
function render($ele_value, $caption, $markupName, $isDisabled, $element, $entry_id, $screen) { $fid = $element->getVar('id_form'); $this_ele_id = $element->getVar('ele_id'); global $xoopsUser; $uid = $xoopsUser ? $xoopsUser->getVar('uid') : 0; $groups = $xoopsUser->getGroups(); $sub_fids = $GLOBALS['formulize_sub_fids']; // set in compileElements, right before the displayElement function is called $mid = getFormulizeModId(); $frid = $GLOBALS['framework']; $sub_entries = $GLOBALS['sub_entries']; //set in compileElements $owner = getEntryOwner($entry_id, $fid); $thissfid = $ele_value[0]; if (!$thissfid) { continue; } // can't display non-specified subforms! if ($passed = security_check($thissfid) and in_array($thissfid, $sub_fids)) { $GLOBALS['sfidsDrawn'][] = $thissfid; $customCaption = $element->getVar('ele_caption'); $customElements = $ele_value[1] ? explode(",", $ele_value[1]) : ""; $subUICols = drawSubLinks($thissfid, $sub_entries, $uid, $groups, $frid, $mid, $fid, $entry_id, $caption, $customElements, intval($ele_value[2]), $ele_value[3], $ele_value[4], $ele_value[5], $owner, $ele_value[6], $ele_value[7], $this_ele_id, $ele_value[8], $ele_value[9]); // 2 is the number of default blanks, 3 is whether to show the view button or not, 4 is whether to use captions as headings or not, 5 is override owner of entry, $owner is mainform entry owner, 6 is hide the add button, 7 is the conditions settings for the subform element, 8 is the setting for showing just a row or the full form, 9 is text for the add entries button if (isset($subUICols['single'])) { $form_ele = array($subUICols['single'], "even"); } else { $subLinkUI = new XoopsFormLabel($subUICols['c1'], $subUICols['c2']); $form_ele = $subLinkUI; } unset($subLinkUI); } return $form_ele; }
print "<title>" . _formulize_DE_PICKCALCS . "</title>\n"; calcJavascript(); print "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"" . XOOPS_URL . "/xoops.css\" />\n"; $themecss = xoops_getcss(); //$themecss = substr($themecss, 0, -6); //$themecss .= ".css"; print "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"{$themecss}\" />\n"; print "</head>"; print "<body style=\"background: white; margin-top:20px;\"><center>"; print "<table width=100%><tr><td width=5%></td><td width=90%>"; $pickcalc = new xoopsThemeForm(_formulize_DE_PICKCALCS, 'pickcalc', $_SERVER["REQUEST_URI"]); $returned = addReqdCalcs($pickcalc); $pickcalc = $returned['form']; // add note for module admins to remind them of the need to set types properly for some calculations to work if ($xoopsUser) { if ($gperm_handler->checkRight("module_admin", getFormulizeModId(), $xoopsUser->getGroups(), 1)) { $pickcalc->insertBreak("<div style=\"font-weight: normal;\">" . _formulize_DE_CALC_NEEDDATATYPES1 . "<a href=\"" . XOOPS_URL . "/modules/formulize/admin/index.php?title={$fid}\" target=\"_blank\">" . _formulize_DE_CALC_NEEDDATATYPES2 . "</a></div>", "head"); // add note for module admins to remind them to set types properly for calculations to work } } $columns = new xoopsFormSelect(_formulize_DE_CALC_COL, 'column', "", min(count($options) + 6, 18), true); if (!in_array("creation_uid", $_POST['column']) and !$_POST['reqdcalc_column_uid']) { $columns->addOption("creation_uid", _formulize_DE_CALC_CREATOR); } if (!in_array("mod_uid", $_POST['column']) and !$_POST['reqdcalc_column_proxyid']) { $columns->addOption("mod_uid", _formulize_DE_CALC_MODIFIER); } if (!in_array("creation_datetime", $_POST['column']) and !$_POST['reqdcalc_column_creation_date']) { $columns->addOption("creation_datetime", _formulize_DE_CALC_CREATEDATE); } if (!in_array("mod_datetime", $_POST['column']) and !$_POST['reqdcalc_column_mod_date']) {
<?php include "../../../mainfile.php"; include_once XOOPS_ROOT_PATH . '/modules/formulize/include/functions.php'; global $xoopsUser; //Everything Needed from the Mainfile Goes here .Using my Own Define defined('DB_TYPE') ? NULL : define('DB_TYPE', 'mysql'); defined('DB_HOST') ? NULL : define('DB_HOST', XOOPS_DB_HOST); defined('DB_USER') ? NULL : define('DB_USER', XOOPS_DB_USER); defined('DB_PASS') ? NULL : define('DB_PASS', XOOPS_DB_PASS); defined('DB_NAME') ? NULL : define('DB_NAME', XOOPS_DB_NAME); defined('Prefix') ? NULL : define('Prefix', XOOPS_DB_PREFIX); defined('SID') ? define('SID', $xoopsUser->getVar('uid')) : NULL; defined('MOD_ID') ? NULL : define('MOD_ID', getFormulizeModId());
} if ($orderGroups == "alpha") { ksort($groups); } // get all the permissions for the selected groups for this form $gperm_handler =& xoops_gethandler('groupperm'); $formulize_permHandler = new formulizePermHandler($fid); $filterSettings = $formObject->getVar('filterSettings'); $groupperms = array(); $groupfilters = array(); $i = 0; foreach ($selectedGroups as $thisGroup) { // get all the permissions this group has on this form $criteria = new CriteriaCompo(new Criteria('gperm_groupid', $thisGroup)); $criteria->add(new Criteria('gperm_itemid', $fid)); $criteria->add(new Criteria('gperm_modid', getFormulizeModId())); $perms = $gperm_handler->getObjects($criteria, true); $groupObject = $member_handler->getGroup($thisGroup); $groupperms[$i]['name'] = $groupObject->getVar('name'); $groupperms[$i]['id'] = $groupObject->getVar('groupid'); foreach ($perms as $perm) { $groupperms[$i][$perm->getVar('gperm_name')] = " checked"; } // group-specific-scope $scopeGroups = $formulize_permHandler->getGroupScopeGroupIds($groupObject->getVar('groupid')); if ($scopeGroups === false) { $groupperms[$i]['groupscope_choice'][0] = " selected"; } else { foreach ($scopeGroups as $thisScopeGroupId) { $groupperms[$i]['groupscope_choice'][$thisScopeGroupId] = " selected"; }
$_GET['aid'] = 1; include "import.php"; break; default: case "home": include "home.php"; break; } $adminPage['logo'] = "/modules/formulize/images/formulize-logo.png"; // assign the default selected tab, if any: if (isset($_GET['tab']) and (!isset($_POST['tabs_selected']) or $_POST['tabs_selected'] === "")) { foreach ($adminPage['tabs'] as $selected => $tabData) { if (strtolower($tabData['name']) == $_GET['tab']) { $adminPage['tabselected'] = $selected - 1; break; } } } elseif (isset($_POST['tabs_selected']) and $_POST['tabs_selected'] !== "") { $adminPage['tabselected'] = intval($_POST['tabs_selected']); } // assign the contents to the template and display $adminPage['formulizeModId'] = getFormulizeModId(); $xoopsTpl->assign('adminPage', $adminPage); if (isset($breadcrumbtrail)) { $xoopsTpl->assign('breadcrumbtrail', $breadcrumbtrail); } $xoopsTpl->assign('scrollx', isset($_POST['scrollx']) ? intval($_POST['scrollx']) : 0); $accordion_active = (isset($_POST['accordion_active']) and $_POST['accordion_active'] !== "" and $_POST['accordion_active'] !== "false") ? intval($_POST['accordion_active']) : "false"; $xoopsTpl->assign('accordion_active', $accordion_active); $xoopsTpl->display("db:admin/ui.html"); xoops_cp_footer();
## Project: Formulize ## ############################################################################### // This file receives ajax form submissions from the new admin UI include_once "../../../mainfile.php"; ob_end_clean(); ob_end_clean(); // in some cases ther appear to be two buffers active?! So we must try to end twice. global $xoopsUser; if (!$xoopsUser) { print "Error: you are not logged in"; return; } $gperm_handler = xoops_gethandler('groupperm'); include_once XOOPS_ROOT_PATH . "/modules/formulize/include/functions.php"; $groups = $xoopsUser->getGroups(); $mid = getFormulizeModId(); $permissionToCheck = "module_admin"; $itemToCheck = $mid; $moduleToCheck = 1; // system module if (!$gperm_handler->checkRight($permissionToCheck, $itemToCheck, $groups, $moduleToCheck)) { print "Error: you do not have permission to save this data"; return; } // process all the submitted form values, looking for ones that can be immediately assigned to objects $processedValues = array(); foreach ($_POST as $k => $v) { if (!strstr($k, "-")) { // ignore fields with no hyphen continue; }
function displayFormPages($formframe, $entry = "", $mainform = "", $pages, $conditions = "", $introtext = "", $thankstext = "", $done_dest = "", $button_text = "", $settings = "", $overrideValue = "", $printall = 0, $screen = null, $saveAndContinueButtonText = null) { // nmc 2007.03.24 - added 'printall' formulize_benchmark("Start of displayFormPages."); // extract the optional page titles from the $pages array for use in the jump to box // NOTE: pageTitles array must start with key 1, not 0. Page 1 is the first page of the form $pageTitles = array(); if (isset($pages['titles'])) { $pageTitles = $pages['titles']; unset($pages['titles']); } if (!$saveAndContinueButtonText and isset($_POST['formulize_saveAndContinueButtonText'])) { $saveAndContinueButtonText = unserialize($_POST['formulize_saveAndContinueButtonText']); } if (!$done_dest and $_POST['formulize_doneDest']) { $done_dest = $_POST['formulize_doneDest']; } if (!$button_text and $_POST['formulize_buttonText']) { $button_text = $_POST['formulize_buttonText']; } list($fid, $frid) = getFormFramework($formframe, $mainform); $thankstext = $thankstext ? $thankstext : _formulize_DMULTI_THANKS; $introtext = $introtext ? $introtext : ""; global $xoopsUser; $mid = getFormulizeModId(); $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS); $uid = $xoopsUser ? $xoopsUser->getVar('uid') : 0; $gperm_handler =& xoops_gethandler('groupperm'); $member_handler =& xoops_gethandler('member'); $single_result = getSingle($fid, $uid, $groups, $member_handler, $gperm_handler, $mid); // if this function was called without an entry specified, then assume the identity of the entry we're editing (unless this is a new save, in which case no entry has been made yet) // no handling of cookies here, so anonymous multi-page surveys will not benefit from that feature // this emphasizes how we need to standardize a lot of these interfaces with a real class system if (!$entry and $_POST['entry' . $fid]) { $entry = $_POST['entry' . $fid]; } elseif (!$entry) { // or check getSingle to see what the real entry is $entry = $single_result['flag'] ? $single_result['entry'] : 0; } // formulize_newEntryIds is set when saving data if (!$entry and isset($GLOBALS['formulize_newEntryIds'][$fid])) { $entry = $GLOBALS['formulize_newEntryIds'][$fid][0]; } $owner = getEntryOwner($entry, $fid); $prevPage = isset($_POST['formulize_prevPage']) ? $_POST['formulize_prevPage'] : 1; // last page that the user was on, not necessarily the previous page numerically $currentPage = isset($_POST['formulize_currentPage']) ? $_POST['formulize_currentPage'] : 1; $thanksPage = count($pages) + 1; // debug control: $currentPage = (isset($_GET['debugpage']) and is_numeric($_GET['debugpage'])) ? $_GET['debugpage'] : $currentPage; $usersCanSave = formulizePermHandler::user_can_edit_entry($fid, $uid, $entry); if ($pages[$prevPage][0] !== "HTML" and $pages[$prevPage][0] !== "PHP") { // remember prevPage is the last page the user was on, not the previous page numerically if (isset($_POST['form_submitted']) and $usersCanSave) { include_once XOOPS_ROOT_PATH . "/modules/formulize/include/formread.php"; include_once XOOPS_ROOT_PATH . "/modules/formulize/include/functions.php"; include_once XOOPS_ROOT_PATH . "/modules/formulize/class/data.php"; //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE); $data_handler = new formulizeDataHandler($fid); $owner_groups = $data_handler->getEntryOwnerGroups($entry); $entries[$fid][0] = $entry; if ($frid) { $linkResults = checkForLinks($frid, array(0 => $fid), $fid, $entries, $gperm_handler, $owner_groups, $mid, $member_handler, $owner); unset($entries); $entries = $linkResults['entries']; } $entries = $GLOBALS['formulize_allWrittenEntryIds']; // set in readelements.php // if there has been no specific entry specified yet, then assume the identity of the entry that was just saved -- assumption is it will be a new save // from this point forward in time, this is the only entry that should be involved, since the 'entry'.$fid condition above will put this value into $entry even if this function was called with a blank entry value if (!$entry) { $entry = $entries[$fid][0]; } synchSubformBlankDefaults($fid, $entry); } } // there are several points above where $entry is set, and now that we have a final value, store in ventry if ($entry > 0) { $settings['ventry'] = $entry; } // check to see if there are conditions on this page, and if so are they met // if the conditions are not met, move on to the next page and repeat the condition check // conditions only checked once there is an entry! $pagesSkipped = false; if (is_array($conditions) and $entry) { $conditionsMet = false; while (!$conditionsMet) { if (isset($conditions[$currentPage]) and count($conditions[$currentPage][0]) > 0) { // conditions on the current page $thesecons = $conditions[$currentPage]; $elements = $thesecons[0]; $ops = $thesecons[1]; $terms = $thesecons[2]; $types = $thesecons[3]; // indicates if the term is part of a must or may set, ie: boolean and or or $filter = ""; $oomfilter = ""; $blankORSearch = ""; foreach ($elements as $i => $thisElement) { if ($ops[$i] == "NOT") { $ops[$i] = "!="; } if ($terms[$i] == "{BLANK}") { // NOTE...USE OF BLANKS WON'T WORK CLEANLY IN ALL CASES DEPENDING WHAT OTHER TERMS HAVE BEEN SPECIFIED!! if ($ops[$i] == "!=" or $ops[$i] == "NOT LIKE") { if ($types[$i] != "oom") { // add to the main filter, ie: entry id = 1 AND x=5 AND y IS NOT "" AND y IS NOT NULL if (!$filter) { $filter = $entry . "][" . $elements[$i] . "/**//**/!=][" . $elements[$i] . "/**//**/IS NOT NULL"; } else { $filter .= "][" . $elements[$i] . "/**//**/!=][" . $elements[$i] . "/**//**/IS NOT NULL"; } } else { // Add to the OOM filter, ie: entry id = 1 AND (x=5 OR y IS NOT "" OR y IS NOT NULL) if (!$oomfilter) { $oomfilter = $elements[$i] . "/**//**/=][" . $elements[$i] . "/**//**/IS NULL"; } else { $oomfilter .= "][" . $elements[$i] . "/**//**/=][" . $elements[$i] . "/**//**/IS NULL"; } } } else { if ($types[$i] != "oom") { // add to its own OR filter, since we MUST match this condition, but we don't care if it's "" OR NULL // ie: entry id = 1 AND (x=5 OR y=10) AND (z = "" OR z IS NULL) if (!$blankORSearch) { $blankORSearch = $elements[$i] . "/**//**/=][" . $elements[$i] . "/**//**/IS NULL"; } else { $blankORSearch .= "][" . $elements[$i] . "/**//**/=][" . $elements[$i] . "/**//**/IS NULL"; } } else { // it's part of the oom filters anyway, so we put it there, because we don't care if it's null or "" or neither if (!$oomfilter) { $oomfilter = $elements[$i] . "/**//**/=][" . $elements[$i] . "/**//**/IS NULL"; } else { $oomfilter .= "][" . $elements[$i] . "/**//**/=][" . $elements[$i] . "/**//**/IS NULL"; } } } } elseif ($types[$i] == "oom") { if (!$oomfilter) { $oomfilter = $elements[$i] . "/**/" . trans($terms[$i]) . "/**/" . $ops[$i]; } else { $oomfilter .= "][" . $elements[$i] . "/**/" . trans($terms[$i]) . "/**/" . $ops[$i]; } } else { if (!$filter) { $filter = $entry . "][" . $elements[$i] . "/**/" . trans($terms[$i]) . "/**/" . $ops[$i]; } else { $filter .= "][" . $elements[$i] . "/**/" . trans($terms[$i]) . "/**/" . $ops[$i]; } } } if ($oomfilter and $filter) { $finalFilter = array(); $finalFilter[0][0] = "AND"; $finalFilter[0][1] = $filter; $finalFilter[1][0] = "OR"; $finalFilter[1][1] = $oomfilter; if ($blankORSearch) { $finalFilter[2][0] = "OR"; $finalFilter[2][1] = $blankORSearch; } } elseif ($oomfilter) { // need to add the $entry as a separate filter from the oom, so the entry and oom get an AND in between them $finalFilter = array(); $finalFilter[0][0] = "AND"; $finalFilter[0][1] = $entry; $finalFilter[1][0] = "OR"; $finalFilter[1][1] = $oomfilter; if ($blankORSearch) { $finalFilter[2][0] = "OR"; $finalFilter[2][1] = $blankORSearch; } } else { if ($blankORSearch) { $finalFilter[0][0] = "AND"; $finalFilter[0][1] = $filter ? $filter : $entry; $finalFilter[1][0] = "OR"; $finalFilter[1][1] = $blankORSearch; } else { $finalFilter = $filter; } } $masterBoolean = "AND"; include_once XOOPS_ROOT_PATH . "/modules/formulize/include/extract.php"; $data = getData($frid, $fid, $finalFilter, $masterBoolean, "", "", "", "", "", false, 0, false, "", false, true); if (!$data) { if ($prevPage <= $currentPage) { $currentPage++; } else { $currentPage--; } $pagesSkipped = true; } else { $conditionsMet = true; } } else { // no conditions on the current page $conditionsMet = true; } } } if ($currentPage > 1) { $previousPage = $currentPage - 1; // previous page numerically } else { $previousPage = "none"; } $nextPage = $currentPage + 1; $done_dest = $done_dest ? $done_dest : getCurrentURL(); $done_dest = substr($done_dest, 0, 4) == "http" ? $done_dest : "http://" . $done_dest; // Set up the javascript that we need for the form-submit functionality to work // note that validateAndSubmit calls the form validation function again, but obviously it will pass if it passed here. The validation needs to be called prior to setting the pages, or else you can end up on the wrong page after clicking an ADD button in a subform when you've missed a required field. // savedPage and savedPrevPage are used to pick up the page and prevpage only when a two step validation, such as checking for uniqueness, returns and calls validateAndSubmit again ?> <script type='text/javascript'> var savedPage; var savedPrevPage; function submitForm(page, prevpage) { var validate = xoopsFormValidate_formulize(); if(validate) { savedPage = 0; savedPrevPage = 0; multipageSetHiddenFields(page, prevpage); if (formulizechanged) { validateAndSubmit(); } else { jQuery("#formulizeform").animate({opacity:0.4}, 200, "linear"); jQuery("input[name^='decue_']").remove(); // 'rewritePage' will trigger the page to change after the locks have been removed removeEntryLocks('rewritePage'); } } else { savedPage = page; savedPrevPage = prevpage; } } function multipageSetHiddenFields(page, prevpage) { <?php // neuter the ventry which is the key thing that keeps us on the form page, // if in fact we just came from a list screen of some kind. // need to use an unusual selector, because something about selecting by id wasn't working, // apparently may be related to setting actions on forms with certain versions of jQuery? print "\r\n\t\t\tif(page == {$thanksPage}) {\r\n\t\t\t\twindow.document.formulize.ventry.value = '';\r\n\t\t\t\tjQuery('form[name=formulize]').attr('action', '{$done_dest}');\r\n }\r\n"; ?> window.document.formulize.formulize_currentPage.value = page; window.document.formulize.formulize_prevPage.value = prevpage; window.document.formulize.formulize_doneDest.value = '<?php print $done_dest; ?> '; window.document.formulize.formulize_buttonText.value = '<?php print $button_text; ?> '; } function pageJump(options, prevpage) { for (var i=0; i < options.length; i++) { if (options[i].selected) { submitForm(options[i].value, prevpage); return false; } } } </script><noscript> <h1>You do not have javascript enabled in your web browser. This form will not work with your web browser. Please contact the webmaster for assistance.</h1> </noscript> <?php if ($currentPage == $thanksPage) { if ($screen and $screen->getVar('finishisdone')) { print "<script type='text/javascript'>location = '{$done_dest}';</script>"; return; // if we've ended up on the thanks page via conditions (last page was not shown) then we should just bail if there is not supposed to be a thanks page } if (is_array($thankstext)) { if ($thankstext[0] === "PHP") { eval($thankstext[1]); } else { print $thankstext[1]; } } else { // HTML print html_entity_decode($thankstext); } print "<br><hr><br><div id=\"thankYouNavigation\"><p><center>\n"; if ($pagesSkipped) { print _formulize_DMULTI_SKIP . "</p><p>\n"; } $button_text = $button_text ? $button_text : _formulize_DMULTI_ALLDONE; if ($button_text != "{NOBUTTON}") { print "<a href='{$done_dest}'"; if (is_array($settings)) { print " onclick=\"javascript:window.document.calreturnform.submit();return false;\""; } print ">" . $button_text . "</a>\n"; } print "</center></p></div>"; if (is_array($settings)) { print "<form name=calreturnform action=\"{$done_dest}\" method=post>\n"; writeHiddenSettings($settings); print "</form>"; } } if ($currentPage == 1 and $pages[1][0] !== "HTML" and $pages[1][0] !== "PHP" and !$_POST['goto_sfid']) { // only show intro text on first page if there's actually a form there print html_entity_decode(html_entity_decode($introtext)); } unset($_POST['form_submitted']); // display an HTML or PHP page if that's what this page is... if ($currentPage != $thanksPage and ($pages[$currentPage][0] === "HTML" or $pages[$currentPage][0] === "PHP")) { // PHP if ($pages[$currentPage][0] === "PHP") { eval($pages[$currentPage][1]); // HTML } else { print $pages[$currentPage][1]; } // put in the form that passes the entry, page we're going to and page we were on include_once XOOPS_ROOT_PATH . "/modules/formulize/include/functions.php"; ?> <form name=formulize id=formulize action=<?php print getCurrentURL(); ?> method=post> <input type=hidden name=entry<?php print $fid; ?> id=entry<?php print $fid; ?> value=<?php print $entry; ?> > <input type=hidden name=formulize_currentPage id=formulize_currentPage value=""> <input type=hidden name=formulize_prevPage id=formulize_prevPage value=""> writeHiddenSettings($settings); </form> <script type="text/javascript"> function validateAndSubmit() { window.document.formulize.submit(); } </script> <?php } // display a form if that's what this page is... if ($currentPage != $thanksPage and $pages[$currentPage][0] !== "HTML" and $pages[$currentPage][0] !== "PHP") { $buttonArray = array(0 => "{NOBUTTON}", 1 => "{NOBUTTON}"); foreach ($pages[$currentPage] as $element) { $elements_allowed[] = $element; } $forminfo['elements'] = $elements_allowed; $forminfo['formframe'] = $formframe; $titleOverride = isset($pageTitles[$currentPage]) ? trans($pageTitles[$currentPage]) : "all"; // we can pass in any text value as the titleOverride, and it will have the same effect as "all", but the alternate text will be used as the title for the form $GLOBALS['nosubforms'] = true; // subforms cannot have a view button on multipage forms, since moving to a sub causes total confusion of which entry and fid you are looking at $settings['formulize_currentPage'] = $currentPage; $settings['formulize_prevPage'] = $currentPage; // now that we're done everything else, we can send the current page as the previous page when initializing the form. Javascript will set the true value prior to submission. formulize_benchmark("Before drawing nav."); $previousButtonText = (is_array($saveAndContinueButtonText) and isset($saveAndContinueButtonText['previousButtonText'])) ? $saveAndContinueButtonText['previousButtonText'] : _formulize_DMULTI_PREV; if ($usersCanSave and $nextPage == $thanksPage) { $nextButtonText = (is_array($saveAndContinueButtonText) and $saveAndContinueButtonText['saveButtonText']) ? $saveAndContinueButtonText['saveButtonText'] : _formulize_DMULTI_SAVE; } else { $nextButtonText = (is_array($saveAndContinueButtonText) and $saveAndContinueButtonText['nextButtonText']) ? $saveAndContinueButtonText['nextButtonText'] : _formulize_DMULTI_NEXT; } $previousPageButton = generatePrevNextButtonMarkup("prev", $previousButtonText, $usersCanSave, $nextPage, $previousPage, $thanksPage); $nextPageButton = generatePrevNextButtonMarkup("next", $nextButtonText, $usersCanSave, $nextPage, $previousPage, $thanksPage); $savePageButton = generatePrevNextButtonMarkup("save", _formulize_SAVE, $usersCanSave, $nextPage, $previousPage, $thanksPage); $totalPages = count($pages); $skippedPageMessage = $pagesSkipped ? _formulize_DMULTI_SKIP : ""; $pageSelectionList = pageSelectionList($currentPage, $totalPages, $pageTitles, "above"); // calling for the 'above' drawPageNav // setting up the basic templateVars for all templates $templateVariables = array('previousPageButton' => $previousPageButton, 'nextPageButton' => $nextPageButton, 'savePageButton' => $savePageButton, 'totalPages' => $totalPages, 'currentPage' => $currentPage, 'skippedPageMessage' => $skippedPageMessage, 'pageSelectionList' => $pageSelectionList, 'pageTitles' => $pageTitles, 'entry_id' => $entry, 'form_id' => $fid, 'owner' => $owner); print "<form name=\"pageNavOptions_above\" id=\"pageNavOptions_above\">\n"; if ($screen and $toptemplate = $screen->getTemplate('toptemplate')) { formulize_renderTemplate('toptemplate', $templateVariables, $screen->getVar('sid')); } else { drawPageNav($usersCanSave, $currentPage, $totalPages, "above", $nextPageButton, $previousPageButton, $skippedPageMessage, $pageSelectionList); } print "</form>"; formulize_benchmark("After drawing nav/before displayForm."); // need to check for the existence of an elementtemplate property in the screen, like we did with the top and bottom templates // if there's an eleemnt template, then do this loop, otherwise, do the displayForm call like normal if ($screen and $elementtemplate = $screen->getTemplate('elementtemplate')) { // Code added by Julian 2012-09-04 and Gordon Woodmansey 2012-09-05 to render the elementtemplate if (!security_check($fid, $entry)) { exit; } // start the form manually... $formObjectForRequiredJS = new formulize_themeForm('form object for required js', 'formulize', getCurrentURL(), "post", true); $element_handler = xoops_getmodulehandler('elements', 'formulize'); print "<div id='formulizeform'><form id='formulize' name='formulize' action='" . getCurrentURL() . "' method='post' onsubmit='return xoopsFormValidate_formulize();' enctype='multipart/form-data'>"; foreach ($elements_allowed as $thisElement) { // entry is a recordid, $thisElement is the element id // to get the conditional logic to be captured, we should buffer the drawing of the displayElement, and then output that later, because when displayElement does NOT return an object, then we get conditional logic -- subform rendering does it this way unset($form_ele); // previously set elements may linger when added to the form object, due to assignment of objects by reference or something odd like that...legacy of old code in the form class I think $deReturnValue = displayElement("", $thisElement, $entry, false, $screen, null, false); if (is_array($deReturnValue)) { $form_ele = $deReturnValue[0]; $isDisabled = $deReturnValue[1]; if (isset($deReturnValue[2])) { $hiddenElements = $deReturnValue[2]; } } else { $form_ele = $deReturnValue; $isDisabled = false; } if ($form_ele == "not_allowed") { continue; } elseif ($form_ele == "hidden") { $cueEntryValue = $entry ? $entry : "new"; $cueElement = new xoopsFormHidden("decue_" . $fid . "_" . $cueEntryValue . "_" . $thisElement, 1); print $cueElement->render(); if (is_array($hiddenElements)) { foreach ($hiddenElements as $thisHiddenElement) { if ($is_object($thisHiddenElement)) { print $thisHiddenElement->render() . "\n"; } } } elseif (is_object($hiddenElements)) { print $hiddenElements->render() . "\n"; } continue; } else { $thisElementObject = $element_handler->get($thisElement); $req = !$isDisabled ? intval($thisElementObject->getVar('ele_req')) : 0; $formObjectForRequiredJS->addElement($form_ele, $req); $elementMarkup = $form_ele->render(); $elementCaption = displayCaption("", $thisElement); $elementDescription = displayDescription("", $thisElement); $templateVariables['elementObjectForRendering'] = $form_ele; $templateVariables['elementCaption'] = $elementCaption; // here we can assume that the $previousPageButton etc has not be changed before rendering $templateVariables['elementMarkup'] = $elementMarkup; $templateVariables['elementDescription'] = $elementDescription; $templateVariables['element_id'] = $thisElement; formulize_renderTemplate('elementtemplate', $templateVariables, $screen->getVar('sid')); } } // now we also need to add in some bits that are necessary for the form submission logic to work...borrowed from parts of formdisplay.php mostly...this should be put together into a more distinct rendering system for forms, so we can call the pieces as needed print "<input type=hidden name=formulize_currentPage value='" . $settings['formulize_currentPage'] . "'>"; print "<input type=hidden name=formulize_prevPage value='" . $settings['formulize_prevPage'] . "'>"; print "<input type=hidden name=formulize_doneDest value='" . $settings['formulize_doneDest'] . "'>"; print "<input type=hidden name=formulize_buttonText value='" . $settings['formulize_buttonText'] . "'>"; print "<input type=hidden name=ventry value='" . $settings['ventry'] . "'>"; print $GLOBALS['xoopsSecurity']->getTokenHTML(); if ($entry) { print "<input type=hidden name=entry" . $fid . " value=" . intval($entry) . ">"; // need this to persist the entry that the user is } print "</form></div>"; print "<div id=savingmessage style=\"display: none; position: absolute; width: 100%; right: 0px; text-align: center; padding-top: 50px;\">\n"; if (file_exists(XOOPS_ROOT_PATH . "/modules/formulize/images/saving-" . $xoopsConfig['language'] . ".gif")) { print "<img src=\"" . XOOPS_URL . "/modules/formulize/images/saving-" . $xoopsConfig['language'] . ".gif\">\n"; } else { print "<img src=\"" . XOOPS_URL . "/modules/formulize/images/saving-english.gif\">\n"; } print "</div>\n"; drawJavascript(); // need to create the form object, and add all the rendered elements to it, and then we'll have working required elements if we render the validation logic for the form print $formObjectForRequiredJS->renderValidationJS(true, true); // with tags, true, skip the extra js that checks for the formulize theme form divs around the elements so that conditional animation works, true // print "<script type=\"text/javascript\">function xoopsFormValidate_formulize(){return true;}</script>"; // shim for the validation javascript that is created by the xoopsThemeForms, and which our saving logic currently references...saving won't work without this...we should actually render the proper validation logic at some point, but not today. } else { displayForm($forminfo, $entry, $mainform, "", $buttonArray, $settings, $titleOverride, $overrideValue, "", "", 0, 0, $printall, $screen); // nmc 2007.03.24 - added empty params & '$printall' } formulize_benchmark("After displayForm."); } if ($currentPage != $thanksPage and !$_POST['goto_sfid']) { // have to get the new value for $pageSelection list if the user requires it on the users view. $pageSelectionList = pageSelectionList($currentPage, $totalPages, $pageTitles, "below"); print "<form name=\"pageNavOptions_below\" id=\"pageNavOptions_below\">\n"; if ($screen and $bottomtemplate = $screen->getTemplate('bottomtemplate')) { $templateVariables['pageSelectionList'] = $pageSelectionList; // assign the new pageSelectionList, since it was redone for the bottom section formulize_renderTemplate('bottomtemplate', $templateVariables, $screen->getVar('sid')); } else { drawPageNav($usersCanSave, $currentPage, $totalPages, "below", $nextPageButton, $previousPageButton, $skippedPageMessage, $pageSelectionList); } print "</form>"; } formulize_benchmark("End of displayFormPages."); }