array( 'title' => t('execute unlink files'), 'description' => t('TODO Add a description for \'execute unlink files\''), ), ); } /** * Implements hook_menu(). * * @return An array of menu items. */ function ftools_menu() { $items = array(); $items['admin/structure/features/unlink'] = array( 'title' => 'Execute unlink files', 'page callback' => 'drupal_get_form', 'page arguments' => array('ftools_unlink_form'), 'access arguments' => array('execute unlink files'), ); return $items; } /** * Implements hook_form_alter(). */ function ftools_form_features_admin_form_alter(&$form, &$form_state) { $form['disable_ajax'] = array('#type' => 'checkbox', '#title' => t('disable the features status ajax loading'), '#default_value' => variable_get('ftools_disable_features_page_js', 0)); $form['buttons']['submit']['#submit'][] = 'ftools_features_admin_form_submit'; $form['buttons']['revert'] = array( '#type' => 'submit', '#value' => t('Revert them All'), '#attributes' => array('onclick' => 'if(!confirm("Are you sure you want to revert all features? \nThis action cannot be undone.")){return false;}'), '#submit' => array('ftools_features_revert_all_submit') ); if (variable_get('ftools_disable_features_page_js', 0) == 0) { return; } drupal_add_css('table.features .admin-check, table.features .admin-default, table.features .admin-overridden, table.features .admin-rebuilding, table.features .admin-needs-review { display: inline!important;}', array('type' => 'inline')); $groups = array(); foreach ($form['#features'] as $feature) { if (isset($feature->info['package'])) { $package_title = !empty($feature->info['package']) ? $feature->info['package'] : t('Other'); $package = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $package_title)); if (in_array($package, $groups)) { continue; } $groups[] = $package; } } foreach ($groups as $group) { foreach ($form[$group]['state'] as $feature_name => &$feature_status) { if ($form[$group]['status'][$feature_name]['#default_value'] == 0) { continue; } $status = features_get_storage($feature_name); $cls = "admin"; switch ($status) { case 3: $cls .= "-rebuilding"; $txt = "Rebuilding"; break; case 2: $cls .= "-needs-review"; $txt = "Needs review"; break; case 1: $txt = "Overridden"; $cls .= "-overridden"; break; default: $txt = "Default"; $cls .= "-default"; break; } $cls .= " features-storage"; $feature_status['#markup'] = l($txt, "admin/structure/features/$feature_name", array('attributes' => array('class' => $cls))); } } } /** * Implements hook_form_FORM_ID_alter(). */ function ftools_form_features_export_form_alter(&$form, &$form_state) { if (isset($form['#feature']) && is_object($form['#feature']) && isset($form['#feature']->name)) { $path = drupal_get_path('module', $form['#feature']->name); } else { $path = 'sites/all/modules'; } $writeable = file_prepare_directory($path); if ($writeable === FALSE) { drupal_set_message(t('The directory @path does not exists or not writable', array('@path' => $path)), 'error'); } //TODO: add backup options. if (variable_get('ftools_disable_features_page_js', 0)) { foreach ($form['export']['sources'] as &$value) { if (is_array($value) && isset($value['#ajax'])) { unset($value['#ajax']); } } } $form['buttons']['create'] = array( '#type' => 'submit', '#value' => t('Auto create feature'), '#weight' => 10, '#submit' => array('ftools_export_build_form_submit'), ); $form['ftools_dest'] = array( '#title' => t('Custom module path.'), '#type' => 'textfield', '#default_value' => $path ); if ($form['#feature']) { $form['buttons']['safe_recreate'] = array( '#type' => 'submit', '#value' => t('Safe Auto create feature'), '#weight' => 10, '#submit' => array('ftools_form_features_export_form_safe_submit'), ); } } /** * @todo Please document this function. * @see http://drupal.org/node/1354 */ function ftools_form_features_export_form_safe_submit($form, &$form_state) { if (module_exists('rules')) { module_load_include('inc', 'features', 'features.export'); features_include(); module_load_include('inc', 'rules', 'modules/events'); rules_invoke_event('init'); module_load_include('inc', 'rules_admin', 'rules_admin.export'); module_load_include('inc', 'rules', 'rules.export'); } $destination = $form_state['values']['ftools_dest']; $arr = explode('/', $destination); $arr[sizeof($arr) - 1] .= '_unlink'; $module_name = $arr[sizeof($arr) - 1]; $destination = implode('/', $arr) . '/'; $destination_info = _ftools_get_unlink_version($destination); $hooks = _ftools_get_hooks(); $new_feature = $form_state['values']['sources']; $old_feature = $form['#feature']->info['features']; $stub = array(); foreach ($hooks as $hook) { if (isset($old_feature[$hook])) { foreach ($old_feature[$hook] as $value) { if (!$new_feature[$hook][$value]) { $stub[$hook][] = $value; } } } } if ($stub) { $file_content = array(); foreach ($stub as $hook => $value) { $output = array(); $code_buffer = ''; foreach ($value as $component) { switch ($hook) { case 'views_view': $view = views_get_view($component); $output[] = $view->export(); $output[] = '$view->save();'; break; case 'box': $export = array('features' => array('box' => array($component => $component))); $component_hooks = features_export_render_hooks($export, $module_name, TRUE); $output[] = str_replace(' return $export;', '', $component_hooks['box']['default_box']); $output[] = 'drupal_write_record(' . "'box'" . ', $box);'; break; } } $code_buffer .= implode("\n", $output); $output = array(); $output[] = "/**"; $output[] = " * Unlink {$module_name}_{$destination_info['delta']}_{$hook}()."; $output[] = " */"; $output[] = "function {$module_name}_{$destination_info['delta']}_{$hook}() {"; $output[] = $code_buffer; $output[] = "}"; $file_content[] = implode("\n", $output); } $file_content = " l(t('the Features Tools module page'), 'http://drupal.org/project/ftools'))), 'error'); return; } else { drupal_set_message(t('The unlink file was successfully created.')); } } ftools_export_build_form_submit($form, $form_state); } /** * submit function for the features_export_form, write the file to disk. */ function ftools_export_build_form_submit($form, &$form_state) { module_load_include('inc', 'features', 'features.export'); features_include(); // Assemble the combined component list. $stub = array(); $components = array_keys(features_get_components()); foreach ($components as $component) { // User-selected components take precedence. if (!empty($form_state['values']['sources'][$component])) { $stub[$component] = features_dom_decode_options(array_filter($form_state['values']['sources'][$component])); } // Only fallback to an existing feature's values if there are no export options for the component. elseif (!empty($form['#feature']->info['features'][$component])) { $stub[$component] = $form['#feature']->info['features'][$component]; } } // Generate populated feature. $module_name = $form_state['values']['module_name']; $export = features_populate($stub, $form_state['values']['sources']['dependencies'], $module_name); // Directly copy the following attributes. $attr = array('name', 'description'); foreach ($attr as $key) { $export[$key] = isset($form_state['values'][$key]) ? $form_state['values'][$key] : NULL; } // If either update status-related keys are provided, add a project key // corresponding to the module name. if (!empty($form_state['values']['version']) || !empty($form_state['values']['project_status_url'])) { $export['project'] = $form_state['values']['module_name']; } if (!empty($form_state['values']['version'])) { $export['version'] = $form_state['values']['version']; } if (!empty($form_state['values']['project_status_url'])) { $export['project status url'] = $form_state['values']['project_status_url']; } // Generate download. $directory = ''; $destination = $form_state['values']['ftools_dest']; if ($destination) { $directory .= $destination . '/'; } //TODO: find a better term then arg(3) to find if we are on create page or recreat. if (arg(3) == 'create') { $directory .= $module_name; } if ($files = features_export_render($export, $module_name, TRUE)) { //If the directory dont exists create it. if (!file_exists($directory)) { mkdir($directory, 0777, TRUE); } $error = false; foreach ($files as $extension => $file_contents) { if (!in_array($extension, array('module', 'info'))) { $extension .= '.inc'; } if (file_put_contents("{$directory}/{$module_name}.$extension", $file_contents) === FALSE) { $error = true; } } if ($error) { drupal_set_message(t('One or more files could not be written to the file system. This is probably a permission issue. See !link for more information.', array('!link' => l(t('the Features Tools module page'), 'http://drupal.org/project/ftools'))), 'error'); } else { drupal_set_message(t('The feature was successfully created.')); } } drupal_flush_all_caches(); } /** * @todo Please document this function. * @see http://drupal.org/node/1354 */ function ftools_unlink_form($form, $form_state) { $files = drupal_system_listing('/\.unlink.inc$/', 'modules', 'name', 0); $form = array(); $options = array(); foreach ($files as $value) { $options[$value->name] = str_replace('_unlink.unlink', '', $value->name); } $form['unlink_options'] = array( '#type' => 'checkboxes', '#options' => $options, ); $form['submit'] = array( '#type' => 'submit', '#value' => 'submit', '#name' => 'submit', ); return $form; } /** * @todo Please document this function. * @see http://drupal.org/node/1354 */ function ftools_unlink_form_submit($form, &$form_state) { $hooks = _ftools_get_hooks(); $files = drupal_system_listing('/\.unlink.inc$/', 'modules', 'name', 0); foreach ($form_state['values']['unlink_options'] as $key => $value) { if ($value) { include_once DRUPAL_ROOT . "/" . $files[$key]->uri; views_include('view'); foreach ($hooks as $hook) { $function_name = str_replace('.unlink', '', $key) . "_$hook"; $function_name = str_replace('.', '_', $function_name); if (function_exists($function_name)) { //TODO add info file so we can check if the element is in the db before trying to insert it. //i add a try catch block meanwhile to hide the error message. try { include_once DRUPAL_ROOT . "/" . $files[$key]->uri; } catch (Exception $e) { watchdog('ftools', "error in unlink function:" . $e->getMessage()); } drupal_set_message("$hook $function_name"); } } } } } function _ftools_get_hooks() { return array('box', 'views_view'); } /** * Get the next version for the unlink directory. * @param string $destination , the $destination path. * @return array with the directory delta and the new destination. */ function _ftools_get_unlink_version($destination) { $destination = substr($destination, 0, strlen($destination) - 1); $i = 1; while (file_exists("{$destination}_$i")) { $i++; } return array('destination' => "{$destination}_$i/", 'delta' => $i); } function ftools_features_admin_form_submit($form, &$form_state) { variable_set('ftools_disable_features_page_js', $form_state['values']['disable_ajax']); } function ftools_features_revert_all_submit($form, &$form_state) { module_load_include('inc', 'features', 'features.export'); features_include(); features_revert(); $form_state['redirect'] = 'admin/structure/features'; }