/** * {@inheritdoc} * * The translation update functions executed here are batch operations which * are also used in translation update batches. The batch functions may need * to be executed multiple times to complete their task, typically this is the * translation import function. When a batch function is not finished, a new * queue task is created and added to the end of the queue. The batch context * data is needed to continue the batch task is stored in the queue with the * queue data. */ public function processItem($data) { $this->moduleHandler->loadInclude('locale', 'batch.inc'); list($function, $args) = $data; // We execute batch operation functions here to check, download and import // the translation files. Batch functions use a context variable as last // argument which is passed by reference. When a batch operation is called // for the first time a default batch context is created. When called // iterative (usually the batch import function) the batch context is passed // through via the queue and is part of the $data. $last = count($args) - 1; if (!is_array($args[$last]) || !isset($args[$last]['finished'])) { $batch_context = ['sandbox' => [], 'results' => [], 'finished' => 1, 'message' => '']; } else { $batch_context = $args[$last]; unset($args[$last]); } $args = array_merge($args, [&$batch_context]); // Call the batch operation function. call_user_func_array($function, $args); // If the batch operation is not finished we create a new queue task to // continue the task. This is typically the translation import task. if ($batch_context['finished'] < 1) { unset($batch_context['strings']); $this->queue->createItem([$function, $args]); } }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { // Make sure the install API is available. include_once DRUPAL_ROOT . '/core/includes/install.inc'; // Get a list of all available modules. $modules = system_rebuild_module_data(); $uninstallable = array_filter($modules, function ($module) use($modules) { return empty($modules[$module->getName()]->info['required']) && $module->status; }); // Include system.admin.inc so we can use the sort callbacks. $this->moduleHandler->loadInclude('system', 'inc', 'system.admin'); $form['filters'] = array('#type' => 'container', '#attributes' => array('class' => array('table-filter', 'js-show'))); $form['filters']['text'] = array('#type' => 'search', '#title' => $this->t('Search'), '#size' => 30, '#placeholder' => $this->t('Enter module name'), '#attributes' => array('class' => array('table-filter-text'), 'data-table' => '#system-modules-uninstall', 'autocomplete' => 'off', 'title' => $this->t('Enter a part of the module name or description to filter by.'))); $form['modules'] = array(); // Only build the rest of the form if there are any modules available to // uninstall; if (empty($uninstallable)) { return $form; } $profile = drupal_get_profile(); // Sort all modules by their name. uasort($uninstallable, 'system_sort_modules_by_info_name'); $validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable)); $form['uninstall'] = array('#tree' => TRUE); foreach ($uninstallable as $module_key => $module) { $name = $module->info['name'] ?: $module->getName(); $form['modules'][$module->getName()]['#module_name'] = $name; $form['modules'][$module->getName()]['name']['#markup'] = $name; $form['modules'][$module->getName()]['description']['#markup'] = $this->t($module->info['description']); $form['uninstall'][$module->getName()] = array('#type' => 'checkbox', '#title' => $this->t('Uninstall @module module', array('@module' => $name)), '#title_display' => 'invisible'); // If a validator returns reasons not to uninstall a module, // list the reasons and disable the check box. if (isset($validation_reasons[$module_key])) { $form['modules'][$module->getName()]['#validation_reasons'] = $validation_reasons[$module_key]; $form['uninstall'][$module->getName()]['#disabled'] = TRUE; } // All modules which depend on this one must be uninstalled first, before // we can allow this module to be uninstalled. (The installation profile // is excluded from this list.) foreach (array_keys($module->required_by) as $dependent) { if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) { $name = isset($modules[$dependent]->info['name']) ? $modules[$dependent]->info['name'] : $dependent; $form['modules'][$module->getName()]['#required_by'][] = $name; $form['uninstall'][$module->getName()]['#disabled'] = TRUE; } } } $form['#attached']['library'][] = 'system/drupal.system.modules'; $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Uninstall')); return $form; }
/** * Tests locale_translation_clear_cache_projects(). */ public function testLocaleTranslationClearCacheProjects() { $this->moduleHandler->loadInclude('locale', 'inc', 'locale.translation'); $expected = []; $this->assertIdentical($expected, locale_translation_get_projects()); $this->projectStorage->set('foo', []); $expected['foo'] = new \stdClass(); $this->assertEqual($expected, locale_translation_get_projects()); $this->projectStorage->set('bar', []); locale_translation_clear_cache_projects(); $expected['bar'] = new \stdClass(); $this->assertEqual($expected, locale_translation_get_projects()); }
/** * Loads the cached form state. * * @param string $form_build_id * The unique form build ID. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ protected function loadCachedFormState($form_build_id, FormStateInterface $form_state) { if ($stored_form_state = $this->keyValueExpirableFactory->get('form_state')->get($form_build_id)) { // Re-populate $form_state for subsequent rebuilds. $form_state->setFormState($stored_form_state); // If the original form is contained in include files, load the files. // @see \Drupal\Core\Form\FormStateInterface::loadInclude() $build_info = $form_state->getBuildInfo(); $build_info += ['files' => []]; foreach ($build_info['files'] as $file) { if (is_array($file)) { $file += array('type' => 'inc', 'name' => $file['module']); $this->moduleHandler->loadInclude($file['module'], $file['type'], $file['name']); } elseif (file_exists($file)) { require_once $this->root . '/' . $file; } } // Retrieve the list of previously known safe strings and store it for // this request. // @todo Ensure we are not storing an excessively large string list // in: https://www.drupal.org/node/2295823 $build_info += ['safe_strings' => []]; SafeMarkup::setMultiple($build_info['safe_strings']); unset($build_info['safe_strings']); $form_state->setBuildInfo($build_info); } }
/** * {@inheritdoc} */ public function getCache($form_build_id, &$form_state) { if ($form = $this->keyValueExpirableFactory->get('form')->get($form_build_id)) { $user = $this->currentUser(); if (isset($form['#cache_token']) && $this->csrfToken->validate($form['#cache_token']) || !isset($form['#cache_token']) && $user->isAnonymous()) { if ($stored_form_state = $this->keyValueExpirableFactory->get('form_state')->get($form_build_id)) { // Re-populate $form_state for subsequent rebuilds. $form_state = $stored_form_state + $form_state; // If the original form is contained in include files, load the files. // @see form_load_include() $form_state['build_info'] += array('files' => array()); foreach ($form_state['build_info']['files'] as $file) { if (is_array($file)) { $file += array('type' => 'inc', 'name' => $file['module']); $this->moduleHandler->loadInclude($file['module'], $file['type'], $file['name']); } elseif (file_exists($file)) { require_once DRUPAL_ROOT . '/' . $file; } } // Retrieve the list of previously known safe strings and store it // for this request. // @todo Ensure we are not storing an excessively large string list // in: https://www.drupal.org/node/2295823 $form_state['build_info'] += array('safe_strings' => array()); SafeMarkup::setMultiple($form_state['build_info']['safe_strings']); unset($form_state['build_info']['safe_strings']); } return $form; } } }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { require_once DRUPAL_ROOT . '/core/includes/install.inc'; $distribution = SafeMarkup::checkPlain(drupal_install_profile_distribution_name()); // Include system.admin.inc so we can use the sort callbacks. $this->moduleHandler->loadInclude('system', 'inc', 'system.admin'); $form['filters'] = array('#type' => 'container', '#attributes' => array('class' => array('table-filter', 'js-show'))); $form['filters']['text'] = array('#type' => 'search', '#title' => $this->t('Search'), '#size' => 30, '#placeholder' => $this->t('Enter module name'), '#attributes' => array('class' => array('table-filter-text'), 'data-table' => '#system-modules', 'autocomplete' => 'off', 'title' => $this->t('Enter a part of the module name or description to filter by.'))); // Sort all modules by their names. $modules = system_rebuild_module_data(); uasort($modules, 'system_sort_modules_by_info_name'); // Iterate over each of the modules. $form['modules']['#tree'] = TRUE; foreach ($modules as $filename => $module) { if (empty($module->info['hidden'])) { $package = $module->info['package']; $form['modules'][$package][$filename] = $this->buildRow($modules, $module, $distribution); } } // Add a wrapper around every package. foreach (Element::children($form['modules']) as $package) { $form['modules'][$package] += array('#type' => 'details', '#title' => $this->t($package), '#open' => TRUE, '#theme' => 'system_modules_details', '#header' => array(array('data' => $this->t('Installed'), 'class' => array('checkbox', 'visually-hidden')), array('data' => $this->t('Name'), 'class' => array('name', 'visually-hidden')), array('data' => $this->t('Description'), 'class' => array('description', 'visually-hidden', RESPONSIVE_PRIORITY_LOW))), '#attributes' => array('class' => array('package-listing')), '#weight' => $package == 'Core' ? -10 : NULL); } // If testing modules are shown, collapse the corresponding package by // default. if (isset($form['modules']['Testing'])) { $form['modules']['Testing']['#open'] = FALSE; } // Lastly, sort all packages by title. uasort($form['modules'], array('\\Drupal\\Component\\Utility\\SortArray', 'sortByTitleProperty')); $form['#attached']['library'][] = 'system/drupal.system.modules'; $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save configuration'), '#button_type' => 'primary'); return $form; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->moduleHandler->loadInclude('locale', 'fetch.inc'); $this->moduleHandler->loadInclude('locale', 'bulk.inc'); $langcodes = array_filter($form_state->getValue('langcodes')); $projects = array_filter($form_state->getValue('projects_update')); // Set the translation import options. This determines if existing // translations will be overwritten by imported strings. $options = _locale_translation_default_update_options(); // If the status was updated recently we can immediately start fetching the // translation updates. If the status is expired we clear it an run a batch to // update the status and then fetch the translation updates. $last_checked = $this->state->get('locale.translation_last_checked'); if ($last_checked < REQUEST_TIME - LOCALE_TRANSLATION_STATUS_TTL) { locale_translation_clear_status(); $batch = locale_translation_batch_update_build(array(), $langcodes, $options); batch_set($batch); } else { // Set a batch to download and import translations. $batch = locale_translation_batch_fetch_build($projects, $langcodes, $options); batch_set($batch); // Set a batch to update configuration as well. if ($batch = locale_config_batch_update_components($options, $langcodes)) { batch_set($batch); } } }
/** * Build the list of modules * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * @param boolean $enabled * Enable the check boxes */ protected function buildTable(array &$form, FormStateInterface $form_state, $enabled) { $config = $this->config('nagios.settings'); $header = array('title' => t('Title'), 'description' => t('Description')); $options = array(); // Include system.admin.inc so we can use the sort callbacks. $this->moduleHandler->loadInclude('system', 'inc', 'system.admin'); // Sort all modules by their names. $modules = system_rebuild_module_data(); uasort($modules, 'system_sort_modules_by_info_name'); // Build the rows foreach ($modules as $filename => $module) { if (empty($module->info['hidden'])) { $options[$filename] = $this->buildRow($modules, $module); $options[$filename]['#disabled'] = TRUE; } } // Set up the check boxes $defaults = array(); $nagios_ignored_modules = $config->get('nagios.ignored_modules') ?: array(); foreach ($nagios_ignored_modules as $ignored_module) { $defaults[$ignored_module] = 1; } $form['modules'] = array('#type' => 'tableselect', '#header' => $header, '#options' => $options, '#empty' => t('No modules available.'), '#default_value' => $defaults); if (!$enabled) { foreach ($form['modules']['#options'] as $key => $value) { $form['modules']['#options']['#disabled'] = TRUE; } } }
private function devel_token_object($entity_type, $entity_id, Request $request) { $this->moduleHandler->loadInclude('token', 'pages.inc'); $entity = entity_load($entity_type, $entity_id); $header = array(t('Token'), t('Value')); $rows = array(); $options = array('flat' => TRUE, 'values' => TRUE, 'data' => array($entity_type => $entity)); $tree = token_build_tree($entity_type, $options); foreach ($tree as $token => $token_info) { if (!empty($token_info['restricted'])) { continue; } if (!isset($token_info['value']) && !empty($token_info['parent']) && !isset($tree[$token_info['parent']]['value'])) { continue; } $row = _token_token_tree_format_row($token, $token_info); unset($row['data']['description']); unset($row['data']['name']); $rows[] = $row; } $build['tokens'] = array('#theme' => 'tree_table', '#header' => $header, '#rows' => $rows, '#attributes' => array('class' => array('token-tree')), '#empty' => t('No tokens available.'), '#attached' => array('library' => array('token/token'))); return $build; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { // Add language, if not yet supported. $language = $this->languageManager->getLanguage($form_state->getValue('langcode')); if (empty($language)) { $language = ConfigurableLanguage::createFromLangcode($form_state->getValue('langcode')); $language->save(); drupal_set_message($this->t('The language %language has been created.', array('%language' => $this->t($language->label())))); } $options = array('langcode' => $form_state->getValue('langcode'), 'overwrite_options' => $form_state->getValue('overwrite_options'), 'customized' => $form_state->getValue('customized') ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED); $this->moduleHandler->loadInclude('locale', 'bulk.inc'); $file = locale_translate_file_attach_properties($this->file, $options); $batch = locale_translate_batch_build(array($file->uri => $file), $options); batch_set($batch); $form_state->setRedirect('locale.translate_page'); }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { // Add language, if not yet supported. $language = $this->languageManager->getLanguage($form_state['values']['langcode']); if (empty($language)) { $language = new Language(array('id' => $form_state['values']['langcode'])); $language = language_save($language); drupal_set_message($this->t('The language %language has been created.', array('%language' => $this->t($language->name)))); } $options = array('langcode' => $form_state['values']['langcode'], 'overwrite_options' => $form_state['values']['overwrite_options'], 'customized' => $form_state['values']['customized'] ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED); $this->moduleHandler->loadInclude('locale', 'bulk.inc'); $file = locale_translate_file_attach_properties($this->file, $options); $batch = locale_translate_batch_build(array($file->uri => $file), $options); batch_set($batch); $form_state['redirect_route']['route_name'] = 'locale.translate_page'; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); $projects = array(); foreach (array('projects', 'disabled_projects') as $type) { if (!empty($form_state['values'][$type])) { $projects = array_merge($projects, array_keys(array_filter($form_state['values'][$type]))); } } $operations = array(); foreach ($projects as $project) { $operations[] = array('update_manager_batch_project_get', array($project, $form_state['values']['project_downloads'][$project])); } $batch = array('title' => $this->t('Downloading updates'), 'init_message' => $this->t('Preparing to download selected updates'), 'operations' => $operations, 'finished' => 'update_manager_download_batch_finished', 'file' => drupal_get_path('module', 'update') . '/update.manager.inc'); batch_set($batch); }
/** * Shows the status of all required packages. * * @return array * Returns a render array as expected by drupal_render(). */ public function page() { if (!composer_manager_initialized()) { $message = t("Composer Manager needs to be initialized before usage. Run the module's <code>init.sh</code> script or <code>drush composer-manager-init</code> on the command line."); drupal_set_message($message, 'warning'); return array(); } try { $packages = $this->packageManager->getRequiredPackages(); } catch (\RuntimeException $e) { drupal_set_message(Xss::filterAdmin($e->getMessage()), 'error'); $packages = array(); } $rows = array(); foreach ($packages as $package_name => $package) { // Prepare the package name and description. if (!empty($package['homepage'])) { $options = array('attributes' => array('target' => '_blank')); $name = $this->l($package_name, Url::fromUri($package['homepage']), $options); } else { $name = SafeMarkup::checkPlain($package_name); } if (!empty($package['description'])) { $name .= '<div class="description">' . SafeMarkup::checkPlain($package['description']) . '</div>'; } // Prepare the installed and required versions. $installed_version = $package['version'] ? $package['version'] : $this->t('Not installed'); $required_version = $this->buildRequiredVersion($package['constraint'], $package['required_by']); // Prepare the row classes. $class = array(); if (empty($package['version'])) { $class[] = 'error'; } elseif (empty($package['required_by'])) { $class[] = 'warning'; } $rows[$package_name] = array('class' => $class, 'data' => array('package' => SafeMarkup::set($name), 'installed_version' => $installed_version, 'required_version' => SafeMarkup::set($required_version))); } $build = array(); $build['packages'] = array('#theme' => 'table', '#header' => array('package' => $this->t('Package'), 'installed_version' => $this->t('Installed Version'), 'required_version' => $this->t('Required Version')), '#rows' => $rows, '#caption' => $this->t('Status of Packages Managed by Composer'), '#attributes' => array('class' => array('system-status-report'))); // Display any errors returned by hook_requirements(). $this->moduleHandler->loadInclude('composer_manager', 'install'); $requirements = composer_manager_requirements('runtime'); if ($requirements['composer_manager']['severity'] == REQUIREMENT_ERROR) { drupal_set_message($requirements['composer_manager']['description'], 'warning'); } return $build; }
/** * Shows the status of all required packages. * * @return array * Returns a render array as expected by drupal_render(). */ public function page() { if (!composer_manager_initialized()) { $message = t("Composer Manager needs to be initialized before usage. Run the module's <code>init.php</code> script on the command line."); drupal_set_message($message, 'warning'); return []; } try { $packages = $this->packageManager->getRequiredPackages(); } catch (\RuntimeException $e) { drupal_set_message(Xss::filterAdmin($e->getMessage()), 'error'); return []; } $rows = []; foreach ($packages as $package_name => $package) { $package_column = []; if (!empty($package['homepage'])) { $package_column[] = ['#type' => 'link', '#title' => $package_name, '#url' => Url::fromUri($package['homepage']), '#options' => ['attributes' => ['target' => '_blank']]]; } else { $package_column[] = ['#plain_text' => $package_name]; } if (!empty($package['description'])) { $package_column[] = ['#prefix' => '<div class="description">', '#plain_text' => $package['description'], '#suffix' => '</div>']; } // Prepare the installed and required versions. $installed_version = $package['version'] ? $package['version'] : $this->t('Not installed'); $required_version = $this->buildRequiredVersion($package['constraint'], $package['required_by']); // Prepare the row classes. $class = []; if (empty($package['version'])) { $class[] = 'error'; } elseif (empty($package['required_by'])) { $class[] = 'warning'; } $rows[$package_name] = ['class' => $class, 'data' => ['package' => ['data' => $package_column], 'installed_version' => $installed_version, 'required_version' => ['data' => $required_version]]]; } $build = []; $build['packages'] = ['#theme' => 'table', '#header' => ['package' => $this->t('Package'), 'installed_version' => $this->t('Installed Version'), 'required_version' => $this->t('Required Version')], '#rows' => $rows, '#caption' => $this->t('Status of Packages Managed by Composer'), '#attributes' => ['class' => ['system-status-report']]]; // Display any errors returned by hook_requirements(). $this->moduleHandler->loadInclude('composer_manager', 'install'); $requirements = composer_manager_requirements('runtime'); if ($requirements['composer_manager']['severity'] == REQUIREMENT_ERROR) { drupal_set_message($requirements['composer_manager']['description'], 'warning'); } return $build; }
/** * Loads the cached form state. * * @param string $form_build_id * The unique form build ID. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ protected function loadCachedFormState($form_build_id, FormStateInterface $form_state) { if ($stored_form_state = $this->keyValueExpirableFactory->get('form_state')->get($form_build_id)) { // Re-populate $form_state for subsequent rebuilds. $form_state->setFormState($stored_form_state); // If the original form is contained in include files, load the files. // @see \Drupal\Core\Form\FormStateInterface::loadInclude() $build_info = $form_state->getBuildInfo(); $build_info += ['files' => []]; foreach ($build_info['files'] as $file) { if (is_array($file)) { $file += array('type' => 'inc', 'name' => $file['module']); $this->moduleHandler->loadInclude($file['module'], $file['type'], $file['name']); } elseif (file_exists($file)) { require_once $this->root . '/' . $file; } } } }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { // Store maintenance_mode setting so we can restore it when done. $_SESSION['maintenance_mode'] = $this->state->get('system.maintenance_mode'); if ($form_state->getValue('maintenance_mode') == TRUE) { $this->state->set('system.maintenance_mode', TRUE); } if (!empty($_SESSION['update_manager_update_projects'])) { // Make sure the Updater registry is loaded. drupal_get_updaters(); $updates = array(); $directory = _update_manager_extract_directory(); $projects = $_SESSION['update_manager_update_projects']; unset($_SESSION['update_manager_update_projects']); $project_real_location = NULL; foreach ($projects as $project => $url) { $project_location = $directory . '/' . $project; $updater = Updater::factory($project_location, $this->root); $project_real_location = drupal_realpath($project_location); $updates[] = array('project' => $project, 'updater_name' => get_class($updater), 'local_url' => $project_real_location); } // If the owner of the last directory we extracted is the same as the // owner of our configuration directory (e.g. sites/default) where we're // trying to install the code, there's no need to prompt for FTP/SSH // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local // and invoke update_authorize_run_update() directly. if (fileowner($project_real_location) == fileowner($this->sitePath)) { $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); $filetransfer = new Local($this->root); $response = update_authorize_run_update($filetransfer, $updates); if ($response instanceof Response) { $form_state->setResponse($response); } } else { // The page title must be passed here to ensure it is initially used // when authorize.php loads for the first time with the FTP/SSH // credentials form. system_authorized_init('update_authorize_run_update', __DIR__ . '/../../update.authorize.inc', array($updates), $this->t('Update manager')); $form_state->setRedirectUrl(system_authorized_get_url()); } } }
/** * Builds a query for database log administration filters based on session. * * @return array * An associative array with keys 'where' and 'args'. */ protected function buildFilterQuery() { if (empty($_SESSION['dblog_overview_filter'])) { return; } $this->moduleHandler->loadInclude('dblog', 'admin.inc'); $filters = dblog_filters(); // Build query. $where = $args = array(); foreach ($_SESSION['dblog_overview_filter'] as $key => $filter) { $filter_where = array(); foreach ($filter as $value) { $filter_where[] = $filters[$key]['where']; $args[] = $value; } if (!empty($filter_where)) { $where[] = '(' . implode(' OR ', $filter_where) . ')'; } } $where = !empty($where) ? implode(' AND ', $where) : ''; return array('where' => $where, 'args' => $args); }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { // Store maintenance_mode setting so we can restore it when done. $_SESSION['maintenance_mode'] = $this->state->get('system.maintenance_mode'); if ($form_state['values']['maintenance_mode'] == TRUE) { $this->state->set('system.maintenance_mode', TRUE); } if (!empty($_SESSION['update_manager_update_projects'])) { // Make sure the Updater registry is loaded. drupal_get_updaters(); $updates = array(); $directory = _update_manager_extract_directory(); $projects = $_SESSION['update_manager_update_projects']; unset($_SESSION['update_manager_update_projects']); $project_real_location = NULL; foreach ($projects as $project => $url) { $project_location = $directory . '/' . $project; $updater = Updater::factory($project_location); $project_real_location = drupal_realpath($project_location); $updates[] = array('project' => $project, 'updater_name' => get_class($updater), 'local_url' => $project_real_location); } // If the owner of the last directory we extracted is the same as the // owner of our configuration directory (e.g. sites/default) where we're // trying to install the code, there's no need to prompt for FTP/SSH // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local // and invoke update_authorize_run_update() directly. if (fileowner($project_real_location) == fileowner(conf_path())) { $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); $filetransfer = new Local(DRUPAL_ROOT); update_authorize_run_update($filetransfer, $updates); } else { system_authorized_init('update_authorize_run_update', drupal_get_path('module', 'update') . '/update.authorize.inc', array($updates), $this->t('Update manager')); $form_state['redirect'] = system_authorized_get_url(); } } }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $local_cache = NULL; if ($form_state->getValue('project_url')) { $local_cache = update_manager_file_get($form_state->getValue('project_url')); if (!$local_cache) { drupal_set_message($this->t('Unable to retrieve Drupal project from %url.', array('%url' => $form_state->getValue('project_url'))), 'error'); return; } } elseif ($_FILES['files']['name']['project_upload']) { $validators = array('file_validate_extensions' => array(archiver_get_extensions())); if (!($finfo = file_save_upload('project_upload', $validators, NULL, 0, FILE_EXISTS_REPLACE))) { // Failed to upload the file. file_save_upload() calls // drupal_set_message() on failure. return; } $local_cache = $finfo->getFileUri(); } $directory = _update_manager_extract_directory(); try { $archive = update_manager_archive_extract($local_cache, $directory); } catch (\Exception $e) { drupal_set_message($e->getMessage(), 'error'); return; } $files = $archive->listContents(); if (!$files) { drupal_set_message($this->t('Provided archive contains no files.'), 'error'); return; } // Unfortunately, we can only use the directory name to determine the // project name. Some archivers list the first file as the directory (i.e., // MODULE/) and others list an actual file (i.e., MODULE/README.TXT). $project = strtok($files[0], '/\\'); $archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', array($project, $local_cache, $directory)); if (!empty($archive_errors)) { drupal_set_message(array_shift($archive_errors), 'error'); // @todo: Fix me in D8: We need a way to set multiple errors on the same // form element and have all of them appear! if (!empty($archive_errors)) { foreach ($archive_errors as $error) { drupal_set_message($error, 'error'); } } return; } // Make sure the Updater registry is loaded. drupal_get_updaters(); $project_location = $directory . '/' . $project; try { $updater = Updater::factory($project_location, $this->root); } catch (\Exception $e) { drupal_set_message($e->getMessage(), 'error'); return; } try { $project_title = Updater::getProjectTitle($project_location); } catch (\Exception $e) { drupal_set_message($e->getMessage(), 'error'); return; } if (!$project_title) { drupal_set_message($this->t('Unable to determine %project name.', array('%project' => $project)), 'error'); } if ($updater->isInstalled()) { drupal_set_message($this->t('%project is already installed.', array('%project' => $project_title)), 'error'); return; } $project_real_location = drupal_realpath($project_location); $arguments = array('project' => $project, 'updater_name' => get_class($updater), 'local_url' => $project_real_location); // This process is inherently difficult to test therefore use a state flag. $test_authorize = FALSE; if (drupal_valid_test_ua()) { $test_authorize = \Drupal::state()->get('test_uploaders_via_prompt', FALSE); } // If the owner of the directory we extracted is the same as the owner of // our configuration directory (e.g. sites/default) where we're trying to // install the code, there's no need to prompt for FTP/SSH credentials. // Instead, we instantiate a Drupal\Core\FileTransfer\Local and invoke // update_authorize_run_install() directly. if (fileowner($project_real_location) == fileowner($this->sitePath) && !$test_authorize) { $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); $filetransfer = new Local($this->root); $response = call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments)); if ($response instanceof Response) { $form_state->setResponse($response); } } else { // The page title must be passed here to ensure it is initially used when // authorize.php loads for the first time with the FTP/SSH credentials // form. system_authorized_init('update_authorize_run_install', __DIR__ . '/../../update.authorize.inc', $arguments, $this->t('Update manager')); $form_state->setRedirectUrl(system_authorized_get_url()); } }