function export_data($queryData, $frid, $fid, $groups, $columns, $include_metadata) { global $xoopsDB; // generate the export filename, which the user will see $form_handler = xoops_getmodulehandler('forms', 'formulize'); $formObject = $form_handler->get($fid); if (is_object($formObject)) { $formTitle = "'" . str_replace(array(" ", "-", "/", "'", "`", "\\", ".", "?", ",", ")", "(", "[", "]"), "_", trans($formObject->getVar('title'))) . "'"; } else { $formTitle = "a_form"; } $export_filename = _formulize_EXPORT_FILENAME_TEXT . "_" . $formTitle . "_" . date("M_j_Y_Hi") . ".csv"; // output http headers header('Content-Description: File Transfer'); header('Content-Type: text/csv; charset=' . _CHARSET); header('Content-Disposition: attachment; filename=' . $export_filename); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); // get a list of columns for export $headers = array(); if ($include_metadata) { // include metadata columns if the user requested them $headers = array(_formulize_ENTRY_ID, _formulize_DE_CALC_CREATOR, _formulize_DE_CALC_MODIFIER, _formulize_DE_CALC_CREATEDATE, _formulize_DE_CALC_MODDATE); } else { if (in_array("entry_id", $columns)) { $headers[] = _formulize_ENTRY_ID; } if (in_array("uid", $columns) or in_array("creation_uid", $columns)) { $headers[] = _formulize_DE_CALC_CREATOR; } if (in_array("proxyid", $columns) or in_array("mod_uid", $columns)) { $headers[] = _formulize_DE_CALC_MODIFIER; } if (in_array("creation_date", $columns) or in_array("creation_datetime", $columns)) { $headers[] = _formulize_DE_CALC_CREATEDATE; } if (in_array("mod_date", $columns) or in_array("mod_datetime", $columns)) { $headers[] = _formulize_DE_CALC_MODDATE; } } foreach ($columns as $thiscol) { if ("creator_email" == $thiscol) { $headers[] = _formulize_DE_CALC_CREATOR_EMAIL; } else { $colMeta = formulize_getElementMetaData($thiscol, true); $headers[] = $colMeta['ele_colhead'] ? trans($colMeta['ele_colhead']) : trans($colMeta['ele_caption']); } } if ($include_metadata) { // include metadata columns if the user requested them $columns = array_merge(array("entry_id", "uid", "proxyid", "creation_date", "mod_date"), $columns); } if (strstr(strtolower(_CHARSET), 'utf') and $_POST['excel'] == 1) { echo ""; // necessary to trigger certain versions of Excel to recognize the file as unicode } // output export header $output_handle = fopen('php://output', 'w'); // open a file handle to stdout because fputcsv() needs it fputcsv($output_handle, $headers); // output export data $GLOBALS['formulize_doingExport'] = true; unset($queryData[0]); // get rid of the fid and userid lines unset($queryData[1]); $data_sql = implode(" ", $queryData); // merge all remaining lines into one string to send to getData $limitStart = 0; $limitSize = 50; // export in batches of 50 records at a time do { // load part of the data, since a very large dataset could exceed the PHP memory limit $data = getData($frid, $fid, $data_sql, "AND", null, $limitStart, $limitSize); if (is_array($data)) { foreach ($data as $entry) { $row = array(); foreach ($columns as $column) { switch ($column) { case "entry_id": $formhandle = getFormHandlesFromEntry($entry); $ids = internalRecordIds($entry, $formhandle[0]); $row[] = $ids[0]; break; case "uid": $c_uid = display($entry, 'creation_uid'); $c_name_q = q("SELECT name, uname FROM " . $xoopsDB->prefix("users") . " WHERE uid='{$c_uid}'"); $row[] = isset($c_name_q[0]['name']) ? $c_name_q[0]['name'] : $c_name_q[0]['uname']; break; case "proxyid": $m_uid = display($entry, 'mod_uid'); if ($m_uid) { $m_name_q = q("SELECT name, uname FROM " . $xoopsDB->prefix("users") . " WHERE uid='{$m_uid}'"); $row[] = isset($m_name_q[0]['name']) ? $m_name_q[0]['name'] : $m_name_q[0]['uname']; } else { $row[] = ""; } break; case "creation_date": $row[] = display($entry, 'creation_datetime'); break; case "mod_date": $row[] = display($entry, 'mod_datetime'); break; default: $row[] = trans(html_entity_decode(displayTogether($entry, $column, ", "), ENT_QUOTES)); } } // output this row to the browser fputcsv($output_handle, $row); } // get the next set of data set_time_limit(90); $limitStart += $limitSize; } } while (is_array($data) and count($data) > 0); fclose($output_handle); }
function sendNotifications($fid, $event, $entries, $mid = "", $groups = array()) { // don't send a notification twice, so we store what we have processed already and don't process again static $processedNotifications = array(); $serializedEntries = serialize($entries); if (isset($processedNotifications[$fid][$event][$serializedEntries])) { return; } $processedNotifications[$fid][$event][$serializedEntries] = true; // 1. Get all conditions attached to this fid for this event // 1b. determine what users have view_globalscope on the form, and what groups that the current user is a member of have view_groupscope on the form // 2. foreach entry, do the following // 4. foreach condition, do the following // 5. if there's actual terms attached to the condition, see if the entry matches the condition, and if not, move on to the next condition // 6. if there's a custom template or subject, then save that condition for later processing // 7. check the uid, curuser and groupid for this condition and store it // 8. after processing each condition // 9. set the intersection of the view_group/global users and the users in the conditions // 10. determine which users are not subscribed to this event // 11. subscribe the necessary users with a oncethendelete notification mode // 12. trigger this notification event // 13. foreach custom template and/or subject, do this // 14. determine the uid, curuser, groupid settings and gather the uids // 15. set the intersection of the users // 16. change the modinfo for this event so the custom template/subject is used // 17. determine the users subscribed and subscribe the necessary others with a oncethendelete mode // 18. trigger the notification global $xoopsDB, $xoopsUser, $xoopsConfig; $uid = $xoopsUser ? $xoopsUser->getVar('uid') : 0; // 1. get all conditions for this fid and event $cons = q("SELECT * FROM " . $xoopsDB->prefix("formulize_notification_conditions") . " WHERE not_cons_fid=" . intval($fid) . " AND not_cons_event=\"" . formulize_db_escape($event) . "\""); if (count($cons) == 0) { return; } if (!$mid) { $mid = getFormulizeModId(); } // 1b. get the complete list of all possible users to notify $gperm_handler =& xoops_gethandler('groupperm'); $member_handler =& xoops_gethandler('member'); // get uids of all users with global scope $groups_global = $gperm_handler->getGroupIds("view_globalscope", $fid, $mid); $global_uids = formulize_getUsersByGroups($groups_global, $member_handler); // get uids of all users with group scope who share a group membership with the owner of the entry, **and the shared membership is in a group that has access to the form** // start with users who have groupscope $groups_group = $gperm_handler->getGroupIds("view_groupscope", $fid, $mid); $group_user_ids = formulize_getUsersByGroups($groups_group, $member_handler); // get groups with view_form, $groups_view = $gperm_handler->getGroupIds("view_form", $fid, $mid); $notification_handler =& xoops_gethandler('notification'); // start main loop $notificationTemplateData = array(); foreach ($entries as $entry) { $notificationTemplateData[$entry] = ""; // user list is potentially different for each entry. ignore anything that was passed in for $groups if (count($groups) == 0) { // if no groups specified as the owner of the current entry, then let's get that from the table $data_handler = new formulizeDataHandler($fid); $groups = $data_handler->getEntryOwnerGroups($entry); } // get the uids of all the users who are members of groups that have a specified groupscope that includes a group that is an owner group of the entry if (!isset($formulize_permHandler)) { $formulize_permHandler = new formulizePermHandler($fid); } $groups_with_specified_scope = $formulize_permHandler->getGroupsHavingSpecificScope($groups); // gets groups that have specific scope that does not include these groups $groups_with_different_specified_scope = $formulize_permHandler->getGroupsHavingDifferentSpecificScope($groups); $specified_group_uids = array(); $specified_different_group_uids = array(); if ($groups_with_specified_scope !== false) { // array_intersect applied to groups that have groupscope permission, and the groups that have the specified scope over the ownergroups (just in case groups were picked in the perm UI, but groupscope itself was not assigned, or turned off) $specified_group_uids = formulize_getUsersByGroups(array_intersect((array) $groups_with_specified_scope, (array) $groups_group), $member_handler); } if ($groups_with_different_specified_scope !== false) { $specified_different_group_uids = formulize_getUsersByGroups(array_intersect((array) $groups_with_different_specified_scope, (array) $groups_group), $member_handler); } // take the intersection of groups with view form perm and the owner's groups (ie: the owner's groups that have view_form perm) $owner_groups_with_view = array_intersect($groups_view, $groups); // get users in the owners-groups-that-have-view_form-perm $owner_groups_user_ids = formulize_getUsersByGroups($owner_groups_with_view, $member_handler); // get the intersection of users in the owners-groups-that-have-view_form-perm and groups with groupscope $group_uids = array_intersect($group_user_ids, $owner_groups_user_ids); // remove the users from groups-with-a-specified-scope that doesn't-include-the-owner-groups, from the users that are part of dynamically generated groupscope (if a user has a specified scope, then that should override any dynamically generated scope, and if the specified scope does not include this entry's groups, then they need to be pulled) $group_uids = array_diff((array) $group_uids, (array) $specified_different_group_uids); $group_uids = array_unique(array_merge((array) $specified_group_uids, (array) $group_uids)); $uids_complete = array(0 => getEntryOwner($entry, $fid)); if (count($group_uids) > 0 and count($global_uids) > 0) { $uids_complete = array_unique(array_merge((array) $group_uids, (array) $global_uids, $uids_complete)); } elseif (count($group_uids) > 0) { $uids_complete = array_unique(array_merge((array) $group_uids, $uids_complete)); } elseif (count($global_uids) > 0) { $uids_complete = array_unique(array_merge((array) $global_uids, $uids_complete)); } $uids_conditions = array(); $saved_conditions = array(); $data = ""; foreach ($cons as $thiscon) { // there is a specific condition for this notification if ($thiscon['not_cons_con'] !== "all") { $thesecons = unserialize($thiscon['not_cons_con']); $elements = unserialize($thesecons[0]); $ops = unserialize($thesecons[1]); $terms = unserialize($thesecons[2]); $start = 1; $blankFilters = array(); for ($i = 0; $i < count($elements); $i++) { if ($ops[$i] == "NOT") { $ops[$i] = "!="; } if ($terms[$i] == "{BLANK}") { $blankFilter = $elements[$i] . "/**//**/" . $ops[$i] . "][" . $elements[$i] . "/**//**/"; if ($ops[$i] == "!=" or $ops[$i] == "NOT LIKE") { $blankFilters['and'][] = $blankFilter . " IS NOT NULL "; } else { $blankFilters['or'][] = $blankFilter . " IS NULL "; } continue; } $terms[$i] = parseUserAndToday($terms[$i]); if ($start) { $filter = $entry . "][" . $elements[$i] . "/**/" . $terms[$i] . "/**/" . $ops[$i]; $start = 0; } else { $filter .= "][" . $elements[$i] . "/**/" . $terms[$i] . "/**/" . $ops[$i]; } } if (isset($blankFilters['and'])) { foreach ($blankFilters['and'] as $thisAndFilter) { $filter .= "][" . $thisAndFilter; } } if (isset($blankFilters['or'])) { $filter = array(0 => array(0 => "and", 1 => $filter), 1 => array(0 => "or", 1 => implode("][", $blankFilters['or']))); } include_once XOOPS_ROOT_PATH . "/modules/formulize/include/extract.php"; $data = getData("", $fid, $filter); if ($data[0] == "") { continue; } } // condition passed the test, so check for custom template or subject if ($thiscon['not_cons_template'] or $thiscon['not_cons_subject']) { $saved_conditions[] = $thiscon; continue; // proceed to the next one } // passed the test and not custom, so save the uid, curuser, groupid info list($uids_conditions, $omit_user) = compileNotUsers($uids_conditions, $thiscon, $uid, $member_handler, false, $entry, $fid); } // end of each condition if (isset($GLOBALS['formulize_notification_email'])) { $uids_complete[] = -1; // if we are notifying an arbitrary e-mail address, then this uid will have been added to the uids_conditions array, so let's add it to the complete array, so that our notification doesn't get ignored as being "out of scope" based on uids } // intersect all possible uids with the ones valid for this condition, and handle subscribing necessary users $uids_real = compileNotUsers2($uids_conditions, $uids_complete, $notification_handler, $fid, $event, $mid); // cannot bug out (return) if $uids_real is empty, since there are still the custom conditions to evaluate below // get form object so the title can be used in notification messages static $formObjs = array(); // make this static so we don't have to hit the database over again if we've already got this form object include_once XOOPS_ROOT_PATH . "/modules/formulize/class/forms.php"; if (!isset($formObjs[$fid])) { $formObjs[$fid] = new formulizeForm($fid); } $extra_tags = array(); if ($xoopsUser) { $extra_tags['ENTRYUSERNAME'] = $xoopsUser->getVar('uname'); $extra_tags['ENTRYNAME'] = $xoopsUser->getVar('name') ? $xoopsUser->getVar('name') : $xoopsUser->getVar('uname'); } else { $extra_tags['ENTRYUSERNAME'] = _FORM_ANON_USER; } $extra_tags['FORMNAME'] = trans($formObjs[$fid]->getVar('title')); // determine if this is the profile form and if so, construct the URL for the notification differently // so the user goes to the userinfo.php page instead of the form page $config_handler =& xoops_gethandler('config'); $formulizeConfig =& $config_handler->getConfigsByCat(0, $mid); $profileFormId = $formulizeConfig['profileForm']; if ($profileFormId == $fid) { $owner = getEntryOwner($entry, $fid); $extra_tags['VIEWURL'] = XOOPS_URL . "/userinfo.php?uid={$owner}"; } else { $extra_tags['VIEWURL'] = XOOPS_URL . "/modules/formulize/index.php?fid={$fid}&ve={$entry}"; } $extra_tags['ENTRYID'] = $entry; $extra_tags['SITEURL'] = XOOPS_URL; if (count($uids_real) > 0) { if (in_array(-1, $uids_real)) { sendNotificationToEmail($GLOBALS['formulize_notification_email'], $event, $extra_tags); unset($uids_real[array_search(-1, $uids_real)]); // now remove the special flag before triggering the event unset($uids_complete[array_search(-1, $uids_complete)]); // now remove the special flag before triggering the event unset($GLOBALS['formulize_notification_email']); } $notification_handler->triggerEvent("form", $fid, $event, $extra_tags, $uids_real, $mid, $omit_user); } unset($uids_real); // handle custom conditions foreach ($saved_conditions as $thiscon) { if ($thiscon['not_cons_template']) { $templateFileName = substr($thiscon['not_cons_template'], -4) == ".tpl" ? $thiscon['not_cons_template'] : $thiscon['not_cons_template'] . ".tpl"; if (!file_exists(XOOPS_ROOT_PATH . "/modules/formulize/language/" . $xoopsConfig['language'] . "/mail_template/" . $templateFileName)) { continue; } else { $templateFileContents = file_get_contents(XOOPS_ROOT_PATH . "/modules/formulize/language/" . $xoopsConfig['language'] . "/mail_template/" . $templateFileName); if (strstr($templateFileContents, "{ELEMENT")) { // gather the data for this entry and make it available to the template, since it uses an element tag in the message // Only do this getData call if we don't already have data from the database. $notificationTemplateData[$entry][0] == "" will probably never be true in Formulize 3.0 and higher, but will evaluate as expected, with a warning about [0] being an invalid offset or something like that if ($notificationTemplateData[$entry][0] == "" or $notificationTemplateData[$entry] == "") { include_once XOOPS_ROOT_PATH . "/modules/formulize/include/extract.php"; $notificationTemplateData[$entry] = getData("", $fid, $entry); } // get all the element IDs for the current form $form_handler = xoops_getmodulehandler('forms', 'formulize'); $formObject = $form_handler->get($fid); foreach ($formObject->getVar('elementHandles') as $elementHandle) { $extra_tags['ELEMENT' . strtoupper($elementHandle)] = trans(html_entity_decode(displayTogether($notificationTemplateData[$entry][0], $elementHandle, ", "), ENT_QUOTES)); // for legacy compatibility, we provide both with and without _ keys in the extra tags array. $extra_tags['ELEMENT_' . strtoupper($elementHandle)] = trans($extra_tags['ELEMENT' . strtoupper($elementHandle)]); } } } } $uids_cust_con = array(); list($uids_cust_con, $omit_user) = compileNotUsers($uids_cust_con, $thiscon, $uid, $member_handler, true, $entry, $fid); if (isset($GLOBALS['formulize_notification_email'])) { $uids_complete[] = -1; // if we are notifying an arbitrary e-mail address, then this uid will have been added to the uids_conditions array, so let's add it to the complete array, so that our notification doesn't get ignored as being "out of scope" based on uids } $uids_cust_real = compileNotUsers2($uids_cust_con, $uids_complete, $notification_handler, $fid, $event, $mid); // set the custom template and subject $module_handler =& xoops_gethandler('module'); $module =& $module_handler->get($mid); $not_config =& $module->getInfo('notification'); switch ($event) { case "new_entry": $evid = 1; break; case "update_entry": $evid = 2; break; case "delete_entry": $evid = 3; break; } $oldsubject = $not_config['event'][$evid]['mail_subject']; $oldtemp = $not_config['event'][$evid]['mail_template']; // rewrite the notification with the subject and template we want, then reset $GLOBALS['formulize_notificationTemplateOverride'] = $thiscon['not_cons_template'] == "" ? $not_config['event'][$evid]['mail_template'] : $thiscon['not_cons_template']; $GLOBALS['formulize_notificationSubjectOverride'] = $thiscon['not_cons_subject'] == "" ? $not_config['event'][$evid]['mail_subject'] : trans($thiscon['not_cons_subject']); $not_config['event'][$evid]['mail_template'] = $thiscon['not_cons_template'] == "" ? $not_config['event'][$evid]['mail_template'] : $thiscon['not_cons_template']; $not_config['event'][$evid]['mail_subject'] = $thiscon['not_cons_subject'] == "" ? $not_config['event'][$evid]['mail_subject'] : trans($thiscon['not_cons_subject']); // loop through the variables and do replacements in the subject, if any if (strstr($not_config['event'][$evid]['mail_subject'], "{ELEMENT")) { foreach ($extra_tags as $tag => $value) { str_replace("{" . $tag . "}", $value, $not_config['event'][$evid]['mail_subject']); str_replace("{" . $tag . "}", $value, $GLOBALS['formulize_notificationSubjectOverride']); } } // trigger the event if (count($uids_cust_real) > 0) { if (in_array(-1, $uids_cust_real)) { sendNotificationToEmail($GLOBALS['formulize_notification_email'], "cust", $extra_tags, $not_config['event'][$evid]['mail_subject'], $not_config['event'][$evid]['mail_template']); unset($uids_cust_real[array_search(-1, $uids_cust_real)]); // now remove the special flag before triggering the event unset($uids_complete[array_search(-1, $uids_complete)]); // now remove the special flag before triggering the event unset($GLOBALS['formulize_notification_email']); } $notification_handler->triggerEvent("form", $fid, $event, $extra_tags, $uids_cust_real, $mid, $omit_user); } $not_config['event'][$evid]['mail_subject'] = $oldsubject; $not_config['event'][$evid]['mail_template'] = $oldtemp; unset($GLOBALS['formulize_notificationTemplateOverride']); unset($GLOBALS['formulize_notificationSubjectOverride']); unset($uids_cust_real); unset($uids_cust_con); } unset($uids_conditions); unset($saved_conditions); } // end of each entry }