to the users.'); // If we're inheriting settings from a different forum, // then disable the inherited fields in the input. $disabled_form_input = ''; if ($inherit_id != -1) { $disabled_form_input = 'disabled="disabled"'; } $frm->addbreak("Inherit Forum Settings"); // First check if the settings for this forum are inherited by one or // more other forums and/or folders. Inherited inheritance is not // allowed, so if this is the case, choosing a forum to inherit from // is not allowed. $disabled_form_input_inherit = ''; $add_inherit_text = ""; if ($forum_id) { $slaves = phorum_api_forums_by_inheritance($forum_id); if (!empty($slaves)) { $disabled_form_input_inherit = 'disabled="disabled"'; $add_inherit_text = "<br />You cannot let this forum inherit its " . "settings from another forum, because the " . "following forums and or folders inherit from " . "the current forum already:<br /><ul>\n"; foreach ($slaves as $id => $data) { array_shift($data['forum_path']); $edit_url = phorum_admin_build_url(array('module=edit' . ($data['folder_flag'] ? 'folder' : 'forum'), "forum_id={$id}")); $add_inherit_text .= "<li><a href=\"{$edit_url}\">" . implode(" / ", $data['forum_path']) . "</li>\n"; } $add_inherit_text .= "</ul>\n"; } } $inherit_id_options = phorum_api_forums_get_inherit_id_options($forum_id); $row = $frm->addrow("Inherit the settings below this option from", $frm->select_tag("inherit_id", $inherit_id_options, $inherit_id, $disabled_form_input_inherit) . $add_inherit_text); } $frm->addbreak("Moderation / Permissions");
/** * This function can be used for creating and updating folders or forums and * for updating default forum settings. * * Here is an example for creating a forum below the folder with forum_id 1234, * which inherits its settings from the default forum settings. * <code> * $newforum = array( * 'forum_id' => NULL, * 'folder_flag' => 0, * 'parent_id' => 1234, * 'inherit_id' => 0, * 'name' => 'Foo bar baz talk' * ); * $forum = phorum_api_forums_save($newforum); * print "The forum_id for the new forum is " . $forum['forum_id'] . "\n"; * </code> * * This example will update some default forum settings. This will also * update the forums / folders that inherit their settings from the * default settings. * <code> * $newsettings = array( * 'display_ip_address' => 0, * 'count_views' => 1, * 'language' => 'foolang' * ); * phorum_api_forums_save($newsettings, PHORUM_FLAG_DEFAULTS); * </code> * * @param array $data * An array containing folder or forum data. This array should contain at * least the field "forum_id". This field can be NULL to create a new * entry with an automatically assigned forum_id (in which case you will * also need to provide at least the fields "folder_flag" and "name). * It can also be set to a forum_id to either update an existing entry or * to create a new one with the provided forum_id. * * @param boolean $flags * If the {@link PHORUM_FLAG_PREPARE} flag is set, then this function * will not save the data in the database. Instead, it will only prepare * the data for storage and return the prepared data. * If the {@link PHORUM_FLAG_DEFAULTS} flag is set, then the data will * be stored in the default forum settings. * * @return array * If the {@link PHORUM_FLAG_PREPARE} is set, this function will only * prepare the data for storage and return the prepared data array. * Otherwise, the stored data will be returned. The main difference is * that for new forums or folders, the forum_id field will be updated * to the newly assigned forum_id. */ function phorum_api_forums_save($data, $flags = 0) { global $PHORUM; // $data must be an array. if (!is_array($data)) { trigger_error('phorum_api_forums_save(): $data argument is not an array', E_USER_ERROR); return NULL; } // Used for keeping track of an existing db record. $existing = NULL; // Initialize data for saving default forum settings. if ($flags & PHORUM_FLAG_DEFAULTS) { $existing = empty($PHORUM['default_forum_options']) ? NULL : $PHORUM['default_forum_options']; // Force a few settings to static values to have the data // processed correctly by the code below. $data['forum_id'] = NULL; $data['parent_id'] = 0; $data['inherit_id'] = NULL; $data['folder_flag'] = 0; $data['name'] = 'Default settings'; } else { // We always require the forum_id field. For new forums, we want to // retrieve an explicit forum_id = NULL field. if (!array_key_exists('forum_id', $data)) { trigger_error('phorum_api_forums_save(): missing field "forum_id" ' . 'in the data array', E_USER_ERROR); return NULL; } if ($data['forum_id'] !== NULL && !is_numeric($data['forum_id'])) { trigger_error('phorum_api_forums_save(): field "forum_id" not NULL or numerical', E_USER_ERROR); return NULL; } // Check if we are handling an existing or new entry. $existing = NULL; if ($data['forum_id'] !== NULL) { $existing = phorum_api_forums_by_forum_id($data['forum_id'], PHORUM_FLAG_INCLUDE_INACTIVE); } // The forum_path is a field that is generated by the API code. So we // pull it from the incoming data array here. unset($data['forum_path']); } // Create a data array that is understood by the database layer. // We start out with the existing record, if we have one. $dbdata = $existing === NULL ? array() : $existing; // Merge in the fields from the $data argument. foreach ($data as $fld => $val) { $dbdata[$fld] = $val; } // Some checks when we are not handling saving of default settings. if (!($flags & PHORUM_FLAG_DEFAULTS)) { // By now, we need the folder_flag field, so we know what kind // of entry we are handling. if (!array_key_exists('folder_flag', $dbdata)) { trigger_error('phorum_api_forums_save(): missing field "folder_flag" ' . 'in the data array', E_USER_ERROR); return NULL; } // The folder_flag cannot change during the lifetime of an entry. if ($existing) { $check1 = $existing['folder_flag'] ? TRUE : FALSE; $check2 = $dbdata['folder_flag'] ? TRUE : FALSE; if ($check1 != $check2) { trigger_error("phorum_api_forums_save(): the folder_flag cannot change", E_USER_ERROR); return NULL; } } } // Find the fields specification to use for this record. $fields = $dbdata['folder_flag'] ? $PHORUM['API']['folder_fields'] : $PHORUM['API']['forum_fields']; // A copy of the $fields array to keep track of missing fields. $missing = $fields; // the empty array to collect custom fields $custom_forum_field_data = array(); // Check and format the provided fields. foreach ($dbdata as $fld => $val) { // Determine the field type. if (!array_key_exists($fld, $fields)) { $spec = array(FFLD_MS => 'm', FFLD_TYPE => 'custom_field'); } else { $spec = explode(':', $fields[$fld]); } $fldtype = $spec[FFLD_TYPE]; // For tracking if all required fields are available. unset($missing[$fld]); switch ($fldtype) { case 'int': $dbdata[$fld] = (int) $val; break; case 'inherit_id': // This is a special one. The database value is NULL or // a positive integer, but NULL is not an easy value to // use in HTML forms. Therefore, we also accept the value // -1 to indicate a NULL value here. $dbdata[$fld] = $val === NULL || $val == -1 ? NULL : (int) $val; break; case 'string': $dbdata[$fld] = trim($val); break; case 'bool': $dbdata[$fld] = $val ? 1 : 0; break; case 'array': $dbdata[$fld] = is_array($val) ? serialize($val) : ''; break; case 'custom_field': $custom_forum_field_data[$fld] = $val; unset($dbdata[$fld]); break; default: trigger_error('phorum_api_forums_save(): Illegal field type used: ' . htmlspecialchars($spec[FFLD_TYPE]), E_USER_ERROR); return NULL; break; } } // The forum_path is autogenerated and does not have to be provided. // Therefore, we take it out of the loop here. unset($missing['forum_path']); unset($dbdata['forum_path']); // Check if all required fields are available. if (count($missing)) { // Try to fill in some default values for the missing fields. foreach ($missing as $fld => $fldspec) { $spec = explode(':', $fldspec); if (isset($spec[FFLD_DEFAULT])) { $dbdata[$fld] = $spec[FFLD_DEFAULT]; unset($missing[$fld]); } } } // Apply inheritance driven settings to the data if some sort of // inheritance is configured. Options for this field are: // - NULL : no inheritance used // - 0 : inherit from the default forum options // - <forum_id> : inherit from the forum identified by this forum_id if ($dbdata['inherit_id'] !== NULL) { // Check if the settings for this forum aren't inherited by // a different forum already. Inherited inheritance is not allowed. if ($existing) { $childs = phorum_api_forums_by_inheritance($dbdata['forum_id']); if (!empty($childs)) { trigger_error('phorum_api_forums_save(): forum_id ' . $dbdata['forum_id'] . ' cannot inherit data from some ' . 'other forum or default settings, because on or more ' . 'other folders and/or forums are inheriting their data ' . 'from this one already. Inherited inheritance is not ' . 'allowed.', E_USER_ERROR); return NULL; } } // Inherit from the default settings. if ($dbdata['inherit_id'] == 0) { $defaults = $PHORUM['default_forum_options']; } else { // Inheriting from yourself? No way. if ($dbdata['inherit_id'] == $dbdata['forum_id']) { trigger_error('phorum_api_forums_save(): a forum or folder cannot ' . 'inherit settings from itself. Save was called for ' . 'forum_id ' . $dbdata['forum_id'] . ' with that same ' . 'forum_id set as the inherit_id.', E_USER_ERROR); return NULL; } $defaults = phorum_api_forums_by_forum_id($dbdata['inherit_id'], PHORUM_FLAG_INCLUDE_INACTIVE); // Check if the inherit_id forum was found. if ($defaults === NULL) { trigger_error('phorum_api_forums_save(): no forum found for ' . 'inherid_id ' . $dbdata['inherit_id'], E_USER_ERROR); return NULL; } // It is only allowed to inherit settings from forums. if (!empty($defaults['folder_flag'])) { trigger_error('phorum_api_forums_save(): inherit_id ' . $dbdata['inherit_id'] . ' points to a folder instead of ' . 'a forum. You can only inherit from forums.', E_USER_ERROR); return NULL; } // Inherited inheritance is not allowed. if ($defaults['inherit_id'] != -1) { trigger_error('phorum_api_forums_save(): inherit_id ' . $dbdata['inherit_id'] . ' points to a forum that ' . 'inherits settings itself. Inherited inheritance is ' . 'not allowed.', E_USER_ERROR); return NULL; } } // Overlay our data record with the inherited settings. if (is_array($defaults)) { foreach ($defaults as $fld => $value) { // We need to check if the $fld is in $fields, because we // could be applying forum defaults to a folder here. // A folder does not contain all the same fields as a forum. // Also check if we're handling a slave (s) field. if (isset($fields[$fld]) && $fields[$fld][0] == 's') { $dbdata[$fld] = $value; unset($missing[$fld]); } } } } // Check if there are any missing fields left. if (count($missing)) { trigger_error('phorum_api_forums_save(): Missing field(s) in the data: ' . implode(', ', array_keys($missing)), E_USER_ERROR); return NULL; } // If we are storing default settings, then filter the data array to // only contain fields that are no master fields. We could store them // unfiltered in the database, but this provides cleaner data. if ($flags & PHORUM_FLAG_DEFAULTS) { $filtered = array(); foreach ($dbdata as $fld => $value) { if (isset($fields[$fld]) && $fields[$fld][0] == 's') { $filtered[$fld] = $value; } } $dbdata = $filtered; } // Return the prepared data if the PHORUM_FLAG_PREPARE flag was set. if ($flags & PHORUM_FLAG_PREPARE) { return $dbdata; } // Store default settings in the database. if ($flags & PHORUM_FLAG_DEFAULTS) { // Create or update the settings record. $PHORUM['DB']->update_settings(array('default_forum_options' => $dbdata)); // Update the global default forum options variable, so it // matches the updated settings. $PHORUM['default_forum_options'] = $dbdata; // Update all forums that inherit the default settings. $childs = phorum_api_forums_by_inheritance(0); if (!empty($childs)) { foreach ($childs as $child) { phorum_api_forums_save(array('forum_id' => $child['forum_id'])); } } return $dbdata; } // Store the forum or folder in the database. if ($existing) { $PHORUM['DB']->update_forum($dbdata); } else { $dbdata['forum_id'] = $PHORUM['DB']->add_forum($dbdata); } if (is_array($custom_forum_field_data) && count($custom_forum_field_data) && !empty($dbdata['forum_id'])) { $PHORUM['DB']->save_custom_fields($dbdata['forum_id'], PHORUM_CUSTOM_FIELD_FORUM, $custom_forum_field_data); } // Handle changes that influence the forum tree paths. // We handle the updates in a separate function, because we need // to be able to do recursive handling for those. if (!$existing || $existing['parent_id'] != $dbdata['parent_id'] || $existing['vroot'] != $dbdata['vroot'] || $existing['name'] != $dbdata['name']) { $recurse = $existing ? TRUE : FALSE; if (!phorum_api_forums_update_path($dbdata, $recurse)) { return NULL; } } // Handle cascading of inherited settings. // Inheritance is only possible from existing forums that do not inherit // settings themselves. So only if the currently saved entry does match // those criteria, we might have to cascade. if ($existing && $existing['folder_flag'] == 0 && $existing['inherit_id'] == -1) { // Find the forums and folders that inherit from this forum. $childs = phorum_api_forums_by_inheritance($existing['forum_id']); // If there are child forums, then update their inherited settings. if (!empty($childs)) { foreach ($childs as $child) { phorum_api_forums_save(array('forum_id' => $child['forum_id'])); } } } return $dbdata; }