Exemplo n.º 1
0
 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;
 }
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
function formulize_screenLOEButton($button, $buttonText, $settings, $fid, $frid, $colhandles, $flatcols, $pubstart, $loadOnlyView, $calc_cols, $calc_calcs, $calc_blanks, $calc_grouping, $doNotForceSingle, $lastloaded, $currentview, $endstandard, $pickgroups, $viewoptions, $loadviewname, $advcalc_acid, $screen)
{
    static $importExportCleanupDone = false;
    if ($buttonText) {
        $buttonText = trans($buttonText);
        switch ($button) {
            case "modifyScreenLink":
                return "<a href=" . XOOPS_URL . "/modules/formulize/admin/ui.php?page=screen&sid=" . $screen->getVar('sid') . ">" . $buttonText . "</a>";
                break;
            case "changeColsButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=changecols value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/changecols.php?fid={$fid}&frid={$frid}&cols={$colhandles}');\"></input>";
                break;
            case "calcButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=calculations value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/pickcalcs.php?fid={$fid}&frid={$frid}&calc_cols=" . urlencode($calc_cols) . "&calc_calcs=" . urlencode($calc_calcs) . "&calc_blanks=" . urlencode($calc_blanks) . "&calc_grouping=" . urlencode($calc_grouping) . "&cols=" . urlencode($colhandles) . "&cols=" . urlencode($colhandles) . "');\"></input>";
                break;
            case "advCalcButton":
                // only if any procedures (advanced calculations) are defined for this form
                $procedureHandler = xoops_getmodulehandler('advancedCalculation', 'formulize');
                $procList = $procedureHandler->getList($fid);
                if (is_array($procList) and count($procList) > 0) {
                    return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=advcalculations value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/pickadvcalcs.php?fid={$fid}&frid={$frid}&{$advcalc_acid}');\"></input>";
                } else {
                    return false;
                }
                break;
            case "advSearchButton":
                $buttonCode = "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=advsearch value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/advsearch.php?fid={$fid}&frid={$frid}";
                foreach ($settings as $k => $v) {
                    if (substr($k, 0, 3) == "as_") {
                        $v = str_replace("'", "&#39;", $v);
                        $v = stripslashes($v);
                        $buttonCode .= "&{$k}=" . urlencode($v);
                    }
                }
                $buttonCode .= "');\"></input>";
                return $buttonCode;
                break;
            case "exportCalcsButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=export value='" . $buttonText . "' onclick=\"javascript:showExport();\"></input>";
                break;
            case "exportButton":
            case "importButton":
                // need to write the query to the cache folder so it can be picked up when needed
                $exportTime = time();
                $queryForExportFile = fopen(XOOPS_ROOT_PATH . "/cache/exportQuery_" . $exportTime . ".formulize_cached_query_for_export", "w");
                fwrite($queryForExportFile, $fid . "\n");
                global $xoopsUser;
                $exportUid = $xoopsUser ? $xoopsUser->getVar('uid') : 0;
                fwrite($queryForExportFile, $exportUid . "\n");
                fwrite($queryForExportFile, $GLOBALS['formulize_queryForExport']);
                fclose($queryForExportFile);
                // cleanup old export files
                if (!$importExportCleanupDone) {
                    formulize_benchmark("before scandir during export/import button creation");
                    formulize_scandirAndClean(XOOPS_ROOT_PATH . "/cache/", "exportQuery");
                    formulize_benchmark("after scandir during export/import button creation. " . count($formulize_export_cache_files) . " files found");
                    $importExportCleanupDone = true;
                }
                if ($button == "exportButton") {
                    return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=export value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/export.php?fid={$fid}&frid={$frid}&cols={$colhandles}&eq={$exportTime}');\"></input>";
                } else {
                    return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=impdata value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/import.php?fid={$fid}&eq={$exportTime}');\"></input>";
                }
                break;
            case "addButton":
                $addNewParam = $doNotForceSingle ? "" : "'single'";
                // force the addNew behaviour to single entry unless this button is being used on a single entry form, in which case we don't need to force anything
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=addentry value='" . $buttonText . "' onclick=\"javascript:addNew({$addNewParam});\"></input>";
                break;
            case "addMultiButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=addentry value='" . $buttonText . "' onclick=\"javascript:addNew();\"></input>";
                break;
            case "addProxyButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=addentry value='" . $buttonText . "' onclick=\"javascript:addNew('proxy');\"></input>";
                break;
            case "notifButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=notbutton value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/setnot.php?fid={$fid}');\"></input>";
                break;
            case "cloneButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=clonesel value='" . $buttonText . "' onclick=\"javascript:confirmClone();\"></input>";
                break;
            case "deleteButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=deletesel value='" . $buttonText . "' onclick=\"javascript:confirmDel();\"></input>";
                break;
            case "selectAllButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=sellall value='" . $buttonText . "' onclick=selectAll(this.check); ></input>";
                break;
            case "clearSelectButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=clearall value='" . $buttonText . "' onclick=unselectAll(this.uncheck); ></input>";
                break;
            case "resetViewButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=resetviewbutton value='" . $buttonText . "' onclick=\"javascript:showLoadingReset();\"></input>";
                break;
            case "saveViewButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=save value='" . $buttonText . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/save.php?fid={$fid}&frid={$frid}&lastloaded={$lastloaded}&cols={$flatcols}&currentview={$currentview}&loadonlyview={$loadOnlyView}');\"></input>";
                break;
            case "deleteViewButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=delete value='" . $buttonText . "' onclick=\"javascript:delete_view(this.form, '{$pubstart}', '{$endstandard}');\"></input>";
                break;
            case "currentViewList":
                $currentViewList = "<b>" . $buttonText . "</b><br><SELECT style=\"width: 350px;\" name=currentview id=currentview size=1 onchange=\"javascript:change_view(this.form, '{$pickgroups}', '{$endstandard}');\">\n";
                $currentViewList .= $viewoptions;
                $currentViewList .= "\n</SELECT>\n";
                if (!$loadviewname and strstr($currentview, ",") and !$loadOnlyView) {
                    // if we're on a genuine pick-groups view (not a loaded view)...and the load-only-view override is not in place (which eliminates other viewing options besides the loaded view)
                    $currentViewList .= "<br><input type=button name=pickdiffgroup value='" . _formulize_DE_PICKDIFFGROUP . "' onclick=\"javascript:showPop('" . XOOPS_URL . "/modules/formulize/include/changescope.php?fid={$fid}&frid={$frid}&scope={$currentview}');\"></input>";
                }
                return $currentViewList;
                break;
            case "saveButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=deSaveButton value='" . $buttonText . "' onclick=\"javascript:showLoading();\"></input>";
            case "goButton":
                return "<input type=button class=\"formulize_button\" id=\"formulize_{$button}\" name=deSubmitButton value='" . $buttonText . "' onclick=\"javascript:showLoading();\"></input>";
                break;
            case "globalQuickSearch":
                return "<input type=text id=\"formulize_{$button}\" name=\"global_search\" placeholder='" . $buttonText . "' value='" . $settings['global_search'] . "' onchange=\"javascript:window.document.controls.ventry.value = '';\"></input>";
                break;
        }
    } elseif ($button == "currentViewList") {
        // must always set a currentview value in POST even if the list is not visible
        return "<input type=hidden name=currentview value='{$currentview}'></input>\n";
    } else {
        return false;
    }
}
Exemplo n.º 5
0
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";
    }
}
Exemplo n.º 6
0
function formatLinks($matchtext, $handle, $textWidth = 35, $entryBeingFormatted)
{
    formulize_benchmark("start of formatlinks");
    global $xoopsDB, $myts;
    static $cachedValues = array();
    static $cachedTypes = array();
    $matchtext = $myts->undoHtmlSpecialChars($matchtext);
    if (isMetaDataField($handle)) {
        return printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth);
    }
    if (!isset($cachedValues[$handle])) {
        $elementMetaData = formulize_getElementMetaData($handle, true);
        $ele_value = unserialize($elementMetaData['ele_value']);
        $ele_type = $elementMetaData['ele_type'];
        if (!$ele_value) {
            return _formatLinksRegularElement($matchtext, $textWidth, $ele_type, $handle, $entryBeingFormatted);
        }
        if (!isset($ele_value[4])) {
            $ele_value[4] = 0;
        }
        if (!isset($ele_value[3])) {
            $ele_value[3] = 0;
        }
        $cachedValues[$handle] = $ele_value;
        $cachedTypes[$handle] = $ele_type;
    } else {
        $ele_value = $cachedValues[$handle];
        $ele_type = $cachedTypes[$handle];
    }
    formulize_benchmark("got element info");
    // dealing with a textbox where an associated element has been set
    if ($ele_value[4] > 0 and $ele_type == 'text' or $ele_value[3] > 0 and $ele_type == 'textarea') {
        $formulize_mgr = xoops_getmodulehandler('elements', 'formulize');
        if ($ele_type == 'text') {
            $target_element = $formulize_mgr->get($ele_value[4]);
        } else {
            $target_element = $formulize_mgr->get($ele_value[3]);
        }
        $target_fid = $target_element->getVar('id_form');
        // if user has no perm in target fid, then do not make link!
        if (!($target_allowed = security_check($target_fid))) {
            return printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth);
        }
        $matchtexts = explode(";", $matchtext);
        // have to breakup the textbox's text since it may contain multiple matches.  Note no space after semicolon spliter, but we trim the results in the foreach loop below.
        $printText = "";
        $start = 1;
        foreach ($matchtexts as $thistext) {
            $thistext = trim($thistext);
            if (!$start) {
                $printText .= ", ";
            }
            if ($id_req = findMatchingIdReq($target_element, $target_fid, $thistext)) {
                $printText .= "<a href='" . XOOPS_URL . "/modules/formulize/index.php?fid={$target_fid}&ve={$id_req}' target='_blank'>" . printSmart(trans($myts->htmlSpecialChars($thistext)), $textWidth) . "</a>";
            } else {
                $printText .= $myts->htmlSpecialChars($thistext);
            }
            $start = 0;
        }
        return $printText;
    } elseif ($ele_type == 'select' and is_string($ele_value[2]) and strstr($ele_value[2], "#*=:*") and $ele_value[7] == 1) {
        // dealing with a linked selectbox
        $boxproperties = explode("#*=:*", $ele_value[2]);
        // NOTE:
        // boxproperties[0] is form_id
        // [1] is handle of linked field
        $target_fid = $boxproperties[0];
        // if user has no perm in target fid, then do not make link!
        if (!($target_allowed = security_check($target_fid))) {
            return printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth);
        }
        static $cachedQueryResults = array();
        if (isset($cachedQueryResults[$boxproperties[0]][$boxproperties[1]][$entryBeingFormatted][$handle])) {
            $id_req = $cachedQueryResults[$boxproperties[0]][$boxproperties[1]][$entryBeingFormatted][$handle];
        } else {
            // should only be one match anyway, so limit 0,1 ought to be unnecessary
            $element_id_q = q("SELECT ele_id FROM " . $xoopsDB->prefix("formulize") . " WHERE id_form='" . $boxproperties[0] . "' AND ele_handle='" . formulize_db_escape($boxproperties[1]) . "' LIMIT 0,1");
            $formulize_mgr = xoops_getmodulehandler('elements', 'formulize');
            $target_element =& $formulize_mgr->get($element_id_q[0]['ele_id']);
            // get the targetEntry by checking in the entry we're processing, for the actual value recorded in the DB for the entry id we're pointing to
            $elementHandle = $handle;
            if (is_array($elementHandle)) {
                $elementHandle = $elementHandle[0];
            }
            $currentElementObject = $formulize_mgr->get($elementHandle);
            $currentFormId = $currentElementObject->getVar('id_form');
            $data_handler = new formulizeDataHandler($currentFormId);
            $matchEntryList = explode(",", trim($data_handler->getElementValueInEntry($entryBeingFormatted, $elementHandle), ","));
            $id_req = $matchEntryList[0];
            $cachedQueryResults[$boxproperties[0]][$boxproperties[1]][$entryBeingFormatted][$handle] = $id_req;
        }
        if ($id_req) {
            return "<a href='" . XOOPS_URL . "/modules/formulize/index.php?fid={$target_fid}&ve={$id_req}' target='_blank'>" . printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth) . "</a>";
        } else {
            // no id_req found
            return printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth);
        }
    } elseif ($ele_type == 'select' and (isset($ele_value[2]['{USERNAMES}']) or isset($ele_value[2]['{FULLNAMES}'])) and $ele_value[7] == 1) {
        $nametype = isset($ele_value[2]['{USERNAMES}']) ? "uname" : "name";
        $archiveFilter = $GLOBALS['formulize_archived_available'] ? " AND archived = 0" : "";
        static $cachedUidResults = array();
        if (isset($cachedUidResults[$matchtext])) {
            $uids = $cachedUidResults[$matchtext];
        } else {
            $uids = q("SELECT uid FROM " . $xoopsDB->prefix("users") . " WHERE {$nametype} = '" . formulize_db_escape($matchtext) . "' {$archiveFilter}");
            $cachedUidResults[$matchtext] = $uids;
        }
        if (count($uids) == 1) {
            return "<a href='" . XOOPS_URL . "/userinfo.php?uid=" . $uids[0]['uid'] . "' target=_blank>" . printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth) . "</a>";
        } else {
            return printSmart(trans($myts->htmlSpecialChars($matchtext)), $textWidth);
        }
    } elseif ($ele_type == 'derived') {
        return formulize_text_to_hyperlink($matchtext, $textWidth);
        // allow HTML codes in derived values
    } else {
        // regular element
        formulize_benchmark("done formatting, about to print");
        return _formatLinksRegularElement($matchtext, $textWidth, $ele_type, $handle, $entryBeingFormatted);
    }
}
Exemplo n.º 7
0
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.");
}