function compileElements($fid, $form, $formulize_mgr, $prevEntry, $entry, $go_back, $parentLinks, $owner_groups, $groups, $overrideValue = "", $elements_allowed = "", $profileForm = "", $frid = "", $mid, $sub_entries, $sub_fids, $member_handler, $gperm_handler, $title, $screen = null, $printViewPages = "", $printViewPageTitles = "") { include_once XOOPS_ROOT_PATH . '/modules/formulize/include/elementdisplay.php'; $entryForDEElements = is_numeric($entry) ? $entry : "new"; // if there is no entry, ie: a new entry, then $entry is "" so when writing the entry value into decue_ and other elements that go out to the HTML form, we need to use the keyword "new" global $xoopsDB, $xoopsUser; $elementsAvailableToUser = array(); // set criteria for matching on display // set the basics that everything has to match $criteriaBase = new CriteriaCompo(); $criteriaBase->add(new Criteria('ele_display', 1), 'OR'); foreach ($groups as $thisgroup) { $criteriaBase->add(new Criteria('ele_display', '%,' . $thisgroup . ',%', 'LIKE'), 'OR'); } if (is_array($elements_allowed) and count($elements_allowed) > 0) { // if we're limiting the elements, then add a criteria for that (multiple criteria are joined by AND unless you specify OR manually when adding them (as in the base above)) $criteria = new CriteriaCompo(); $criteria->add(new Criteria('ele_id', "(" . implode(",", $elements_allowed) . ")", "IN")); $criteria->add($criteriaBase); } else { $criteria = $criteriaBase; // otherwise, just use the base } $criteria->setSort('ele_order'); $criteria->setOrder('ASC'); $elements =& $formulize_mgr->getObjects($criteria, $fid, true); // true makes the keys of the returned array be the element ids $count = 0; global $gridCounter; $gridCounter = array(); $inGrid = 0; formulize_benchmark("Ready to loop elements."); // set the array to be used as the structure of the loop, either the passed in elements in order, or the elements as gathered from the DB // ignore passed in element order if there's a screen in effect, since we assume that official element order is authoritative when screens are involved // API should still allow arbitrary ordering, so $element_allowed can still be set manually as part of a displayForm call, and the order will be respected then if (!is_array($elements_allowed) or $screen) { $element_order_array = $elements; } else { $element_order_array = $elements_allowed; } // if this is a printview page, foreach ($element_order_array as $thisElement) { if (is_numeric($thisElement)) { // if we're doing the order based on passed in element ids... if (isset($elements[$thisElement])) { $i = $elements[$thisElement]; // set the element object for this iteration of the loop } else { continue; // do not try to render elements that don't exist in the form!! (they might have been deleted from a multipage definition, or who knows what) } $this_ele_id = $thisElement; // set the element ID number } else { // else...we're just looping through the elements directly from the DB $i = $thisElement; // set the element object $this_ele_id = $i->getVar('ele_id'); // get the element ID number } // check if we're at the start of a page, when doing a printable view of all pages (only situation when printViewPageTitles and printViewPages will be present), and if we are, then put in a break for the page titles if ($printViewPages) { if (!$currentPrintViewPage) { $currentPrintViewPage = 1; } while (!in_array($this_ele_id, $printViewPages[$currentPrintViewPage]) and $currentPrintViewPage <= count($printViewPages)) { $currentPrintViewPage++; } if ($this_ele_id == $printViewPages[$currentPrintViewPage][0]) { $form->insertBreak("<div id=\"formulize-printpreview-pagetitle\">" . $printViewPageTitles[$currentPrintViewPage] . "</div>", "head"); } } // check if this element is included in a grid, and if so, skip it // $inGrid will be a number indicating how many times we have to skip things if ($inGrid or isset($gridCounter[$this_ele_id])) { if (!$inGrid) { $inGrid = $gridCounter[$this_ele_id]; } $inGrid--; continue; } $uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : 0; $owner = getEntryOwner($entry, $fid); $ele_type = $i->getVar('ele_type'); $ele_value = $i->getVar('ele_value'); if ($go_back['form']) { // if there's a parent form... // check here to see if we need to initialize the value of a linked selectbox when it is the key field for a subform // although this is setup as a loop through all found parentLinks, only the last one will be used, since ele_value[2] is overwritten each time. // assumption is there will only be one parent link for this form for ($z = 0; $z < count($parentLinks['source']); $z++) { if ($this_ele_id == $parentLinks['self'][$z]) { // this is the element $ele_value[2] = $go_back['entry']; // 3.0 datastructure...needs to be tested!! -- now updated for 5.0 } } } elseif ($overrideValue) { // used to force a default setting in a form element, other than the normal default if (!is_array($overrideValue)) { //convert a string to an array so that strings don't screw up logic below (which is designed for arrays) $temp = $overrideValue; unset($overrideValue); $overrideValue[0] = $temp; } // currently only operative for select boxes switch ($ele_type) { case "select": foreach ($overrideValue as $ov) { if (array_key_exists($ov, $ele_value[2])) { $ele_value[2][$ov] = 1; } } break; case "date": // debug //var_dump($overrideValue); foreach ($overrideValue as $ov) { //if(ereg ("([0-9]{4})-([0-9]{2})-([0-9]{2})", $ov, $regs)) { if (ereg("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $ov, $regs)) { $ele_value[0] = $ov; } } break; } } if ($ele_type != "subform" and $ele_type != 'grid') { // "" is framework, ie: not applicable // $i is element object // $entry is entry_id // false is "nosave" param...only used to force element to not be picked up by readelements.php after saving // $screen is the screen object // false means don't print it out to screen, return it here $GLOBALS['formulize_sub_fids'] = $sub_fids; // set here so we can pick it up in the render method of elements, if necessary (only necessary for subforms?); $deReturnValue = displayElement("", $i, $entry, false, $screen, $prevEntry, false, $profileForm, $groups); if (is_array($deReturnValue)) { $form_ele = $deReturnValue[0]; $isDisabled = $deReturnValue[1]; } else { $form_ele = $deReturnValue; $isDisabled = false; } $elementsAvailableToUser[$this_ele_id] = true; if ($form_ele == "not_allowed" or $form_ele == "hidden") { if (isset($GLOBALS['formulize_renderedElementHasConditions']["de_" . $fid . "_" . $entryForDEElements . "_" . $this_ele_id])) { // need to add a tr container for elements that are not allowed, since if it was a condition that caused them to not show up, they might appear later on asynchronously, and we'll need the row to attach them to if ($ele_type == "ib" and $form_ele == "not_allowed") { $rowHTML = "<tr style='display: none' id='formulize-de_" . $fid . "_" . $entryForDEElements . "_" . $this_ele_id . "'></tr>"; } elseif ($form_ele == "not_allowed") { $rowHTML = "<tr style='display: none' id='formulize-de_" . $fid . "_" . $entryForDEElements . "_" . $this_ele_id . "' valign='top' align='" . _GLOBAL_LEFT . "'></tr>"; } // need to also get the validation code for this element, wrap it in a check for the table row being visible, and assign that to the global array that contains all the validation javascript that we need to add to the form // following code follows the pattern set in elementdisplay.php for actually creating rendered element objects if ($ele_type != "ib") { $conditionalValidationRenderer = new formulizeElementRenderer($i); if ($prevEntry or $profileForm === "new") { $data_handler = new formulizeDataHandler($i->getVar('id_form')); $ele_value = loadValue($prevEntry, $i, $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 } $conditionalElementForValidiationCode = $conditionalValidationRenderer->constructElement("de_" . $fid . "_" . $entryForDEElements . "_" . $this_ele_id, $ele_value, $entry, $isDisabled, $screen); if ($js = $conditionalElementForValidiationCode->renderValidationJS()) { $GLOBALS['formulize_renderedElementsValidationJS'][$GLOBALS['formulize_thisRendering']][$conditionalElementForValidiationCode->getName()] = "if(window.document.getElementById('formulize-" . $conditionalElementForValidiationCode->getName() . "').style.display != 'none') {\n" . $js . "\n}\n"; } unset($conditionalElementForValidiationCode); unset($conditionalValidationRenderer); } $form->addElement($rowHTML); // since it was treated as a conditional element, and the user might interact with it, then we don't consider it a not-available-to-user element unset($elementsAvailableToUser[$this_ele_id]); } continue; } } $req = !$isDisabled ? intval($i->getVar('ele_req')) : 0; $GLOBALS['sub_entries'] = $sub_entries; if ($ele_type == "subform") { $thissfid = $ele_value[0]; if (!$thissfid) { continue; } // can't display non-specified subforms! $deReturnValue = displayElement("", $i, $entry, false, $screen, $prevEntry, false, $profileForm, $groups); // do this just to evaluate any conditions...it won't actually render anything, but will return "" for the first key in the array, if the element is allowed if (is_array($deReturnValue)) { $form_ele = $deReturnValue[0]; $isDisabled = $deReturnValue[1]; } else { $form_ele = $deReturnValue; $isDisabled = false; } if ($passed = security_check($thissfid) and $form_ele == "") { $GLOBALS['sfidsDrawn'][] = $thissfid; $customCaption = $i->getVar('ele_caption'); $customElements = $ele_value[1] ? explode(",", $ele_value[1]) : ""; if (isset($GLOBALS['formulize_inlineSubformFrid'])) { $newLinkResults = checkForLinks($GLOBALS['formulize_inlineSubformFrid'][0], array($fid), $fid, array($fid => array($entry)), null, $owner_groups, $mid, null, $owner, true); // final true means only include entries from unified display linkages $sub_entries = $newLinkResults['sub_entries']; } // 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 $subUICols = drawSubLinks($thissfid, $sub_entries, $uid, $groups, $frid, $mid, $fid, $entry, $customCaption, $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], $thisElement); if (isset($subUICols['single'])) { $form->insertBreak($subUICols['single'], "even"); } else { $subLinkUI = new XoopsFormLabel($subUICols['c1'], $subUICols['c2']); $form->addElement($subLinkUI); } unset($subLinkUI); } } elseif ($ele_type == "grid") { // we are going to have to store some kind of flag/counter with the id number of the starting element in the table, and the number of times we need to ignore things // we need to then listen for this up above and skip those elements as they come up. This is why grids must come before their elements in the form definition include_once XOOPS_ROOT_PATH . "/modules/formulize/include/griddisplay.php"; list($grid_title, $grid_row_caps, $grid_col_caps, $grid_background, $grid_start, $grid_count) = compileGrid($ele_value, $title, $i); $headingAtSide = ($ele_value[5] and $grid_title) ? true : false; // if there is a value for ele_value[5], then the heading should be at the side, otherwise, grid spans form width as it's own chunk of HTML $gridCounter[$grid_start] = $grid_count; $gridContents = displayGrid($fid, $entry, $grid_row_caps, $grid_col_caps, $grid_title, $grid_background, $grid_start, "", "", true, $screen, $headingAtSide); if ($headingAtSide) { // grid contents is the two bits for the xoopsformlabel when heading is at side, otherwise, it's just the contents for the break $form->addElement(new XoopsFormLabel($gridContents[0], $gridContents[1])); } else { $form->insertBreak($gridContents, "head"); // head is the css class of the cell } } elseif ($ele_type == "ib" or is_array($form_ele)) { // if it's a break, handle it differently...$form_ele may be an array if it's a non-interactive element such as a grid if (is_object($thisElement)) { // final param is used as id name in the table row where this element exists, so we can interact with it for showing and hiding $form->insertBreakFormulize("<div class=\"formulize-subform-heading\">" . trans(stripslashes($form_ele[0])) . "</div>", $form_ele[1], 'de_' . $fid . '_' . $entryForDEElements . '_' . $this_ele_id, $thisElement->getVar("ele_handle")); } } else { $form->addElement($form_ele, $req); } $count++; unset($hidden); unset($form_ele); // apparently necessary for compatibility with PHP 4.4.0 -- suggested by retspoox, sept 25, 2005 } formulize_benchmark("Done looping elements."); // find any hidden elements in the form, that aren't available to the user in this rendering of the form... unset($criteria); $notAllowedCriteria = new CriteriaCompo(); $notAllowedCriteria->add(new Criteria('ele_forcehidden', 1)); foreach ($elementsAvailableToUser as $availElementId => $boolean) { $notAllowedCriteria->add(new Criteria('ele_id', $availElementId, '!=')); } $notAllowedCriteria->setSort('ele_order'); $notAllowedCriteria->setOrder('ASC'); $notAllowedElements =& $formulize_mgr->getObjects($notAllowedCriteria, $fid); $hiddenElements = generateHiddenElements($notAllowedElements, $entryForDEElements); // in functions.php, keys in returned array will be the element ids foreach ($hiddenElements as $element_id => $thisHiddenElement) { $form->addElement(new xoopsFormHidden("decue_" . $fid . "_" . $entryForDEElements . "_" . $element_id, 1)); if (is_array($thisHiddenElement)) { // could happen for checkboxes foreach ($thisHiddenElement as $thisIndividualHiddenElement) { $form->addElement($thisIndividualHiddenElement); } } else { $form->addElement($thisHiddenElement); } unset($thisHiddenElement); // some odd reference thing going on here...$thisHiddenElement is being added by reference or something like that, so that when $thisHiddenElement changes in the next run through, every previous element that was created by adding it is updated to point to the next element. So if you unset at the end of the loop, it forces each element to be added as you would expect. } if ($entry and !is_a($form, 'formulize_elementsOnlyForm')) { // two hidden fields encode the main entry id, the first difficult-to-use format is a legacy thing // the 'lastentry' format is more sensible, but is only available when there was a real entry, not 'new' (also a legacy convention) $form->addElement(new XoopsFormHidden('entry' . $fid, $entry)); if (is_numeric($entry)) { $form->addElement(new XoopsFormHidden('lastentry', $entry)); } } if ($_POST['parent_form']) { // if we just came back from a parent form, then if they click save, we DO NOT want an override condition, even though we are now technically editing an entry that was previously saved when we went to the subform in the first place. So the override logic looks for this hidden value as an exception. $form->addElement(new XoopsFormHidden('back_from_sub', 1)); } // add a hidden element to carry all the validation javascript that might be associated with elements rendered with elementdisplay.php...only relevant for elements rendered inside subforms or grids...the validation code comes straight from the element, doesn't have a check around it for the conditional table row id, like the custom form classes at the top of the file use, since those elements won't render as hidden and show/hide in the same way if (isset($GLOBALS['formulize_renderedElementsValidationJS'][$GLOBALS['formulize_thisRendering']])) { $formulizeHiddenValidation = new XoopsFormHidden('validation', ''); foreach ($GLOBALS['formulize_renderedElementsValidationJS'][$GLOBALS['formulize_thisRendering']] as $thisValidation) { // grab all the validation code we stored in the elementdisplay.php file and attach it to this element foreach (explode("\n", $thisValidation) as $thisValidationLine) { $formulizeHiddenValidation->customValidationCode[] = $thisValidationLine; } } $form->addElement($formulizeHiddenValidation, 1); } if (get_class($form) == "formulize_elementsOnlyForm") { // forms of this class are ones that we're rendering just the HTML for the elements, and we need to preserve any validation javascript to stick in the final, parent form when it's finished $validationJS = $form->renderValidationJS(); if (trim($validationJS) != "") { $GLOBALS['formulize_elementsOnlyForm_validationCode'][] = $validationJS . "\n\n"; } } elseif (count($GLOBALS['formulize_elementsOnlyForm_validationCode']) > 0) { $elementsonlyvalidation = new XoopsFormHidden('elementsonlyforms', ''); $elementsonlyvalidation->customValidationCode = $GLOBALS['formulize_elementsOnlyForm_validationCode']; $form->addElement($elementsonlyvalidation, 1); } return $form; }
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; }