/[drupal]/contributions/modules/og_collections/og_collections.module
ViewVC logotype

Contents of /contributions/modules/og_collections/og_collections.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Sat Mar 15 20:16:45 2008 UTC (20 months, 1 week ago) by sdboyer
Branch: MAIN
CVS Tags: DRUPAL-5--1-0-BETA1, HEAD
Branch point for: DRUPAL-5
Changes since 1.1: +38 -32 lines
File MIME type: text/x-php
small tweaks and optimizations. ready for initial release
1 <?php
2 // $Id: og_collections.module,v 1.1 2008/03/13 20:12:56 sdboyer Exp $
3
4 /**
5 * @file
6 * The og_collections.module file, which manages the creation and deployment of
7 * 'Collections' of 'Pre-Configured Panels' in conjunction with Organic Groups.
8 *
9 * Collections are sets of panels (as in the Panels and OG Panels modules) that
10 * can be paired with group types. Once a collection of panels has been paired
11 * with a group type, every new group of that type will automatically be granted
12 * their own duplicate set of the panels in the collection.
13 *
14 */
15
16 /**
17 * Implementation of hook_help()
18 */
19 function og_collections_help($section) {
20 switch ($section) {
21 case 'admin/help#og_collections': // TODO write up quite a
22 }
23 }
24
25 /**
26 * Implementation of hook_menu()
27 */
28 function og_collections_menu($may_cache) {
29 if ($group_types = og_collections_group_types()) {
30 $multgrps = count($group_types) > 1 ? TRUE : FALSE;
31 }
32 $collectionsetting = variable_get('og_collections_settings', FALSE);
33 if ($may_cache) {
34 $items[] = array(
35 'path' => 'admin/og/og_collections',
36 'title' => t('OG Collections'),
37 'description' => t('Set up OG Panels to automatically generate associated sets of panels when new groups are created.'),
38 'callback' => 'drupal_get_form',
39 'callback arguments' => array('og_collections_admin'),
40 'access' => user_access('administer organic groups'),
41 'weight' => 0,
42 );
43 $items[] = array(
44 'path' => 'admin/og/og_collections/settings',
45 'title' => t('Collections Settings'),
46 'type' => MENU_DEFAULT_LOCAL_TASK,
47 'weight' => -10,
48 );
49 if ($group_types && $collectionsetting) { // at least one group type must have already been set, and collections must be enabled
50 if ($collectionsetting == 1) {
51 $pcpanels = FALSE;
52 }
53 else if ($collectionsetting == 2) {
54 $pcpanels = TRUE;
55 }
56 // sets up the pre-configured panel types selection tab
57 $items[] = array(
58 'path' => 'admin/og/og_collections/collectioncfg',
59 'title' => t('Collections'),
60 'description' => $pcpanels ? t('Select which pre-configured panels are to be used for each of your group type bundles.') : t('Select which pre-configured panels are to be used in your group bundle.'),
61 'callback' => 'og_collections_admin_collectioncfg',
62 'callback arguments' => array('default'),
63 'type' => MENU_LOCAL_TASK,
64 'access' => user_access('administer organic groups'),
65 'weight' => -4,
66 );
67 if ($collectionsetting == 2) {
68 $items[] = array(
69 'path' => 'admin/og/og_collections/collectioncfg/default',
70 'title' => t('Default'),
71 'type' => MENU_DEFAULT_LOCAL_TASK,
72 'access' => user_access('administer organic groups'),
73 );
74 $i = 1;
75 foreach ($group_types as $type => $name) {
76 $items[] = array(
77 'path' => 'admin/og/og_collections/collectioncfg/'. $type,
78 'title' => t($name),
79 'callback' => 'og_collections_admin_collectioncfg',
80 'callback arguments' => array($type), // for some reason, this argument isn't being passed. currently sporking it using arg() in the callback
81 'type' => MENU_LOCAL_TASK,
82 'access' => user_access('administer organic groups'),
83 'weight' => $i,
84 );
85 $i++;
86 }
87 }
88 // sets up the pre-configured panels configuration tab
89 $items[] = array(
90 'path' => 'admin/og/og_collections/pcpanelsetup',
91 'title' => t('Pre-Configured Panels'),
92 'description' => t('Configure the panels that make up your collection.'),
93 'callback' => 'og_collections_admin_pcpanelsetup',
94 'callback arguments' => array('default'),
95 'type' => MENU_LOCAL_TASK,
96 'access' => user_access('administer organic groups'),
97 'weight' => -2,
98 );
99 if ($collectionsetting == 2) {
100 $items[] = array(
101 'path' => 'admin/og/og_collections/pcpanelsetup/default',
102 'title' => t('Default'),
103 'description' => t('Configure the panels that make up your collection.'),
104 'type' => MENU_DEFAULT_LOCAL_TASK,
105 'access' => user_access('administer organic groups'),
106 );
107 $i = 1;
108 foreach ($group_types as $type => $name) {
109 $items[] = array(
110 'path' => 'admin/og/og_collections/pcpanelsetup/'. $type,
111 'title' => t($name),
112 'callback' => 'og_collections_admin_pcpanelsetup',
113 'callback arguments' => array($type),
114 'type' => MENU_LOCAL_TASK,
115 'access' => user_access('administer organic groups'),
116 'weight' => $i,
117 );
118 $i++;
119 }
120 }
121 $items[] = array(
122 'path' => 'admin/og/og_collections/pcpanel',
123 'callback' => 'og_collections_pcpanel_manage',
124 'type' => MENU_CALLBACK,
125 'access' => user_access('admnister organic groups'),
126 );
127 }
128 }
129 return $items;
130 }
131
132 /**
133 * Return the list of node types that have been classified by og as groups.
134 *
135 * Because of the omnipresent 'Default' collection, it's sometimes helpful to add a 'Default'
136 * value to the beginning of this array. That's what the first parameter is for.
137 *
138 * @param boolean $default, default FALSE
139 * indicates whether a 'Default' type should be added at the beginning of the array.
140 * @return array $group_types
141 * An associative array of the form [systemtypename] => [publicfacingntypeame] for all group types.
142 * Also can return FALSE if no groups have been defined.
143 */
144 function og_collections_group_types($default = FALSE) {
145 if ($group_types = variable_get('og_node_types', FALSE)) {
146 asort($group_types);
147 foreach ($group_types as $type) {
148 $group_types[$type] = node_get_types('name', $type);
149 }
150 if ($default) { // defaults to not, but if the caller requests it, the 'default' group is inserted at the beginning of the array
151 $group_types = array_merge(array('default' => 'Default'), $group_types);
152 }
153 }
154 return $group_types;
155 }
156
157 /**
158 * Renders the form for group collections settings
159 */
160 function og_collections_admin_collectioncfg($type) {
161 $group_types = og_collections_group_types(TRUE);
162 drupal_set_title("'". $group_types[$type] ."' Collection");
163 if (mysql_num_fields(db_query("SELECT * FROM {og_collections} WHERE grouptype = 'default'")) == 1) {
164 drupal_set_message("You need to create at least one pre-configured panel for OG Collections to operate properly. Use this form to create your first one.");
165 drupal_get_destination();
166 drupal_goto('admin/og/og_collections/pcpanel/form');
167 }
168 $collectionsetting = variable_get('og_collections_settings', FALSE);
169 // TODO Need to improve helptext considerably
170 if ($collectionsetting == 1) {
171 $helptext = '<p>This form allows you to control the overall configuration for your collection. You can also !link to the list below.';
172 }
173 elseif ($collectionsetting == 2) {
174 $helptext = "<p>This form allows you to control the overall configuration for each group type's pre-configured panel. You can also !link to the list below.";
175 }
176 $output = t($helptext, array('!link' => l(t('add a new pre-configured panel'), 'admin/og/og_collections/pcpanel/form', array(), drupal_get_destination())));
177 $output .= drupal_get_form('og_collections_collectioncfg_table', $type);
178 return $output;
179 }
180
181 /**
182 * FAPI definition for the configure overall collection settings form.
183 *
184 * @ingroup forms
185 * @param string $type
186 * The group type for which the collection settings are being edited.
187 *
188 */
189 function og_collections_collectioncfg_table($type) {
190 $collectioncfg = og_collections_load_collectioncfg($type);
191 $form['typevar'] = array('#type' => 'hidden', '#value' => $type);
192 // $form['#action'] = arg(3) ? url('admin/og/og_collections/'. $theme_key) : url('admin/build/block');
193 $form['#tree'] = TRUE;
194 // TODO add a default tab as a means of allowing people to add/remove panel pre-configured panels?
195 foreach ($collectioncfg as $pcpid => $pcpanel) {
196 $pcpanel = og_collections_load_pcpanel($pcpanel['did'], FALSE, $type);
197 $form[$pcpid]['page_title'] = array('#value' => '#'. $pcpid .': '. $pcpanel->page_title);
198 $form[$pcpid]['weight'] = array('#type' => 'weight', '#default_value' => $pcpanel->weight ? $pcpanel->weight : 0);
199 $form[$pcpid]['edit'] = array('#value' => l(t('Edit'), "admin/og/og_collections/pcpanel/form/$type/$pcpid", array(), drupal_get_destination()));
200 if ($type == 'default') {
201 $form[$pcpid]['delete'] = array('#value' => l(t('Delete'), "admin/og/og_collections/pcpanel/delete/$pcpid", array(), drupal_get_destination()));
202 }
203 if ($pcpanel->default_page == 1) {
204 $default_page = $pcpid;
205 }
206 if ($pcpanel->active == 1) {
207 $activelist[] = $pcpid;
208 }
209 if ($pcpanel->published == 1) {
210 $publist[] = $pcpid;
211 }
212 if ($pcpanel->show_blocks == 1) {
213 $blklist[] = $pcpid;
214 }
215 $optionshome[$pcpid] = '';
216 }
217
218 $options = $optionshome;
219 $optionshome[0] = t('<em>(Do not replace the group homepage with a pre-configured panel)</em>');
220 // $form[0]; // need to add something here that allows people to DESELECT something as the homepage
221 $form['active'] = array(
222 '#type' => 'checkboxes',
223 '#options' => $options,
224 '#default_value' => $activelist ? $activelist : NULL,
225 );
226 $form['default_page'] = array(
227 '#type' => 'radios',
228 '#options' => $optionshome,
229 '#default_value' => $default_page ? $default_page : 0,
230 );
231 $form['published'] = array(
232 '#type' => 'checkboxes',
233 '#options' => $options,
234 '#default_value' => $publist ? $publist : NULL,
235 );
236 $form['show_blocks'] = array(
237 '#type' => 'checkboxes',
238 '#options' => $options,
239 '#default_value' => $blklist ? $blklist : NULL,
240 );
241 $form['submit'] = array(
242 '#type' => 'submit',
243 '#value' => t('Save Collection'),
244 );
245 return $form;
246 }
247
248 /**
249 * Theme the collection settings form into a table.
250 *
251 * @ingroup themeable
252 */
253 function theme_og_collections_collectioncfg_table($form) {
254 $isdefault = $form['typevar']['#value'] == 'default' ? TRUE : FALSE;
255 foreach (element_children($form) as $pcpid) {
256 if (is_numeric($pcpid)) {
257 $rows[] = array(
258 drupal_render($form[$pcpid]['page_title']),
259 drupal_render($form['default_page'][$pcpid]),
260 drupal_render($form['active'][$pcpid]),
261 drupal_render($form['published'][$pcpid]),
262 drupal_render($form['show_blocks'][$pcpid]),
263 drupal_render($form[$pcpid]['weight']),
264 drupal_render($form[$pcpid]['edit']),
265 drupal_render($form[$pcpid]['delete']), // TODO figure out a way to get rid of this if !$isdefault
266 );
267 }
268 }
269
270 $output = drupal_render($form);
271 $oper = $isdefault ? array('data' => t('Operations'), 'align' => 'center', 'colspan' => 2) : array('data' => t('Operations'), 'align' => 'center', 'colspan' => 1);
272 $header = array(t('Panel Name'), t('Home Page'), t('Enabled'), t('Published'), t('Show Blocks'), t('Weight'), $oper);
273 return theme('table', $header, $rows). $output;
274 }
275
276 function og_collections_collectioncfg_table_validate($form_id, $form_values, $form) {
277 // what kind of validation actually needs to be done here? any?
278 }
279
280 function og_collections_collectioncfg_table_submit($form_id, $form_values) {
281 $type = $form_values['typevar'];
282 $collectioncfg = og_collections_load_collectioncfg($type);
283 foreach (array_keys($collectioncfg) as $pcpid) {
284 $collectioncfg[$pcpid]['active'] = (int) $form_values['default_page'] == $pcpid ? 1 : $form_values['active'][$pcpid] ? 1 : 0; // ensures that pcpanels set to be home pages are also active
285 $collectioncfg[$pcpid]['default_page'] = (int) $form_values['default_page'] == $pcpid ? 1 : 0;
286 $collectioncfg[$pcpid]['weight'] = (int) $form_values[$pcpid]['weight'];
287 $collectioncfg[$pcpid]['published'] = (int) $form_values['default_page'] == $pcpid ? 1 : ($form_values['published'][$pcpid]) == $pcpid ? 1 : 0; // ensures that pcpanels set to be home pages are also published
288 $collectioncfg[$pcpid]['show_blocks'] = (int) ($form_values['show_blocks'][$pcpid]) == $pcpid ? 1 : 0;
289 }
290 if (og_collections_save_collectioncfg($type, $collectioncfg, array_keys($collectioncfg))) {
291 drupal_set_message(t("Updated '$type' Collection."));
292 }
293 }
294
295 /**
296 * Render the page containing pcpanel-specific configuration links.
297 *
298 * @ingroup themeable
299 * @param string $type
300 * The group type for which the collection settings are being edited.
301 * @return string $output
302 * String of HTML that has (already) been rendered by the theme('page') function... TODO split this into a separate function so it can be themed
303 */
304 function og_collections_admin_pcpanelsetup($type) {
305 $group_types = og_collections_group_types(TRUE);
306 drupal_set_title("'". $group_types[$type] ."' Panels Collection");
307 if (count(db_fetch_array(db_query("SELECT * FROM {og_collections} WHERE grouptype = 'default'"))) == 1) {
308 drupal_set_message("You need to create at least one group panel pre-configured panel before you can start configuring them! Use this form to create one.");
309 drupal_get_destination();
310 drupal_goto('admin/og/og_collections/pcpanel/form');
311 }
312 $collectionsetting = variable_get('og_collections_settings', FALSE);
313 if ($collectionsetting == 1) {
314 $helptext = '<p>This form allows you to control the panel content and setup for each pre-configured panel. You can !link here, if desired.</p>';
315 $linktext = 'add a new pre-configured panel';
316 }
317 elseif ($collectionsetting == 2) {
318 $helptext = "<p>Because you have selected to allow every group type to maintain its own independent collection, this page will allow you to configure content and layout settings for pre-configured panels that are specific to each collection. However, !link will not immediately result in pre-configured panels that are specific to each collection.</p>
319 <p>Instead, OG Collections creates only one version for each pre-configured panel initially - the 'Default' version. Creating a collection-specific version for one of these panels is easy: simply select the group type from the secondary tabs list and click on any of the modification links that correspond to the pre-configured panel in the table below. The group type-specific pre-configured panel will be created automatically if you save your changes on that form.</p>
320 <p>However, it is strongly recommended that you set up your panel pre-configured panels in the Default type first. Until a version of a pre-configured panel is created for a given group type, that group type will utilize the default pre-configured panel loadout, but when you create the type-specific version, it will be an exact copy of all the settings pre-configured panel's Default settings. Consequently, it is to your advantage to load your Default pre-configured panel configurations out with as much common content as possible, THEN begin working on the type-specific pre-configured panels.</p>
321 <p>These are just guidelines. At any time, you can remove a type-specific pre-configured panel and cause the group type to begin using Default again instead. You can also copy panel pre-configured panel settings from one group type to another, if you want. But, NOTE that <strong>both of these options are completely irreversible</strong> short of restoring your database from a <a href=\"http://drupal.org/project/backup_migrate\">backup</a>.</p>";
322 $linktext = 'adding a new pre-configured panel';
323 }
324 $output = t($helptext, array('!link' => l(t($linktext), 'admin/og/og_collections/pcpanel/form', array(), drupal_get_destination())));
325
326 // looks like we may not need a form, as no data gets submitted or changed directly on this page...begin form substitution!
327 $collectioncfg = og_collections_load_collectioncfg($type);
328 $multi = $collectionsetting == 2 ? TRUE : FALSE;
329 $isdefault = strtolower($type) == 'default' ? TRUE : FALSE;
330
331 if (!$isdefault) {
332 foreach ($collectioncfg as $pcpid => $pcpanel) {
333 $pcpanel = og_collections_load_pcpanel($pcpanel['did'], FALSE, $type);
334 if ($pcpanel->active) {
335 $row = array();
336 $row['page_title'] = $pcpanel->page_title;
337 $row['usedef'] = $pcpanel->usedef ? 'Yes' : 'No';
338 $row['default_page'] = $pcpanel->default_page ? 'Yes' : 'No';
339 $row['content'] = l(t('Content'), "admin/og/og_collections/pcpanel/content/$type/$pcpid", array(), drupal_get_destination());
340 $row['layout'] = l(t('Layout'), "admin/og/og_collections/pcpanel/layout/$type/$pcpid", array(), drupal_get_destination());
341 $row['layset'] = l(t('Layout Settings'), "admin/og/og_collections/pcpanel/layset/$type/$pcpid", array(), drupal_get_destination());
342 $row['revert'] = $pcpanel->usedef ? 'Already Tied' : l(t('Revert'), "admin/og/og_collections/pcpanel/revert/$type/$pcpid", array(), drupal_get_destination());
343 $row['mirror'] = 'Coming Soon';
344
345 $rows[] = $row;
346 }
347 }
348 }
349 else {
350 foreach ($collectioncfg as $pcpid => $pcpanel) {
351 $pcpanel = og_collections_load_pcpanel($pcpanel['did'], FALSE);
352 if ($pcpanel->active) {
353 $row = array();
354 $row['page_title'] = $pcpanel->page_title;
355 $row['default_page'] = $pcpanel->default_page ? 'Yes' : 'No';
356 $row['content'] = l(t('Content'), "admin/og/og_collections/pcpanel/content/$pcpid", array(), drupal_get_destination());
357 $row['layout'] = l(t('Layout'), "admin/og/og_collections/pcpanel/layout/$pcpid", array(), drupal_get_destination());
358 $row['layset'] = l(t('Layout Settings'), "admin/og/og_collections/pcpanel/layset/$pcpid", array(), drupal_get_destination());
359 $row['mirror'] = 'Coming Soon';
360
361 $rows[] = $row; // any utility in making the rows array associative?
362 }
363 }
364 }
365
366 if ($isdefault) {
367 $header = array(t('Panel Name'), t('Home Page?'), t('Edit Content'), t('Edit Layout'), t('Edit Layout Settings'), t('Import Template'));
368 }
369 else {
370 $header = array(t('Panel Name'), t('Tied to Default'), t('Home Page?'), t('Edit Content'), t('Edit Layout'), t('Edit Layout Settings'), t('Revert to Default'), t('Import Template'));
371 }
372 $linktext = "admin/og/og_collections/collectioncfg";
373 $linktext .= $isdefault ? "" : "/$type";
374 $output .= theme('table', $header, $rows);
375 $output .= t('<p>Pre-configured panels that have been disabled in !panpcpanel will not appear in the above list. You must enable them before you can edit them here.</p>', array('!panpcpanel' => l(t('Panel Templates'), $linktext)));
376 return $output;
377 }
378
379 /*
380 * Form to add/edit a pre-configured panel. if a $did is passed in, it edits that pcpanel. if there's no $did, it creates a new pcpanel.
381 */
382 function og_collections_pcpanel_form($did = NULL) {
383 if ($did) {
384 $pcpanel = og_collections_load_pcpanel($did, FALSE);
385 }
386 drupal_set_title($did ? "Configure $pcpanel->page_title Template" : "Add New Pre-Configured Panel");
387
388 $form['page_title'] = array(
389 '#title' => t('Panel Name Title'),
390 '#type' => 'textfield',
391 '#required' => TRUE,
392 '#default_value' => $did ? $pcpanel->page_title : NULL,
393 '#disabled' => $pcpanel->default_page ? TRUE : FALSE,
394 '#description' => t('The title for the page and of the tab that will be used by default when this pre-configured panel is instantiated.'),
395 '#size' => 32,
396 );
397 $form['path'] = array(
398 '#title' => t('Default Path'),
399 '#type' => 'textfield',
400 '#default_value' => $pcpanel->default_page ? '' : $pcpanel->path,
401 '#required' => $pcpanel->default_page ? FALSE : TRUE,
402 '#description' => $pcpanel->default_page ? t('This pre-configured panel is currently set to act as the group home page and therefore cannot be assigned a default path.') : t('The sub-path (appearing after the root group path) this pre-configured panel will appear at upon instantiation.'),
403 '#disabled' => $pcpanel->default_page ? TRUE : FALSE,
404 '#size' => 32,
405 );
406 $form['show_blocks'] = array(
407 '#title' => t('Show blocks'),
408 '#type' => 'checkbox',
409 '#default_value' => $did ? $pcpanel->show_blocks : TRUE,
410 '#description' => t('If unchecked, unmodified instantiations of this pre-configured panel will NOT show the standard group blocks.'),
411 );
412 $form['published'] = array(
413 '#type' => 'checkbox',
414 '#title' => t('Published'),
415 '#default_value' => $did ? $pcpanel->published : FALSE,
416 '#description' => t('If unchecked, instantiations of this pre-configured panel will initially be unpublished and viewable only by site or group administrators. Keeping this unchecked is wise if the page contains information that is not automatically present on group creation, and having this page accessible but empty would reflect poorly on the group.'),
417 );
418
419 $form['submit'] = array(
420 '#type' => 'submit',
421 '#value' => $did ? t('Update Pre-configured Panel') : t('Create Pre-configured Panel'),
422 );
423 $form['did'] = array('#type' => 'value', '#value' => $did);
424 return $form;
425 }
426
427 // FIXME NEED a validation function to ensure that paths entered are valid.
428 function og_collections_pcpanel_form_validate($form_id, $form_values, $form) {
429
430 }
431
432 /**
433 * Creates a new panel pre-configured panel, or modifies an existing one. Also ensures that all relevant
434 * collectioncfgs are updated with the new panel information.
435 **/
436 function og_collections_pcpanel_form_submit($form_id, $form_values) {
437 if ($form_values['did']) {
438 $pcpanel = og_collections_load_pcpanel($form_values['did'], FALSE);
439 $pcpanel->page_title = $form_values['page_title'];
440 $pcpanel->path = $form_values['path'];
441 $pcpanel->show_blocks = $form_values['show_blocks'];
442 $pcpanel->published = $form_values['published'];
443 og_collections_save_pcpanel($pcpanel);
444 drupal_set_message(t('Pre-configured panel "'. $pcpanel->panel_title .'" has successfully been updated.'));
445 return 'admin/og/og_collections/collectioncfg'; // TODO return to the page that the edit was called from?
446 }
447 else {
448 // Create a new display in the default grouptype
449 $display = panels_new_display();
450 panels_save_display($display);
451 // grouptype doesn't need to be included; column defaults to 'default', and new panel pcpanels are always in the default grouptype
452 $pcpid = db_next_id("{og_collections_pcpanel}_pcpid");
453 og_collections_manage_db('pcpid_'. $pcpid, 'add');
454 db_query("INSERT INTO {og_collections_pcpanel} (did, pcpid) VALUES (%d, %d)", $display->did, $pcpid);
455 drupal_set_message(t("The pre-configured panel '%title' created, and has been added to the Default collection. You must now select a default layout.", array('%title' => $form_values['page_title'])));
456 // Update all collectioncfgs to reflect new pre-configured panel. might be worth turning this into a hook at some point, at least in the generalized module.
457 // if this mass-update method is useful somewhere else, split it out into some separate function
458 $conf = array(
459 'active' => 0,
460 'default_page' => 0,
461 'weight' => 0,
462 'did' => $display->did,
463 'usedef' => 1,
464 'page_title' => $form_values['page_title'],
465 'path' => $form_values['path'],
466 'published' => $form_values['published'],
467 'show_blocks' => $form_values['show_blocks'],
468 'grouptype' => 'default',
469 );
470 $group_types = og_collections_group_types(TRUE);
471 foreach (array_keys($group_types) as $type) {
472 $collectioncfg = og_collections_load_collectioncfg($type);
473 $collectioncfg[$pcpid] = $conf;
474 og_collections_save_collectioncfg($type, $collectioncfg, array($pcpid));
475 }
476 drupal_get_destination();
477 return 'admin/og/og_collections/pcpanel/layout/'. $pcpid; // redirect to layout selection
478 }
479 }
480
481 /**
482 * Central pre-configured panel management function, redirects requests based on supplemental args; takes any number of args that can be passed to the
483 * 'admin/og/og_collections/pcpanel' URL and dispatches them appropriately
484 */
485 function og_collections_pcpanel_manage() {
486 $args = func_get_args();
487 $op = array_shift($args);
488 $dest = drupal_get_destination();
489 $error = $success = '';
490 $collectionsetting = variable_get('og_collections_settings', FALSE);
491 $multi = $collectionsetting == 1 ? FALSE : TRUE;
492
493 switch ($op) {
494 case 'form':
495 if (!empty($args[0]) && !empty($args[1])) {
496 if (is_string($args[0]) && is_numeric($args[1])) {
497 if ($pcpanel = og_collections_load_pcpanel(array($args[0], $args[1]))) {
498 $output = drupal_get_form('og_collections_pcpanel_form', $pcpanel->did);
499 }
500 else {
501 $error = 'No pre-configured panel was loaded with the arguments provided.';
502 break;
503 }
504 }
505 else {
506 $error = 'The arguments provided were in an invalid format.';
507 break;
508 }
509 }
510 else {
511 $output = drupal_get_form('og_collections_pcpanel_form');
512 }
513 return $output;
514
515 case 'layout':
516 case 'content': // FIXME display_edit.inc in Panels needs to be updated with a different return value if the form is cancelled. Or something.
517 case 'layset':
518 if (is_numeric($args[0])) { // editing the default version of a pre-configured panel
519 list($pcpid) = $args;
520 $result = og_collections_pcpanel_edit($op, $pcpid, $error, $success);
521 }
522 elseif (is_string($args[0])) { // editing a group type specific version of a pre-configured panel
523 list($type, $pcpid) = $args;
524 $result = og_collections_pcpanel_edit($op, $pcpid, $error, $success, $type);
525 }
526 if ($result) {
527 return $result; // only anything is returned into result is when the form strings need to be returned for processing
528 }
529 // all other situations (errors, success, whatever), result in a break
530 break;
531
532 case 'revert': // reverting a given page pcpanel to default and re-linking it
533 if (!$multi) {
534 $error = 'Reversion is pointless if you are using only one collection for all your group types. How did you even GET here!?!'; // =)
535 break;
536 }
537 if (isset($args[0], $args[1])) {
538 if (is_string($args[0]) && is_numeric($args[1])) {
539 $pcpanel = og_collections_load_pcpanel(array($args[0], $args[1]), FALSE);
540 return drupal_get_form('og_collections_pcpanel_revert_confirm', $pcpanel);
541 }
542 }
543 break;
544
545 case 'delete': // delete a given pcpanel
546 if (!isset($args[0]) || !is_numeric($args[0])) {
547 $error = 'A valid pcpid must be supplied if you want to delete a pre-configured panel.';
548 break;
549 }
550 if ($multi) {
551 $dids = db_num_rows(db_query("SELECT * FROM {og_collections_pcpanel} WHERE pcpid = %d", $args[0]));
552 drupal_set_message(t('WARNING: Deleting this pre-configured panel will remove it for ALL group types. This will result in the automatic, irreversible deletion of the <strong>%dids</strong> uniquely configured display(s) that correspond to this pre-configured panel. If you just want the pre-configured panel to not be instantiated for a particular group type, simply disable it on the !link', array('%dids' => $dids, '!link' => l(t('Panel Templates'), 'admin/og/og_collections/collectioncfg'))));
553 }
554 return drupal_get_form('og_collections_pcpanel_delete_confirm', $args[0], $multi);
555 break;
556
557 }
558 if (!empty($error)) {
559 drupal_set_message($error, 'error');
560 drupal_goto();
561 }
562 elseif (!empty($success)) {
563 drupal_set_message($success);
564 drupal_goto();
565 }
566 }
567
568 function og_collections_pcpanel_revert_confirm($pcpanel) {
569 $form['pcpid'] = array('#type' => 'value', '#value' => $pcpanel->pcpid);
570 $form['type'] = array('#type' => 'value', '#value' => $pcpanel->grouptype);
571 $form['page_title'] = array('#type' => 'value', '#value' => $pcpanel->page_title);
572
573 return confirm_form($form,
574 t('Are you sure you want to revert the type-specific pre-configured panel %title back to the Default type?', array('%title' => $pcpanel->page_title)),
575 "admin/og/og_collections/pcpanelsetup/$pcpanel->grouptype",
576 t('This action CANNOT be undone; any custom type-specific changes you have made to this pre-configured panel will be PERMANENTLY lost.'),
577 t('Revert'), t('Cancel')
578 );
579 }
580
581 function og_collections_pcpanel_revert_confirm_submit($form_id, $form_values) {
582 $pcpanel = og_collections_load_pcpanel(array($form_values['type'], $form_values['pcpid']), FALSE);
583 $defcollectioncfg = og_collections_load_collectioncfg();
584 $collectioncfg = og_collections_load_collectioncfg($pcpanel->grouptype);
585 $collectioncfg[$pcpanel->pcpid]['usedef'] = 1;
586 $collectioncfg[$pcpanel->pcpid]['did'] = $defcollectioncfg[$pcpanel->pcpid]['did'];
587 panels_delete_display($pcpanel->did);
588 db_query("DELETE FROM {og_collections_pcpanel} WHERE pcpid = %d AND grouptype = '%s'", $pcpanel->pcpid, $pcpanel->grouptype);
589 og_collections_save_collectioncfg($pcpanel->grouptype, $collectioncfg, array($pcpanel->pcpid));
590 }
591
592
593 function og_collections_pcpanel_delete_confirm($pcpid) {
594 $collectioncfg = og_collections_load_collectioncfg();
595 $form['pcpid'] = array('#type' => 'value', '#value' => $pcpid);
596 $form['page_title'] = array('#type' => 'value', '#value' => $collectioncfg[$pcpid]['page_title'] ? $collectioncfg[$pcpid]['page_title'] : '');
597
598 return confirm_form($form,
599 t('Are you sure you want to delete the %title pre-configured panel?', array('%title' => $collectioncfg[$pcpid]['page_title'] ? $collectioncfg[$pcpid]['page_title'] : '')),
600 isset($_GET['destination']) ? $_GET['destination'] : 'admin/og/og_collections/collectioncfg',
601 t('This action CANNOT be undone.'),
602 t('Delete'), t('Cancel')
603 );
604 }
605
606 function og_collections_pcpanel_delete_confirm_submit($form_id, $form_values) {
607 og_collections_pcpanel_delete($form_values['pcpid']);
608 drupal_set_message(t('%title has been deleted.', array('%title' => $form_values['page_title'])));
609 }
610
611 // very dangerous function. validate thoroughly before calling.
612 function og_collections_pcpanel_delete($pcpid) {
613 $result = db_query("SELECT did FROM {og_collections_pcpanel} WHERE pcpid = %d", $pcpid);
614 while ($row = db_fetch_array($result)) {
615 panels_delete_display($row['did']);
616 }
617 db_query("DELETE FROM {og_collections_pcpanel} WHERE pcpid = %d", $pcpid);
618 og_collections_manage_db('pcpid_'. $pcpid, 'drop');
619 }
620
621 /*
622 * Function that handles the panels API editing for all three panels
623 * editing types - display editing (i.e., content), layout, and layout settings.
624 */
625 function og_collections_pcpanel_edit($op, $pcpid, &$error, &$success, $type = 'default') {
626 if (!$pcpanel = og_collections_load_pcpanel(array($type, $pcpid), TRUE)) {
627 if (!$pcpanel = og_collections_load_pcpanel(array('default', $pcpid), TRUE, $type)) { // only way this happens is with a bad pcpid. error out.
628 $error .= 'ERROR: Bad pcpid provided. The pre-configured panel you are attempting to edit does not exist.';
629 return FALSE;
630 }
631 $isnew = TRUE;
632 if (isset($_POST['op'])) {
633 if ($_POST['op'] == 'Save') { // this is the second passthrough, and the user has chosen to save the panel; we slip the exported panel w/the 'new' $did so the submit function operates on that one instead
634 og_collections_export_display($pcpanel->display);
635 }
636 elseif ($_POST['op'] == 'Cancel') {
637 $success = t('Operation cancelled. A collection-specific panel has NOT been created; your pre-configured panel is still tied to the Default.');
638 return $success;
639 }
640 }
641 else {
642 $group_types = og_collections_group_types();
643 $newdisplay = 'NOTE: The !grouptype collection is currently tied to the Default type for this panel. If you save changes on this page, a version of this pre-configured panel specific to the !grouptype collection will be generated, and this panel\'s link to the Default pre-configured panel will be broken.';
644 drupal_set_message(t($newdisplay, array('!grouptype' => $group_types[$type])));
645 }
646 }
647 switch ($op) {
648 case 'content':
649 $saved = panels_edit($pcpanel->display, NULL, $pcpanel->display->content_types);
650 break;
651 case 'layout':
652 $saved = panels_edit_layout($pcpanel->display, t('Save'), NULL);
653 break;
654 case 'layset':
655 $saved = panels_edit_layout_settings($pcpanel->display, t('Save'), NULL);
656 break;
657 }
658
659 if (!isset($_POST['op'])) {
660 $error = FALSE;
661 if ($op == 'content') {
662 print theme('page', $saved, FALSE);
663 return FALSE;
664 }
665 return $saved;
666 }
667 elseif ($_POST['op'] == 'Save' && is_object($saved)) { // if it's not an object at this stage, something's wrong. error out
668 if ($isnew) {
669 $pcpanel->display = $saved;
670 $pcpanel->did = $pcpanel->display->did;
671 $pcpanel->usedef = 0;
672 $pcpanel->grouptype = $type;
673 og_collections_save_pcpanel($pcpanel, TRUE);
674 }
675 $success = 'The settings for this pre-configured panel have been successfully updated.';
676 }
677 else {
678 $error .= 'An unknown error occurred, causing the panels edit function to return an unidentified string. No changes have been saved to the pre-configured panel, but changes MAY have been saved to the panels display.'; // returns string on errors
679 }
680 }
681
682 function og_collections_admin() {
683 $ops = variable_get('og_collections_settings', 0);
684 $helptext = t("<p>Group 'pre-configured panels' are saved collections of panels and settings that encompass all the options you are able to manually set for an individual group using OG Panels. By defining collections, you can automatically apply these collections to new groups as they are created.</p>");
685 switch ($ops) {
686 case 0:
687 $helptext .= t("
688 <p>Once activated, OG Collections allows varying levels of granularity in configuring these pre-configured panels. However, collections are currently disabled. Select one of the 'Enabled' settings below to begin collections.</p>
689 <ul><li>Selecting 'Enabled - One Overall Template' will cause ALL of your group types to use the same pre-configured panel.</li>
690 <li>Selecting 'Enabled - Templates Per Type' will allow you to define pre-configured panels for each group type you have defined in !ogadmin.</li></ul>", array('!ogadmin' => l(t('Organic Groups Configuration'), 'admin/og/og')));
691 break;
692 case 1:
693 // TODO need to write up additional helptext for circumstances where the user may be switching from one collections configuration to another, once the backend has been written
694
695 break;
696 case 2:
697 // TODO ditto above
698 break;
699 }
700
701 $options = array('Disabled', 'Enabled - One Overall Template', 'Enabled - Templates Per Type');
702 $form['og_collections']['helptext'] = array('#value' => $helptext);
703 $form['og_collections']['collectionsetting'] = array (
704 '#type' => 'radios',
705 '#title' => t('Group Collections Settings'),
706 '#options' => $options,
707 '#default_value' => $ops,
708 '#required' => TRUE,
709 );
710 $form['submit'] = array(
711 '#type' => 'submit',
712 '#value' => t('Save Configuration'),
713 '#id' => 'panels-dnd-save',
714 );
715 return $form;
716 }
717
718 function og_collections_admin_submit($form, $form_values) {
719 variable_set('og_collections_settings', $form_values['collectionsetting']);
720 if ($form_values['collectionsetting'] == 0) {
721 $msg = t('Group Collections have been disabled. Any pre-configured panel configuration you have done will be accessible if you reactive Group Collections.');
722 }
723 else if ($form_values['collectionsetting'] == 1) {
724 $msg = t('Group Collections have been enabled, using one collection for all group types. You can configure your collection in !ogpanel.', array('!ogpanel' => l(t('Panel Templates'), 'admin/og/og_collections/collectioncfg')));
725 }
726 else if ($form_values['collectionsetting'] == 2) {
727 $msg = t("Group Collections have been enabled, with one pre-configured panel allowed per group type. You can configure all of your collections in !ogpanel. Make sure to set up pre-configured panels for all desired group types now, as there is currently no way to retrofit existing groups with pre-configured panels you update later.", array('!ogpanel' => l(t('OG Collections Configuration'), 'admin/og/og_collections/collectioncfg')));
728 }
729 drupal_set_message($msg);
730 cache_clear_all('*', 'cache_menu', TRUE);
731 return NULL;
732 }
733
734 /**
735 * Implementation of hook_nodeapi()
736 *
737 * og_collections uses nodeapi to trigger the automated duplication of
738 * pcpanel collections into actual og panels whenever a group of the
739 * appropriate type is created.
740 *
741 * // TODO consider switching to workflow_ng for this
742 *
743 */
744 function og_collections_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
745 switch ($op) {
746 case 'insert':
747 if ($collectionsetting = variable_get('og_collections_settings', FALSE)) {
748 $group_types = og_collections_group_types();
749 if (in_array($node->type, array_keys($group_types))) {
750 $multi = $collectionsetting == 1 ? FALSE : TRUE;
751 $defaultcfg = og_collections_load_collectioncfg(); // we'll need the default regardless of $multi
752 if ($multi) {
753 $collectioncfg = og_collections_load_collectioncfg($node->type);
754 foreach ($collectioncfg as $pcpid => $conf) {
755 if (!empty($conf['active'])) {
756 $toinsert[$pcpid] = !empty($conf['usedef']) ? $defaultcfg[$pcpid]['did'] : $conf['did']; // $conf will theoretically have the right $did either way, but this is the surefire way
757 }
758 }
759 }
760 else {
761 $type = 'default';
762 $collectioncfg = $defaultcfg;
763 foreach ($collectioncfg as $pcpid => $conf) {
764 if (!empty($conf['active'])) {
765 $toinsert[$pcpid] = $conf['did'];
766 }
767 }
768 }
769 }
770
771 if (!is_null($toinsert)) {
772 // now, attach the pcpanels to the nid via og_panels!
773 foreach ($toinsert as $pcpid => $did) {
774 $status = _og_collections_panelize_group($did, $node->nid, $collectioncfg[$pcpid], $pcpid);
775 if ($status == 'error') {
776 $message = t("Error occurred while adding the '!page_title'' pre-configured panel to the new '!groupname' group.", array('!page_title' => $collectioncfg[$pcpid]['page_title'], '!groupname' => $node->title));
777 }
778 elseif ($status == 'status') {
779 $message = t("The '!page_title'' pre-configured panel was successfully added to the new '!groupname' group.", array('!page_title' => $collectioncfg[$pcpid]['page_title'], '!groupname' => $node->title));
780 }
781 drupal_set_message($message, $status);
782 }
783 }
784 }
785 break;
786 }
787 }
788
789 /**
790 * Add a pcpanel to a newly-created group, per the parameters passed in.
791 *
792 * @param int $did
793 * the did of the display being exported
794 * @param int $nid
795 * the nid of the newly-added group node
796 * @param array $conf
797 * a configuration array specific to the pcpanel being added in this iteration (@see og_collections_nodeapi())
798 * @param int $pcpid
799 * the pcpid from which the panel is being instantiated
800 * @return string $status
801 * the type of message to report back on adding the pcpanel with - status or error
802 */
803 function _og_collections_panelize_group($did, $nid, $conf, $pcpid) {
804 $display = panels_load_display($did);
805 og_collections_export_display($display, $nid);
806 panels_save_display($display);
807 $fields = og_collections_panel_fields();
808 $conf['nid'] = $nid;
809 $conf['did'] = $display->did;
810 $conf['frompcpanel'] = $pcpid; // FIXME there needs to be a better, more comprehensive method of tracking this relationship. dids can go away, all too easily
811 if (!empty($conf['default_page'])) { // by default, og_panels removes any paths that were assigned to homepages. if this is gonna be a homepage, don't put in a path
812 $conf['path'] = '';
813 }
814 foreach ($fields as $field => $value) {
815 $f[] = $field;
816 $q[] = $value;
817 $v[] = $conf[$field];
818 }
819
820 db_query("INSERT INTO {og_panels} (". implode(', ', $f) .") VALUES (". implode(', ', $q) .")", $v);
821 $status = db_error();
822 return $status ? 'error' : 'status'; // returns string to set $status in drupal_set_message
823 }
824
825 // -------------------------------------------------------------------------
826 // Collections Helper functions, esp. save/load
827
828 /**
829 * Adds/removes fields from the collectioncfg table as needed.
830 *
831 * Plays nice with both mysql and pgsql. The ONLY time this function gets called is when a pcpanel is deleted, or a new one is created.
832 *
833 * @param string $fieldname
834 * @param string $op
835 * must be either 'add' or 'drop'
836 * @return mixed
837 * ONLY returns FALSE if a bad $op value has been passed. Otherwise, void
838 */
839 function og_collections_manage_db($fieldname, $op) {
840 if (strtolower($op) != ('add' || 'drop')) {
841 // bad $op
842 return FALSE;
843 }
844 switch ($GLOBALS['db_type']) {
845 case 'mysql':
846 case 'mysqli':
847 if ($op == 'add') {
848 db_query("ALTER TABLE {og_collections} ADD COLUMN $fieldname LONGTEXT NOT NULL");
849 }
850 elseif ($op == 'drop') {
851 db_query("ALTER TABLE {og_collections} DROP COLUMN $fieldname");
852 }
853 break;
854
855 case 'pgsql':
856 if ($op == 'add') {
857 db_add_column($ret, 'og_collections', $fieldname, 'TEXT');
858 }
859 elseif ($op == 'drop') {
860 db_query("ALTER TABLE {og_collections} DROP $fieldname");
861 }
862 break;
863 }
864 }
865
866
867 /**
868 * Update the database with the new id values for the exported pcpanel.
869 *
870 * @param obj $pcpanel
871 * A pcpanel object. Only needs $collectioncfg values to perform this operation; $display is unnecessary
872 */
873 function og_collections_pcpanel_handle_export($pcpanel) {
874 db_query("DELETE FROM {og_collections_pcpanel} WHERE pcpid = %d AND grouptype = '%s'", $pcpanel->pcpid, $pcpanel->grouptype); // in case of a residual display that avoided deletion
875 db_query("INSERT INTO {og_collections_pcpanel} (did, pcpid, grouptype) VALUES (%d, %d, '%s')", $pcpanel->did, $pcpanel->pcpid, $pcpanel->grouptype);
876 }
877
878 function og_collections_export_display(&$display, $nid = NULL) {
879 eval(panels_export_display($display));
880 panels_load_include('plugins');
881 panels_load_include('common');
882 $display->context = !is_null($nid) ? array('og_panels' => panels_context_create('group', $nid)) : array('og_panels' => panels_context_create_empty('group'));
883 $display->content_types = panels_common_get_allowed_types('og_panels', $display->context);
884 return $display; // just to be nice, return as well as by reference
885 }
886
887 /**
888 * Loads a pre-configured panel object.
889 *
890 * @param mixed $op
891 * Either a valid $did, or an array that should be defined as follows:
892 * array($grouptype, $pcpid), corresponding to values in the og_collections_pcpanel table.
893 * @param bool $loaddisplay = TRUE
894 * If TRUE, the $pcpanel object will also be loaded with corresponding $display information.
895 * @param string $type2 = NULL
896 * Use this parameter if the collectioncfg to be loaded is different from the collectioncfg
897 * corresopnding to param1. Primarily for exporting/reversion.
898 * @return mixed
899 * Returns an object if all goes well. If type/pcpid provided were no good, FALSE is returned.
900 * If a bad did is provided, returns NULL.
901 */
902 function og_collections_load_pcpanel($op, $loaddisplay = TRUE, $type2 = NULL) {
903 if (is_array($op) && (is_string($op[0]) && is_numeric($op[1]))) {
904 $result = db_query("SELECT * FROM {og_collections_pcpanel} WHERE grouptype = '%s' AND pcpid = %d", $op[0], $op[1]);
905 }
906 elseif (is_numeric($op)) {
907 $result = db_query("SELECT * FROM {og_collections_pcpanel} WHERE did = %d", $op);
908 }
909
910 if ($pcpanel = db_fetch_object($result)) {
911 if ($loaddisplay) {
912 $pcpanel->display = panels_load_display($pcpanel->did);
913 panels_load_include('plugins');
914 $pcpanel->display->context = array('og_panels' => panels_context_create_empty('group'));
915 panels_load_include('common');
916 $pcpanel->display->content_types = panels_common_get_allowed_types('og_panels', $pcpanel->display->context); // TODO this is a taxing operation - cache it in some way if possible. store content_types in collectioncfg?
917 }
918 $collectioncfg = og_collections_load_collectioncfg($type2 ? $type2 : $pcpanel->grouptype);
919 if (isset($collectioncfg[$pcpanel->pcpid])) {
920 foreach ($collectioncfg[$pcpanel->pcpid] as $key => $value) {
921 if ($key != 'did') {
922 $pcpanel->$key = $value;
923 }
924 }
925 }
926 return $pcpanel;
927 }
928 else {
929 return is_array($op) ? FALSE : NULL; // returns false if a type/pcpid was provided and got nothing; returns NULL if a did was provided and got nothing
930 }
931 }
932
933 /**
934 * Save a pcpanel object to the database.
935 *
936 * @param object $pcpanel
937 * @param bool $export
938 */
939 function og_collections_save_pcpanel($pcpanel, $export = FALSE) {
940 $collectioncfg = og_collections_load_collectioncfg($pcpanel->grouptype);
941 foreach ((array)$pcpanel as $key => $value) {
942 if (in_array($key, array('pcpid', 'display', 'content_types'))) {
943 continue;
944 }
945 $collectioncfg[$pcpanel->pcpid][$key] = $value;
946 }
947 if ($export) {
948 og_collections_pcpanel_handle_export($pcpanel);
949 }
950 og_collections_save_collectioncfg($pcpanel->grouptype, $collectioncfg, array($pcpanel->pcpid));
951 }
952
953 /**
954 * Load all collection configurations into an associative array, keyed by grouptype.
955 *
956 * Rows are, by default, cached into a static variable. Will only requery to pick up a new set of
957 * collectioncfgs if $refresh is TRUE
958 *
959 * @param bool $refresh
960 * @return mixed $rows
961 * returns FALSE if no results are found.
962 */
963 function og_collections_load_collectioncfgs($refresh = FALSE) {
964 static $rows;
965 if (!$rows || $refresh == TRUE) {
966 $result = db_query("SELECT * FROM {og_collections}");
967 if (count(db_fetch_array($result)) != 1) { // only occurs if no pre-configured panels have been created yet.
968 $result = db_query("SELECT * FROM {og_collections}"); // TODO ugh - have to double-query until D6 solves this problem w/schema
969 while ($row = db_fetch_array($result)) {
970 $grouptype = array_shift($row); // gets rid of grouptype, which is always first
971 foreach ($row as $pcpid => $vals) {
972 $arr[(int)substr($pcpid, 6)] = $vals ? unserialize($vals) : array();
973 }
974 uasort($arr, '_collectioncfg_sort'); // TODO consider trying to move this into the single load function somehow; could improve performance a bit
975 $rows[$grouptype] = $arr;
976 unset ($arr);
977 }
978 }
979 }
980 return $rows ? $rows : FALSE;
981 }
982
983
984 /**
985 * Specialized sort function. Sorts a given collectioncfg $conf array by the following criteria:
986 * 1. Default Page status
987 * 2. Active status (enabled/disabled in the current pre-configured panel)
988 * 3. Weight
989 */
990 function _collectioncfg_sort($a, $b) {
991 $default_page = $b['default_page'] - $a['default_page'];
992 if ($default_page) {
993 return $default_page;
994 }
995
996 $active = $b['active'] - $a['active'];
997 if ($active) {
998 return $active;
999 }
1000
1001 // if ($a['active']) return ($a['weight'] - $b['weight']);
1002 return ($a['weight'] - $b['weight']);
1003 }
1004
1005 /**
1006 * As with og_collections_load_collectioncfgs, uses static var to reduce db queries. only will refresh if explicitly instructed to do so,
1007 * and does so by passing that parameter on to the other load function
1008 */
1009 function og_collections_load_collectioncfg($type = 'default', $refresh = FALSE) {
1010 static $collectioncfgs;
1011 if (!$collectioncfgs || $refresh == TRUE) {
1012 $collectioncfgs = og_collections_load_collectioncfgs($refresh);
1013 }
1014 if ($collectioncfgs) {
1015 if (!isset($collectioncfgs[$type])) {
1016 $collectioncfgs[$type] = og_collections_new_collectioncfg($type, $collectioncfgs['default']);
1017 }
1018 return $collectioncfgs[$type];
1019 }
1020 }
1021
1022 function og_collections_new_collectioncfg($type, $collectioncfg) {
1023 db_query("INSERT INTO {og_collections} (grouptype) VALUES ('%s')", $type);
1024 $pcpids = array_keys($collectioncfg);
1025 return og_collections_save_collectioncfg($type, $collectioncfg, $pcpids);
1026 }
1027