--- module_builder.api.inc.orig 2008-01-02 03:49:33.000000000 +0100
+++ module_builder.api.inc 2008-05-06 03:37:59.000000000 +0200
@@ -11,29 +11,31 @@
*
* Components are things like 'node', 'menu', 'comment'. Basically,
* a component is a hook (however, like the node component, it is not limnited
- * to one Components are supplied with hook_module_builder. It returns an array
- * of arrays, which give information about the components. The components each
- * have a title, a machine(-readable name) a callback (which returns an FAPI array),
+ * to one Components are supplied with hook_module_builder. It returns an array
+ * of arrays, which give information about the components. The components each
+ * have a title, a machine(-readable name) a callback (which returns an FAPI array),
* and a submit function (which is set to a reasonable default).
*
* @return
* An array of all the components
*
- * @see module_builder_module_builder for the example components array
- * @see module_builder_edit_form for an example form
+ * @see module_builder_module_builder(), module_builder_general_form()
*/
function module_builder_get_components() {
include_once drupal_get_path('module', 'module_builder') .'/module_builder.components.inc';
$return = array();
foreach (module_implements('module_builder') as $module) {
- $function = $module .'_module_builder';
- $result = $function();
- foreach ($result as $item) {
- $return[$item['machine']] = $item + array(
+ $queryfunction = $module .'_module_builder';
+ $components = $queryfunction();
+ foreach ($components as $component) {
+ $return[$component['machine']] = $component + array(
'title' => '',
'machine' => '',
- 'callback' => '',
+ 'formconstructor' => '',
'default' => FALSE,
+ 'multiple' => FALSE,
+ 'multicreatenewtext' => '',
+ 'multidescription' => '',
'submit' => 'module_builder_default_submit',
'submit_button' => TRUE,
'export' => FALSE,
@@ -44,81 +46,210 @@
}
/**
- * Checks if a module id is valid
- *
+ * Checks if a module id is valid (wildcard loader called for module_builder/%mid urls)
+ *
* @param $mid
* The module ID to be loaded
* @return
* Either the module ID if found or FALSE if it wasn't found
*/
-function module_builder_load($mid) {
- $result = db_fetch_object(db_query("SELECT * FROM {module_builder_basic} WHERE mid = %d", $mid));
+function mid_load($mid) {
+ $result = db_fetch_object(db_query("SELECT data FROM {module_builder_data} WHERE mid = %d AND type = 'general'", $mid));
if ($result) {
- return $result;
+ $module = unserialize($result->data);
+ $module->mid = $mid;
+ return $module;
}
- else {
+ else
return FALSE;
- }
}
/**
- * Builder form
- *
+ * Builder form (this renders all the forms)
+ *
* @param $form_state
- * The form state (from form.inc). Passed into the callback.
- * @param $callback
- * The callback function
- * @param $mid
- * The module id
+ * The form state (from form.inc). Passed into the constructor.
+ * @param $module
+ * The module entry (loaded by mid_load)
* @param $type
- * The name of the component (menu, node, comment)
+ * The type of component form to show (menu, node, comment)
+ *
* @return
* An FAPI form array
*/
function module_builder_build(&$form_state, $module, $type) {
- $result = db_result(db_query("SELECT name FROM {module_builder_basic} WHERE mid = %d", $module->mid));
- drupal_set_title($result);
+ drupal_set_title(t('Project "!name"', array('!name' => $module->name)));
$components = module_builder_get_components();
$component = $components[$type];
- $result = unserialize(db_result(db_query("SELECT data FROM {module_builder_data} WHERE mid = %d AND type = '%s'", $module->mid, $type)));
- $values = ($result !== FALSE? $result : new stdClass);
- $form = $component['callback']($form_state, $values, $module);
+
+ // receive values from form state if already submitted or else from database
+ if (!empty($form_state['values']))
+ $values = (object) $form_state['values'];
+ else {
+ $result = unserialize(db_result(db_query("SELECT data FROM {module_builder_data} WHERE mid = %d AND type = '%s'", $module->mid, $type)));
+ $values = ($result !== FALSE) ? $result : new stdClass();
+ }
+
+ // get form from component's constructor callback
+ $form = $component['formconstructor']($form_state, $values, $module);
+ $form['mid'] = array(
+ '#type' => 'value',
+ '#value' => $module->mid);
+ $form['type'] = array(
+ '#type' => 'value',
+ '#value' => $type);
+
+ // form can have arbritrary number of items of same kind
+ if ($component['multiple'] == TRUE) {
+ $prototype = $form['item_prototype']['#value'];
+ $form['items'] = array(
+ '#type' => 'fieldset',
+ '#description' => $component['multidescription'],
+ '#prefix' => '
',
+ '#suffix' => '
',
+ );
+
+ // if add item button has been clicked, append entry with default values to item list
+ if ($form_state['values']['itemadded'])
+ $values->items[] = $form_state['values']['item_default'];
+ unset($form_state['values']['itemadded']);
+
+ $count = 0;
+ foreach ($values->items as $key => $item) {
+ // remove item marked for deletion from list
+ if (isset($form_state['post']['deleted']) && ((int) $key === (int) $form_state['post']['deleted'])) {
+ unset($values->items[$key]);
+ continue;
+ }
+ // set form item and populate with existing values
+ if (is_array($item)) {
+ $form['items'][$count] = $prototype;
+ foreach ($item as $field => $value) {
+ if ($field === "name" || $field === "title")
+ $form['items'][$count]['#title'] = $value;
+ $form['items'][$count][$field]['#default_value'] = $value;
+ }
+ // add a delete button for each item
+ $form['items'][$count]["delete_$count"] = array(
+ '#type' => 'submit',
+ '#name' => "delete_$count",
+ '#value' => t('Remove'),
+ // call store callback, then confirmation form
+ '#submit' => array($component['submit'], 'module_builder_itemdelete_confirm'),
+ );
+ $count++;
+ }
+ }
+ $form['new'] = array(
+ '#type' => 'submit',
+ '#value' => $component['multicreatenewtext'],
+ '#submit' => array('module_builder_additem_submit'),
+ '#prefix' => '
',
+ '#ahah' => array(
+ 'wrapper' => 'items-wrapper',
+ 'method' => 'append',
+ 'path' => 'module_builder/js',
+ ),
+ );
+
+ // set submit handler
+ $form['#submit'][] = 'module_builder_multiple_submit';
+ }
+ $form['#submit'][] = $component['submit'];
+
if ($component['submit_button']) {
$form['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
+ '#type' => 'submit',
+ '#value' => t('Save changes'),
);
}
- $form['#submit'][] = $component['submit'];
- $form['mid'] = array('#type' => 'value', '#value' => $module->mid);
- $form['type'] = array('#type' => 'value', '#value' => $type);
-
+
return $form;
}
/**
- * Module builder default submit
+ * Module builder submit handler for forms with multiple items (filters empty/default items)
+ */
+function module_builder_multiple_submit($form, &$form_state) {
+ $unset_items = array();
+ foreach ($form_state['values']['items'] as $key => $item) {
+ $contains_default_values = TRUE;
+ foreach ($item as $field => $value) {
+ if ($field === "delete_$key")
+ continue;
+ if ($value !== $form_state['values']['item_default'][$field])
+ $contains_default_values = FALSE;
+ }
+ if ($contains_default_values)
+ $unset_items[] = $key;
+ }
+ foreach ($unset_items as $key)
+ unset($form_state['values']['items'][$key]);
+ unset($form_state['values']['new']);
+}
+
+/**
+ * Module builder default submit (saves entered form data)
*/
function module_builder_default_submit($form, &$form_state) {
+ // create a clean copy of the values and store it in the db
$values = (object) $form_state['values'];
- unset($values->form_id, $values->submit, $values->op, $values->form_build_id, $values->form_token);
- $final = new stdClass;
- $final->mid = $values->mid;
- $final->type = $values->type;
+ unset($values->form_id, $values->submit, $values->op, $values->form_build_id, $values->form_token, $values->items['new'], $values->item_default, $values->item_prototype);
+ foreach ($values->items as $key => $item)
+ foreach ($item as $field => $value)
+ if ($field === "delete_$key")
+ unset($values->items[$key][$field]);
+ $storecomponent = new stdClass();
+ $storecomponent->mid = $values->mid;
+ $storecomponent->type = $values->type;
unset($values->mid, $values->type);
- $final->data = $values;
- if ((bool) db_result(db_query("SELECT mid FROM {module_builder_data} WHERE mid = %d AND type = '%s'", $final->mid, $final->type))) {
- drupal_write_record('module_builder_data', $final, array('mid', 'type'));
+ $storecomponent->data = $values;
+drupal_set_message('$storecomponent'. print_r($storecomponent, TRUE) .'
');
+
+ if ((bool) db_result(db_query("SELECT mid FROM {module_builder_data} WHERE mid = %d AND type = '%s'", $storecomponent->mid, $storecomponent->type))) {
+ $ret = drupal_write_record('module_builder_data', $storecomponent, array('mid', 'type'));
}
else {
- drupal_write_record('module_builder_data', $final);
+ $ret = drupal_write_record('module_builder_data', $storecomponent);
}
+// drupal_set_message('$ret= '.print_r($ret, TRUE).'
');
+// $form_state['rebuild'] = TRUE;
+}
+
+function module_builder_additem_submit($form, &$form_state) {
+// drupal_set_message('module_builder_additem_submit');
+ $form_state['values']['itemadded'] = TRUE;
$form_state['rebuild'] = TRUE;
}
+
+function module_builder_itemdelete_confirm($form, &$form_state) {
+ $key = $form_state['clicked_button']['#parents'][1];
+ $type = $form_state['values']['type'];
+ $mid = $form_state['values']['mid'];
+ $name = (!empty($form_state['values']['items'][$key]['title'])) ?
+ $form_state['values']['items'][$key]['title'] : ((!empty($form_state['values']['items'][$key]['name'])) ?
+ $form_state['values']['items'][$key]['name'] : t('(unnamed)'));
+ $output = drupal_get_form('module_builder_itemdelete_confirm_form', $type, $mid, $key, $name);
+ print theme('page', $output);
+ exit;
+}
+
+function module_builder_itemdelete_confirm_form(&$form_state, $type, $mid, $key, $name) {
+ $item_deleted = array(
+ 'deleted' => array(
+ '#type' => 'hidden',
+ '#value' => $key,
+ ),
+ );
+ $form = confirm_form($item_deleted, t('Do you really want to delete the !type "!name"?',
+ array('!type' => $type, '!name' => $name)), "admin/build/module_builder/edit/$mid/$type");
+ return $form;
+}
+
/**
* The JavaScript callback.
- *
+ *
* Uses magic too complex to be explained here.
*/
function module_builder_js($param = '') {
@@ -126,38 +257,48 @@
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, &$form_state);
- // #parameters has $form_id, $form_state and then whatever was passed to
- // drupal_get_form.
+
+ // #parameters has $form_id, $form_state and then whatever
+ // was passed to drupal_get_form.
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
+
// This will set up $form_state['clicked_button'] and
// $form_state['storage']['mlid'].
drupal_process_form($form_id, $form, $form_state);
+
// Recreate and re-cache the form.
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
- // Pick up the parents of the pressed button.
- $array_parents = $form_state['clicked_button']['#array_parents'];
- // The last parent is the button itself, we need the wrapper instead.
- array_pop($array_parents);
- while ($array_parents) {
- $parent = array_shift($array_parents);
- $form = $form[$parent];
- }
- // Remove the button.
- unset($form['parent_submit']);
- // Render messages and selects.
- $output = theme('status_messages') . drupal_render($form);
+
+ // get the added form item and add the js pre_render callback
+ $item = $form['items'][end(element_children($form['items']))];
+ $item['#pre_render'] = (!empty($form['#pre_render'])) ? $form['#pre_render'] : '';
+
+ // render the item and its javascript and send it to the browser via JSON
+ $output = drupal_render($item) . drupal_get_js('appended');
drupal_json(array('status' => TRUE, 'data' => $output));
}
-function module_builder_add_js($name, $a2, $a3, $a4) {
+function module_builder_add_js() {
+// drupal_set_message('module_builder_add_js');
drupal_add_js(drupal_get_path('module', 'module_builder') .'/module_builder.js');
- switch ($name) {
- case 'copy':
- drupal_add_js(array('moduleBuilderCopy' => array(array('type' => $a2, 'from' => $a3, 'to' => $a4))), 'setting');
- }
+}
+
+function module_builder_add_item_js($name, $type, $from, $to, $scope = 'header') {
+// drupal_set_message('module_builder_add_item_js');
+ $js_data = array(
+ $name => array(
+ array(
+ 'type' => $type,
+ 'from' => $from,
+ 'to' => $to,
+ ),
+ ),
+ );
+// drupal_set_message(''.print_r($js_data, TRUE).'
');
+ drupal_add_js($js_data, 'setting', $scope);
}
function module_builder_add_hook($hook, $module) {
@@ -170,35 +311,52 @@
}
function module_builder_export_callback($module, $file) {
- $edit = unserialize(db_result(db_query("SELECT data FROM {module_builder_data} WHERE type = '%s' AND mid = %d", 'edit', $module->mid)));
- $module = (object) ((array) $module + (array) $edit + array('description' => '', 'machine' => ''));
- if ($file == 'info') {
- header('Content-disposition: attachment');
- print _module_builder_export_info($module);
- exit();
- }
- elseif ($file == 'module') {
- header('Content-disposition: attachment');
- print _module_builder_export_module($module);
- exit();
- }
- elseif ($file == 'tar') {
-
- }
- else {
- drupal_not_found();
- }
+ switch ($file) {
+ case 'info':
+ drupal_set_header('Content-type: text/plain');
+ drupal_set_header('Content-disposition: attachment; filename="'. $module->machine .'.info"');
+ print _module_builder_export_info($module);
+ exit();
+ case 'module':
+ drupal_set_header('Content-type: text/plain');
+ drupal_set_header('Content-disposition: attachment; filename="'. $module->machine .'.module"');
+ print _module_builder_export_module($module);
+ exit();
+ case 'tar':
+ include_once(drupal_get_path('module', 'module_builder') .'/archive_tar/archive_tar.php');
+ $tarname = file_directory_path() .'/'. $module->machine .'.tar.gz';
+ $tarchive = new Archive_Tar($tarname, 'gz');
+ if ($tarchive->addString($module->machine .'/'. $module->machine .'.info', _module_builder_export_info($module)) &&
+ $tarchive->addString($module->machine .'/'. $module->machine .'.module', _module_builder_export_module($module))) {
+ drupal_set_header('Content-type: application/x-gzip');
+ drupal_set_header('Content-disposition: attachment; filename="'. $module->machine .'.tar.gz"');
+ print file_get_contents($tarname);
+ unlink($tarname);
+ exit();
+ }
+ else {
+ drupal_set_message('Creating GZ compressed TAR archive failed.', 'error');
+ drupal_not_found();
+ }
+ default:
+ drupal_not_found();
+ }
}
function _module_builder_export_info($module) {
- $output = '';
+ $output = '; $Id$'."\n";
$info = array();
$info['name'] = '"'. $module->name .'"';
$info['description'] = '"'. $module->description .'"';
+ if (!empty($module->package)) $info['package'] = $module->package;
$info['core'] = '6.x';
foreach ($info as $key => $value) {
$output .= $key .' = '. $value ."\n";
}
+ $dependencies = (!empty($module->dependencies)) ? explode(' ', $module->dependencies) : '';
+ while (!empty($dependencies)) {
+ $output .= "dependencies[] = ". array_pop($dependencies) ."\n";
+ }
return $output;
}
--- module_builder.components.inc.orig 2008-01-02 03:49:33.000000000 +0100
+++ module_builder.components.inc 2008-05-06 02:50:19.000000000 +0200
@@ -4,194 +4,209 @@
function module_builder_module_builder() {
return array(
array(
- 'title' => t('Edit'),
- 'machine' => 'edit',
- 'callback' => 'module_builder_edit_form',
+ 'title' => t('General'),
+ 'machine' => 'general',
+ 'formconstructor' => 'module_builder_general_form',
'default' => TRUE,
- 'submit' => 'module_builder_edit_form_submit',
+ 'submit' => 'module_builder_general_form_submit',
),
array(
- 'title' => t('Menu'),
+ 'title' => t('Menus'),
'machine' => 'menu',
- 'callback' => 'module_builder_menu_form',
- // 'export' => 'module_builder_menu_export',
+ 'formconstructor' => 'module_builder_menu_form',
+ 'multiple' => TRUE,
+ 'multicreatenewtext' => t('Add menu entry'),
+ 'multidescription' => t('Add here any menu items the module should define.'),
),
array(
- 'title' => t('Node'),
+ 'title' => t('Node types'),
'machine' => 'node',
- 'callback' => 'module_builder_node_form',
+ 'formconstructor' => 'module_builder_node_form',
+ 'multiple' => TRUE,
+ 'multicreatenewtext' => t('Add content type'),
+ 'multidescription' => t('Node content types the module provides can be defined here.'),
'export' => 'module_builder_node_export',
),
array(
- 'title' => t('Delete'),
- 'machine' => 'delete',
- 'callback' => 'module_builder_delete_form',
- 'submit' => 'module_builder_delete_form_submit',
- 'submit_button' => FALSE,
+ 'title' => t('DB schema'),
+ 'machine' => 'schema',
+ 'formconstructor' => 'module_builder_schema_form',
+ ),
+ array(
+ 'title' => t('Functions'),
+ 'machine' => 'function',
+ 'formconstructor' => 'module_builder_function_form',
+ 'multiple' => TRUE,
+ 'multicreatenewtext' => t('Add function definition'),
+ 'multidescription' => t('The functions which provide the module\'s ..well ... functionality!'),
),
array(
- 'title' => t('Export'),
+ 'title' => t('Export module'),
'machine' => 'export',
- 'callback' => 'module_builder_export_form',
+ 'formconstructor' => 'module_builder_export_form',
+ 'submit_button' => FALSE,
+ ),
+ array(
+ 'title' => t('Delete project'),
+ 'machine' => 'delete',
+ 'formconstructor' => 'module_builder_delete_form',
+ 'submit' => 'module_builder_delete_form_submit',
'submit_button' => FALSE,
),
);
}
/**
- * The basic edit form
+ * The general settings form
*/
-function module_builder_edit_form(&$form_state, $values, $mid) {
- $form = array();
- $form['name'] = array(
- '#type' => 'textfield',
- '#title' => t('Name'),
- '#description' => t('The external name of the module'),
- '#size' => 40,
- '#maxlength' => 255,
- '#default_value' => isset($values->name)? $values->name : '',
- );
- $form['machine'] = array(
- '#type' => 'textfield',
- '#title' => t('Machine-readable name'),
- '#description' => t('Alpha-numeric characters and underscores only'),
- '#size' => 40,
- '#maxlength' => 255,
- '#default_value' => isset($values->machine)? $values->machine : '',
- );
- $form['description'] = array(
- '#type' => 'textfield',
- '#title' => t('Description'),
- '#description' => t('The description of the module'),
- '#size' => 40,
- '#maxlength' => 255,
- '#default_value' => isset($values->description)? $values->description : '',
+function module_builder_general_form(&$form_state, $values, $module) {
+ $form = array(
+ 'name' => array(
+ '#type' => 'textfield',
+ '#title' => t('Name'),
+ '#description' => t('The human-readable name of the module'),
+ '#size' => 40,
+ '#maxlength' => 255,
+ '#default_value' => isset($values->name)? $values->name : '',
+ ),
+ 'machine' => array(
+ '#type' => 'textfield',
+ '#title' => t('Machine-readable name'),
+ '#description' => t('Alpha-numeric characters and underscores only'),
+ '#size' => 40,
+ '#maxlength' => 255,
+ '#default_value' => isset($values->machine)? $values->machine : '',
+ ),
+ 'description' => array(
+ '#type' => 'textfield',
+ '#title' => t('Description'),
+ '#description' => t('The description of the module'),
+ '#size' => 40,
+ '#maxlength' => 255,
+ '#default_value' => isset($values->description)? $values->description : '',
+ ),
+ 'package' => array(
+ '#type' => 'textfield',
+ '#title' => t('Package'),
+ '#description' => t('Optional category name (f.e. CCK, Development..)'),
+ '#size' => 40,
+ '#maxlength' => 255,
+ '#default_value' => isset($values->package)? $values->package : '',
+ ),
+ 'dependencies' => array(
+ '#type' => 'textfield',
+ '#title' => t('Dependencies'),
+ '#description' => t('Machine-readable names of needed modules (space seperated)'),
+ '#size' => 40,
+ '#maxlength' => 255,
+ '#default_value' => isset($values->dependencies)? $values->dependencies : '',
+ ),
+ '#pre_render' => array('module_builder_general_js_magic'),
);
- module_builder_add_js('copy', 'makeUnderscore', '#edit-name', '#edit-machine');
return $form;
}
+
+function module_builder_general_js_magic($form, $foo) {
+// drupal_set_message('module_builder_general_js_magic');
+ module_builder_add_js();
+ module_builder_add_item_js('moduleBuilderCopy', 'makeUnderscore', '#edit-name', '#edit-machine');
+ return $form;
+}
+
/**
- * Submit callback for the edit form
+ * Submit callback for general settings form
+ * (updates the project table after saving form values)
*/
-function module_builder_edit_form_submit($form, &$form_state) {
+function module_builder_general_form_submit($form, &$form_state) {
module_builder_default_submit($form, $form_state);
- db_query("UPDATE {module_builder_basic} SET name = '%s' WHERE mid = %d", $form_state['values']['name'], $form_state['values']['mid']);
+ db_query("UPDATE {module_builder_projects} SET name = '%s' WHERE mid = '%d'", $form_state['values']['name'], $form_state['values']['mid']);
}
function module_builder_node_form(&$form_state, $values) {
- if (isset($form_state['storage']['node_type_count']) && $form_state['storage']['node_type_count'] > 1 && isset($form_state['storage']['types']) && !empty($form_state['storage']['types'])) {
- $node_type_count = $form_state['storage']['node_type_count'];
- $types = $form_state['storage']['types'];
- }
- elseif (isset($values->types)) {
- $node_type_count = count($values->types);
- $types = $values->types;
- }
- else {
- $node_type_count = 1;
- }
- $default_type = array(
+// drupal_set_message('module_builder_node_form');
+ $item_default = array(
'name' => '',
'machine' => '',
'description' => '',
- 'locked' => FALSE,
+ 'locked' => 0,
);
-
- $form = array(
- '#cache' => TRUE,
- '#tree' => TRUE,
- );
- $form['integration'] = array(
- '#type' => 'checkbox',
- '#title' => t('Integrate with the node module'),
- '#description' => t('If your module needs to interact with node types other than the ones it defines, check this'),
- '#default_value' => isset($values->integration)? (bool) $values->integration : FALSE,
- );
- $form['types'] = array(
+ $prototype = array(
'#type' => 'fieldset',
- '#title' => t('Node types'),
- '#description' => t('If the module defines any node types, fill out these values.'),
- '#collapsible' => FALSE,
- '#prefix' => '',
- '#suffix' => '
',
- );
- for ($delta = 0; $delta < $node_type_count; $delta++) {
- if (!isset($types[$delta])) {
- $type = $default_type;
- }
- else {
- $type = $types[$delta] + $default_type;
- }
- $form['types'][$delta] = array(
- '#type' => 'fieldset',
- '#title' => t('Node type'), // As an added bonus, change it to (!empty($type['name'])? $type['name'] : t('Node type'))
- '#collapsible' => TRUE,
- );
- $form['types'][$delta]['name'] = array(
+ '#collapsible' => TRUE,
+ 'name' => array(
'#type' => 'textfield',
'#title' => t('Name'),
- '#description' => t('The external (not machine-readable) name of the content type.'),
- '#default_value' => $type['name'],
- );
- $form['types'][$delta]['machine'] = array(
+ '#description' => t('The human-readable name of the content type.'),
+ ),
+ 'machine' => array(
'#type' => 'textfield',
'#title' => t('Machine-readable name'),
'#description' => t('The machine-readable name of the content type.'),
- '#default_value' => $type['machine'],
- );
- $form['types'][$delta]['description'] = array(
+ ),
+ 'description' => array(
'#type' => 'textfield',
'#title' => t('Description'),
'#description' => t('The description of the content type'),
- '#default_value' => $type['description'],
- );
- $form['types'][$delta]['locked'] = array(
+ ),
+ 'locked' => array(
'#type' => 'checkbox',
'#title' => t('Locked'),
- '#description' => t('If the content type is locked, the user can\'t modify any properties from the interface'),
- '#default_value' => $type['locked'],
- );
- }
- $form['types']['new'] = array(
- '#type' => 'submit',
- '#value' => t('New node type'),
- '#submit' => array('_module_builder_node_submit'),
- '#ahah' => array(
- 'wrapper' => 'node-types-wrapper',
- 'path' => 'module_builder/js',
+ '#description' => t('If the content type is locked, the user can not modify any of its properties.'),
),
);
-
- $form['#pre_render'][] = 'module_builder_node_after_build';
+ $form = array(
+ '#cache' => FALSE,
+ '#tree' => TRUE,
+ 'item_default' => array(
+ '#type' => 'value',
+ '#value' => $item_default,
+ ),
+ 'item_prototype' => array(
+ '#type' => 'value',
+ '#value' => $prototype,
+ ),
+ 'nodeapiintegration' => array(
+ '#type' => 'checkbox',
+ '#title' => t('Integrate with the node module (adds a nodeapi hook)'),
+ '#description' => t('Check this if your module needs to interact with node types other than its own.'),
+ '#default_value' => (isset($values->nodeapiintegration)) ? $values->nodeapiintegration : 0,
+ '#suffix' => '
',
+ ),
+ '#pre_render' => array('module_builder_node_js_magic'),
+ );
return $form;
}
-function module_builder_node_after_build($form) {
- foreach (element_children($form['types']) as $key) {
- if (is_numeric($key)) {
- module_builder_add_js('copy', 'makeUnderscore', '#'. $form['types'][$key]['name']['#id'], '#'. $form['types'][$key]['machine']['#id']);
+// can be passed the whole form or just the items part
+function module_builder_node_js_magic($form, $foo) {
+ if (isset($form['items'])) {
+ $items = $form['items'];
+ foreach (element_children($items) as $key) {
+ if (is_numeric($key)) {
+// drupal_set_message('id='.$items[$key]['name']['#id']);
+ module_builder_add_js();
+ module_builder_add_item_js('moduleBuilderCopy', 'makeUnderscore', '#'. $items[$key]['name']['#id'], '#'. $items[$key]['machine']['#id']);
+ }
}
}
+ else {
+ // handle single item that gets appended into page
+ $item = $form;
+ module_builder_add_item_js('moduleBuilderCopy', 'makeUnderscore', '#'. $item['name']['#id'], '#'. $item['machine']['#id'], 'appended');
+ }
return $form;
}
-function _module_builder_node_submit($form, &$form_state) {
- $form_state['storage']['node_type_count'] = count(element_children($form['types']));
- $types = $form_state['values']['types'];
- unset($types['new']);
- $form_state['storage']['types'] = $types;
-}
-
function module_builder_node_export($values, $module) {
$output = "";
- if (isset($values->integration) && $values->integration == 1) {
+ if (isset($values->nodeapiintegration) && $values->nodeapiintegration == 1) {
$output .= module_builder_add_hook('nodeapi', $module);
}
if (isset($values->types) && count($values->types)) {
$output .= "/**\n * Implementation of hook_node_info().\n */\nfunction ". $module->machine ."_node_info() {\n return array(\n";
foreach ($values->types as $type) {
if (!empty($type['machine']) && $type['machine'] != "N") {
- $output .= " '". $type['machine'] ."' => array(,\n";
+ $output .= " '". $type['machine'] ."' => array(\n";
$output .= " 'name' => t('". $type['name'] ."'),\n";
$output .= " 'module' => '". $module->machine ."',\n";
$output .= " 'description' => t('". $type['description'] ."'),\n";
@@ -206,64 +221,74 @@
return $output;
}
+function module_builder_function_form(&$form_state, $values) {
+ $item_default = array(
+ 'name' => '',
+ 'header' => '',
+ 'body' => '',
+ );
+ $prototype = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ 'name' => array(
+ '#type' => 'textfield',
+ '#title' => t('Function name'),
+ '#description' => t('(Functions called externally should be prefixed with the module\'s name.)'),
+ ),
+ 'header' => array(
+ '#type' => 'textarea',
+ '#title' => t('Header comment'),
+ '#description' => t('Can be used to describe the purpose of the function and it\'s parameters and return value.'),
+ '#rows' => 2,
+ ),
+ 'body' => array(
+ '#type' => 'textarea',
+ '#title' => t('Function Body'),
+ '#description' => t('Code goes here.'),
+ '#rows' => 10,
+ ),
+ );
+ $form = array(
+ '#cache' => FALSE,
+ '#tree' => TRUE,
+ 'item_default' => array(
+ '#type' => 'value',
+ '#value' => $item_default,
+ ),
+ 'item_prototype' => array(
+ '#type' => 'value',
+ '#value' => $prototype,
+ ),
+ );
+ return $form;
+}
+function module_builder_schema_form(&$form_state, $values) {
+ $form = array();
+ return $form;
+}
function module_builder_menu_form(&$form_state, $values) {
- if (isset($form_state['storage']['menu_item_count']) && $form_state['storage']['menu_item_count'] > 1 && isset($form_state['storage']['items']) && !empty($form_state['storage']['items'])) {
- $menu_item_count = $form_state['storage']['menu_item_count'];
- $items = $form_state['storage']['items'];
- }
- elseif (isset($values->items)) {
- $menu_item_count = count($values->items);
- $items = $values->items;
- }
- else {
- $menu_item_count = 1;
- }
- $default_item = array(
+ $item_default = array(
'title' => '',
'path' => '',
'type' => 'Normal',
'callback' => '',
);
-
- $form = array(
- '#cache' => FALSE,
- '#tree' => TRUE,
- );
- $form['items'] = array(
+ $prototype = array(
'#type' => 'fieldset',
- '#title' => t('Menu items'),
- '#description' => t('If the module defines any menu items, fill out these values.'),
- '#collapsible' => FALSE,
- '#prefix' => '',
- );
- for ($delta = 0; $delta < $menu_item_count; $delta++) {
- if (!isset($items[$delta])) {
- $item = $default_item;
- }
- else {
- $item = $items[$delta] + $default_item;
- }
- $form['items'][$delta] = array(
- '#type' => 'fieldset',
- '#title' => t('Menu item'), // As an added bonus, change it to (!empty($item['title'])? $item['title'] : t('Menu item'))
- '#collapsible' => TRUE,
- );
- $form['items'][$delta]['title'] = array(
+ '#collapsible' => TRUE,
+ 'title' => array(
'#type' => 'textfield',
'#title' => t('Title'),
'#description' => t('The title of the menu item'),
- '#default_value' => $item['title'],
- );
- $form['items'][$delta]['path'] = array(
+ ),
+ 'path' => array(
'#type' => 'textfield',
'#title' => t('Path'),
'#description' => t('The path of the menu item, such as admin/build/modules'),
- '#default_value' => $item['path'],
- );
- $form['items'][$delta]['type'] = array(
+ ),
+ 'type' => array(
'#type' => 'select',
'#title' => t('Type'),
'#multiple' => FALSE,
@@ -273,59 +298,74 @@
'Default tab',
'Callback',
'Suggested item',
- '#default_value' => $item['type'],
)),
- );
- $form['items'][$delta]['callback'] = array(
+ ),
+ 'callback' => array(
'#type' => 'textfield',
'#title' => t('Callback'),
'#description' => t('The title you enter here appears on the page.'),
'#size' => 40,
'#maxlength' => 255,
- '#default_value' => $item['callback'],
- );
-
- }
- $form['items']['new'] = array(
- '#type' => 'submit',
- '#value' => t('New menu item'),
- '#submit' => array('_module_builder_menu_submit'),
- '#ahah' => array(
- 'wrapper' => 'menu-items-wrapper',
- 'path' => 'module_builder/js',
+ )
+ );
+ $form = array(
+ '#cache' => FALSE,
+ '#tree' => TRUE,
+ 'item_default' => array(
+ '#type' => 'value',
+ '#value' => $item_default,
+ ),
+ 'item_prototype' => array(
+ '#type' => 'value',
+ '#value' => $prototype,
),
);
return $form;
}
-function _module_builder_menu_submit($form, &$form_state) {
- $form_state['storage']['menu_item_count'] = count(element_children($form['items']));
- $items = $form_state['values']['items'];
- unset($items['new']);
- $form_state['storage']['items'] = $items;
-}
-
-function module_builder_export_form() {
- $form = array();
- if (!module_builder_archive_tar_enabled()) {
- $form['note'] = array(
+function module_builder_export_form(&$form_state, $values) {
+ $form = array(
+ 'note' => array(
'#type' => 'item',
- '#value' => t('Several file downloads have started. Please put them all in a single directory, %dir.', array('%dir' => unserialize(db_result(db_query("SELECT data FROM {module_builder_data} WHERE mid = '%d' AND type = '%s'", menu_get_object('module_builder', 4)->mid, 'edit')))->machine)),
- );
- $form['info_file'] = array(
- '#value' => '',
- '#prefix' => '',
- );
- $form['module_file'] = array(
- '#value' => '',
- '#suffix' => '
',
- );
+ '#value' => t('The module skeleton has been generated. Please download the files below and put them in a single directory %dir.', array('%dir' => menu_get_object('mid', 4)->machine)),
+ ),
+ 'info_file' => array(
+ '#value' => '.info file',
+ '#suffix' => '
',
+ ),
+ 'module_file' => array(
+ '#value' => '.module file',
+ ),
+ );
+ if (!module_builder_archive_tar_enabled()) {
$form['enhanced'] = array(
'#type' => 'item',
'#value' => t('Note: For enhanced export capabilities, please download the archive tar package and put it in the module_builder directory.', array('!archive_tar' => 'http://dmitrizone.com/files/archive_tar.tgz')),
);
}
else {
+ $form['tar_note'] = array(
+ '#type' => 'item',
+ '#value' => t('Click below to download a GZipped TAR archive of the module directory.'),
+ );
+ $form['tar_file'] = array(
+ '#value' => '.tar.gz file',
+ );
}
return $form;
}
+
+function module_builder_delete_form(&$form_state, $values, $module) {
+ return confirm_form(
+ array('#modulename' => $module->name),
+ t('Are you sure you want to delete the module "!module"?', array('!module' => $module->name)),
+ 'admin/build/module_builder/edit/'. $module->mid
+ );
+}
+
+function module_builder_delete_form_submit($form, &$form_state) {
+ if (db_query('DELETE FROM {module_builder_data} WHERE mid = %d', $form_state['values']['mid']) &&
+ db_query('DELETE FROM {module_builder_projects} WHERE mid = %d', $form_state['values']['mid']))
+ drupal_set_message(t('The project "!name" has been deleted.', array('!name' => $form['#modulename'])));
+ $form_state['redirect'] = 'admin/build/module_builder';
+}
--- module_builder.info.orig 2008-01-03 13:05:02.000000000 +0100
+++ module_builder.info 2008-05-01 17:22:42.000000000 +0200
@@ -1,7 +1,9 @@
; $Id: module_builder.info,v 1.2.4.2 2008/01/02 02:49:33 dmitrig01 Exp $
name = Module Builder
description = Assists in the process of building modules
+package = Development
core = 6.x
+
; Information added by drupal.org packaging script on 2008-01-03
version = "6.x-1.x-dev"
core = "6.x"
--- module_builder.install.orig 2008-01-02 03:49:33.000000000 +0100
+++ module_builder.install 2008-05-06 03:50:52.000000000 +0200
@@ -2,60 +2,45 @@
// $Id: module_builder.install,v 1.1.2.2 2008/01/02 02:49:33 dmitrig01 Exp $
/**
- * Implementation of hook_install().
+ * Implementation of hook_schema().
*/
-function module_builder_install() {
- // Create tables.
- drupal_install_schema('module_builder');
-
- drupal_set_message('Module builder installed');
-}
-
-/**
- * Implementation of hook_uninstall().
- */
-function module_builder_uninstall() {
- // Remove tables.
- drupal_uninstall_schema('module_builder');
-}
-
function module_builder_schema() {
- $schema['module_builder_basic'] = array(
- 'description' => t('Stores data having to do with modules.'),
+ $schema['module_builder_projects'] = array(
+ 'description' => t('Stores ids and names of modules.'),
'fields' => array(
'mid' => array(
'type' => 'serial',
'description' => t('The id of the module.'),
),
'name' => array(
- 'type' => 'varchar',
- 'length' => '255',
+ 'type' => 'varchar',
+ 'length' => '255',
'default' => '',
- 'not null' => TRUE,
+ 'not null' => TRUE,
'description' => t('The name of the module.'),
),
),
'primary key' => array('mid'),
);
$schema['module_builder_data'] = array(
- 'description' => t('Stores data having to do with modules built with the module builder.'),
+ 'description' => t('Stores each component of modules built with module_builder as data blob.'),
'fields' => array(
'mid' => array(
- 'type' => 'int',
- 'unsigned' => TRUE,
- 'not null' => TRUE,
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
'default' => 0,
'description' => t('The module this data is attached to.'),
),
'type' => array(
- 'type' => 'varchar',
- 'length' => '64',
+ 'type' => 'varchar',
+ 'length' => '64',
'default' => '',
- 'not null' => TRUE,
+ 'not null' => TRUE,
'description' => t('The type, such as "node" or "comment" or "menu".'),
),
'data' => array(
- 'type' => 'blob',
+ 'type' => 'blob',
'description' => t('The data'),
'serialize' => TRUE
),
@@ -63,4 +48,30 @@
'indexes' => array('data' => array('mid', 'type')),
);
return $schema;
-}
\ No newline at end of file
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function module_builder_install() {
+ // Create tables.
+ drupal_install_schema('module_builder');
+
+ drupal_set_message('Module builder installed');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function module_builder_uninstall() {
+ // Remove tables.
+ drupal_uninstall_schema('module_builder');
+}
+
+function module_builder_update_1() {
+ $ret = array();
+ $ret[] = update_sql("RENAME TABLE {module_builder_basic} TO {module_builder_projects}");
+ $ret[] = update_sql("UPDATE {module_builder_data} SET type = 'general' WHERE type = 'edit'");
+ $ret[] = update_sql("UPDATE {module_builder_data} SET type = 'menu' WHERE type = 'menu'");
+ return $ret;
+}
--- module_builder.module.orig 2008-01-02 03:49:33.000000000 +0100
+++ module_builder.module 2008-05-06 00:08:41.000000000 +0200
@@ -14,35 +14,36 @@
'page callback' => 'module_builder_home',
'access arguments' => array('build modules'),
'file' => 'module_builder.pages.inc',
- 'description' => 'Make and customize new modules without writing code',
+ 'description' => 'Create Drupal modules through a supportive interface.',
);
- $modules = module_builder_get_components();
+ $components = module_builder_get_components();
$default = array();
$count = 0;
- foreach ($modules as $builder) {
- $items['admin/build/module_builder/edit/%module_builder/'. $builder['machine']] = array(
- 'title' => $builder['title'],
+ foreach ($components as $component) {
+ $items['admin/build/module_builder/edit/%mid/'. $component['machine']] = array(
+ 'title' => $component['title'],
'page callback' => 'drupal_get_form',
'page arguments' => array('module_builder_build', 4, 5),
- 'type' => $builder['default'] == TRUE ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+ 'access arguments' => array('build modules'),
+ 'type' => $component['default'] == TRUE ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'file' => 'module_builder.pages.inc',
- 'description' => 'Make and customize new modules',
+ 'description' => 'Create Drupal modules',
'weight' => $count,
);
$count++;
- if ($builder['default'] == TRUE) {
- $default = $builder;
+ if ($component['default'] == TRUE) {
+ $default = $component;
}
}
- $items['admin/build/module_builder/edit/%module_builder'] = array(
- 'title' => $default['title'],
+ $items['admin/build/module_builder/edit/%mid'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('module_builder_build', 4, $default['machine']),
+ 'access arguments' => array('build modules'),
'type' => MENU_CALLBACK,
'file' => 'module_builder.pages.inc',
);
$items['admin/build/module_builder/new'] = array(
- 'title' => 'Module Builder',
+ 'title' => t('Creating a new module..'),
'page callback' => 'drupal_get_form',
'page arguments' => array('module_builder_build_new'),
'access arguments' => array('build modules'),
@@ -50,14 +51,12 @@
'file' => 'module_builder.pages.inc',
);
$items['module_builder/js'] = array(
- 'title' => 'Module Builder',
'page callback' => 'module_builder_js',
'access arguments' => array('build modules'),
'type' => MENU_CALLBACK,
'file' => 'module_builder.api.inc',
);
- $items['module_builder/export/%module_builder/%'] = array(
- 'title' => 'Module Builder',
+ $items['module_builder/export/%mid/%'] = array(
'page callback' => 'module_builder_export_callback',
'page arguments' => array(2, 3),
'access arguments' => array('build modules'),
--- module_builder.pages.inc.orig 2008-01-02 03:49:33.000000000 +0100
+++ module_builder.pages.inc 2008-05-06 02:39:23.000000000 +0200
@@ -4,22 +4,16 @@
include_once drupal_get_path('module', 'module_builder') .'/module_builder.components.inc';
/**
- * Menu callback; home page
+ * Menu callback; entry page
*/
function module_builder_home() {
$items = array();
- $new = l('New module!', 'admin/build/module_builder/new', array('html' => TRUE));
- $query = db_query("SELECT name, mid FROM {module_builder_basic}");
+ $query = db_query("SELECT name, mid FROM {module_builder_projects}");
while ($result = db_fetch_array($query)) {
$items[] = l($result['name'], 'admin/build/module_builder/edit/'. $result['mid']);
}
- if (!count($items)) {
- $output = '
'. $new .'
';
- }
- else {
- $items[] = ''. $new .'';
- $output = theme('item_list', $items);
- }
+ $output = (!empty($items)) ? theme('item_list', $items, 'Existing module development projects:') : 'No existing projects found.';
+ $output .= '
'. l(t('Create a new module!'), 'admin/build/module_builder/new');
return $output;
}
@@ -28,15 +22,15 @@
*/
function module_builder_build_new() {
$form = array();
- $form['title'] = array(
+ $form['name'] = array(
'#type' => 'textfield',
- '#title' => t('Title'),
- '#description' => t('The title of the module (not the machine-readable name).'),
+ '#title' => t('Project name'),
+ '#description' => t('The title of the module to be created (not the machine-readable name).'),
'#size' => 40,
'#maxlength' => 255,
);
$form['submit'] = array(
- '#type' => 'submit',
+ '#type' => 'submit',
'#value' => t('Submit'),
);
@@ -44,23 +38,16 @@
}
function module_builder_build_new_submit($form, &$form_state) {
- $save = (object) array('name' => $form_state['values']['title']);
- drupal_write_record('module_builder_basic', $save);
- $prepared_form_values = array('values' => array('mid' => $save->mid, 'type' => 'edit', 'name' => $save->name));
- module_builder_default_submit(array(), $prepared_form_values);
- $form_state['redirect'] = 'admin/build/module_builder/edit/'. $save->mid;
-}
+ $newmodule = new stdClass();
+ $newmodule->name = $form_state['values']['name'];
+ drupal_write_record('module_builder_projects', $newmodule);
-function module_builder_delete_form(&$form_state, $values, $module) {
- return confirm_form(
- array(),
- t('Are you sure you want to delete the module %module?', array('%module' => $module->name)),
- 'admin/build/module_builder/edit/'. $module->mid
- );
-}
-
-function module_builder_delete_form_submit($form, &$form_state) {
- db_query('DELETE FROM {module_builder_data} WHERE mid = %d', $form_state['values']['mid']);
- db_query('DELETE FROM {module_builder_basic} WHERE mid = %d', $form_state['values']['mid']);
- $form_state['redirect'] = 'admin/build/module_builder';
+ // make the entered name appear on the general form then redirect to it
+ $prepared_form_values = array(
+ 'values' => array(
+ 'mid' => $newmodule->mid,
+ 'type' => 'general',
+ 'name' => $newmodule->name));
+ module_builder_default_submit(array(), $prepared_form_values);
+ $form_state['redirect'] = 'admin/build/module_builder/edit/'. $newmodule->mid;
}