- <?php
- * @file
- * Various functions that are required by the Installer browse pages.
- */
-
- * Checks if a project is enabled.
- *
- * @param string $type
- * The type of project. Could be 'theme' or 'module' or 'layout'.
- * @param string $name
- * The short name of the project.
- *
- * @return
- * TRUE if the project is enabled, FALSE otherwise.
- */
- function _installer_browser_is_project_enabled($type, $name) {
- switch ($type) {
- case 'module':
- return module_exists($name);
- break;
- case 'theme':
- $themes = list_themes();
- return isset($themes[$name]) && $themes[$name]->status;
- break;
- case 'layout':
- $excluded_templates = config_get('layout.settings', 'excluded_templates');
- return layout_get_layout_template_info($name) && !in_array($name, $excluded_templates);
- break;
- }
- return FALSE;
- }
-
- * Gets the currently listed projects from the session.
- */
- function installer_browser_get_listed_projects() {
- if (isset($_SESSION['installer_browser_listed_projects'])) {
- return $_SESSION['installer_browser_listed_projects'];
- }
-
- return array();
- }
-
- * Gets the currently queued projects from the session.
- */
- function installer_browser_get_queued_projects($type = NULL) {
- $projects = array();
-
- if (isset($_SESSION['installer_browser_install_list'])) {
- foreach ($_SESSION['installer_browser_install_list'] as $project) {
- if (is_array($project) && !empty($project)) {
- if (isset($type) && $type != $project['type']) {
- continue;
- }
- else {
- $projects[$project['name']] = $project;
- }
- }
- }
- }
-
- return $projects;
- }
-
- * Gets a release from a project and a release_name.
- */
- function installer_browser_get_release($release_name, $project) {
- $release_data = installer_browser_get_project_release_data($project);
-
- return isset($release_data['releases'][$release_name]) ? $release_data['releases'][$release_name] : FALSE;
- }
-
- * Gets the newly installed projects from the session.
- */
- function installer_browser_get_installed_projects() {
- $projects = array();
-
- if (isset($_SESSION['installer_browser_installed_projects'])) {
- foreach ($_SESSION['installer_browser_installed_projects'] as $project) {
- if (is_array($project) && !empty($project)) {
- $projects[$project['name']] = $project;
- }
- }
- }
-
- return $projects;
- }
-
- * Adds a project to the install queue.
- */
- function installer_browser_install_queue_add($project) {
- $_SESSION['installer_browser_install_list'][$project['name']] = $project;
- }
-
- * Removes a project from the install queue.
- */
- function installer_browser_install_queue_remove($project_name) {
- if (isset($_SESSION['installer_browser_install_list'][$project_name])) {
- unset($_SESSION['installer_browser_install_list'][$project_name]);
- }
- }
-
- * Removes a project from the list of recently installed projects.
- *
- * @param string[] $project_names
- * A list of projects to remove from the installed project list.
- *
- * @since 1.10.1
- */
- function installer_browser_installed_projects_remove($project_names) {
- foreach ($project_names as $project_name) {
- if (isset($_SESSION['installer_browser_installed_projects'][$project_name])) {
- unset($_SESSION['installer_browser_installed_projects'][$project_name]);
- }
- }
- }
-
- * Clears the install queue.
- *
- * Removes all projects from the $_SESSION variables.
- *
- * @param bool $include_installed
- * If TRUE, also clear the list of recently installed projects.
- */
- function installer_browser_install_queue_clear($include_installed = FALSE) {
- $_SESSION['installer_browser_install_list'] = array();
- if ($include_installed) {
- $_SESSION['installer_browser_installed_projects'] = array();
- }
- }
-
- * Gets the currently queued releases from the session.
- */
- function installer_browser_get_queued_releases() {
- $releases = array();
-
- if (isset($_SESSION['installer_browser_install_releases_list'])) {
- foreach ($_SESSION['installer_browser_install_releases_list'] as $release_name => $project) {
- if (is_array($project) && !empty($project)) {
- $releases[$release_name] = $project;
- }
- }
- }
-
- return $releases;
- }
-
- * Fetches results from the server based on the parameters passed in.
- *
- * $filters should be an associative array with the following keys:
- * - version: The Major Version of Backdrop that is running on the Client.
- * - text: The text that was entered as the search query, or '' if none.
- * - type: The type of project being searched.
- * - page: The zero-based page number.
- * - items_per_page: How many results are requested per page.
- *
- * For example:
- * @code
- * array(
- * 'version' => '1',
- * 'text' => 'views',
- * 'type' => 'module',
- * 'page' => 3,
- * 'items_per_page' => 12,
- * )
- * @endcode
- *
- * The installer_browser_fetch_results($filters) call returns an array with the
- * following keys:
- * - total: The total number of results found for the filters.
- * - projects: An array of projects returned for this page request keyed by
- * machine name. Each project array may contain the following key-value
- * pairs:
- * - type: The type of project this is. Can be 'module' or 'theme'.
- * - title: The title of the project.
- * - name: The machine name of the project.
- * - author: The author's name.
- * - description: The project description.
- * - image: Absolute url to the image, if any.
- * - usage: Number of reported active installs.
- * - project url: Absolute url to the project page, if any.
- * - project status url: The absolute url of the update checker.
- * - last updated: UNIX Timestamp of when the project was last updated.
- * - maintenance status: The project maintenance status.
- * - development status: The project development status.
- * - rating: A rating on a scale of 1 to 10 of the project, if available.
- * - dependencies: An array of the dependencies of this module.
- *
- * The following is an example of a valid return array:
- * @code
- * array(
- * 'total' = 5,
- * 'projects' => array(
- * 'views' => array(
- * 'type' => 'module',
- * 'title' => 'Views',
- * 'name' => 'views',
- * 'author' => 'merlinofchaos',
- * 'description' => 'Long project description',
- * 'image' => 'http://www.example.com/image.jpg',
- * 'usage' => '542312',
- * 'project url' => 'https://www.example.org/projects/views',
- * 'project status url' => 'https://updates.example.org/release-history/views/1.x',
- * 'last updated' => '12342523',
- * 'maintenance status' => 'Actively maintained',
- * 'development status' => 'Under active development',
- * 'rating' => '9.6',
- * 'dependencies' => array(
- * 'entity',
- * ),
- * ),
- * 'another_project => array(
- * 'type' => 'module',
- * ...
- * ),
- * ),
- * );
- * @endcode
- *
- * @param array $filters
- * An associative array of queries to use to filter results.
- *
- * @return
- * Returns an array of results.
- */
- function installer_browser_fetch_results($filters) {
- $server = installer_browser_get_server();
-
- $cid = 'installer:results:' . md5(serialize(array_merge($filters, $server)));
- if ($cache = cache_get($cid)) {
- return $cache->data;
- }
-
- $local_filters = $filters;
- $local_filters['method'] = 'query';
-
- $query_url = $server['url'] . '/query/' . $local_filters['type'] . '/1?' . http_build_query($local_filters, FALSE, '&');
- $response = backdrop_http_request($query_url);
-
- if ($response->code == '200') {
- $results = backdrop_json_decode($response->data);
- }
- else {
- backdrop_set_message(t("Encountered an error when trying to fetch results from @name. Error @code : @message",
- array('@name' => $server['name'], '@code' => $response->code, '@message' => $response->error)));
- return array();
- }
-
-
- cache_set($cid, $results, 'cache', strtotime("+24 hours"));
-
- return $results;
- }
-
- * Gets the server to use for fetching results.
- *
- * The installer_browser_fetch_results($filters) call returns an array with the
- * following keys:
- * @return
- * Returns an array representing the active server with the following keys:
- * - url: The absolute url to the server without query parameters.
- * - name: A human-readable name for this server.
- * For example:
- * @code
- * array(
- * "url" => "https://projects.backdropcms.org",
- * "name" => "Backdrop",
- * )
- * @endcode
- */
- function installer_browser_get_server() {
- $server = config_get('installer.settings', 'installer_server');
- backdrop_alter('installer_server', $server);
-
- return $server;
- }
-
- * Uses the project status url to get the available releases for a project.
- *
- * @param array $project
- * Associative array of information about the project to fetch release data
- * for, as returned by the remote server.
- *
- * @return array|FALSE
- * An array of releases for this project or FALSE if the project is not found.
- */
- function installer_browser_get_project_release_data(array $project) {
- $project['project_type'] = $project['type'];
-
- module_load_include('inc', 'update', 'update.fetch');
- if (_update_process_fetch_task($project)) {
- $data = _update_cache_get('available_releases::' . $project['name']);
- if (isset($data->data) && isset($data->data['releases']) && is_array($data->data['releases'])) {
- return $data->data;
- }
- }
-
- return FALSE;
- }
-
- * Batch API callback: Installs a single release of a project during batch.
- *
- * @param $release_name
- * The short name of the selected release of the project being installed.
- * @param $project
- * Associative array of information about the project to be installed.
- */
- function _installer_browser_batch_install_release($release_name, $project, &$context) {
- $release = installer_browser_get_release($release_name, $project);
-
- module_load_include('inc', 'installer', 'installer.manager');
- $url = file_create_url($release['download_link']);
- $result = installer_manager_download_project($url, TRUE);
-
- if ($result['success']) {
- $context['results']['successes'][] = t('Successfully installed %project.', array('%project' => $project['title']));
- $context['message'] = t('Installed %project...', array('%project' => $project['title']));
-
-
-
- $_SESSION['installer_browser_installed_projects'][$project['name']] = $project;
- unset($_SESSION['installer_browser_install_list'][$project['name']]);
- }
- else {
- watchdog('installer', 'There was an error while installing %project.
- !message',
- array('%project' => $project['title'], '!message' => $result['message']), WATCHDOG_ERROR);
- $context['results']['failures'][] = t('Error installing %project. !message',
- array('%project' => $project['title'], '!message' => $result['message']));
- $context['message'] = t('Error installing %project. Errors have been logged.',
- array('%project' => $project['title']));
- }
- }
-
- * Batch API callback: shows a message and finishes up the batch.
- */
- function _installer_browser_batch_install_releases_finished($success, $results, $operations) {
-
-
-
- backdrop_get_messages();
-
-
- if (isset($_SESSION['maintenance_mode'])) {
- state_set('maintenance_mode', $_SESSION['maintenance_mode']);
- unset($_SESSION['maintenance_mode']);
- }
-
- unset($_SESSION['installer_browser_install_releases_list']);
- if ($success) {
- if (!empty($results)) {
- if (!empty($results['failures'])) {
- backdrop_set_message(format_plural(count($results['failures']), 'Failed to install one project.', 'Failed to install @count projects.'), 'error');
- foreach($results['failures'] as $message){
- backdrop_set_message($message, 'error');
- }
- }
- }
- }
- else {
- backdrop_set_message(t('Error installing projects.'), 'error');
- backdrop_goto('admin/installer/install/select_versions');
- }
-
- $projects = installer_browser_get_installed_projects();
- $missing = installer_browser_get_missing_dependencies($projects);
-
- if (count($missing) > 0) {
- backdrop_goto('admin/installer/install/install_dependencies');
- }
- else {
- installer_browser_get_destination_after_install();
- }
- }
-
- * Determines the types of installed projects.
- */
- function installer_browser_get_installed_types() {
- $types = array();
- $projects = installer_browser_get_installed_projects();
- foreach ($projects as $project) {
- $types[$project['type']] = $project['type'];
- }
-
- return $types;
- }
-
- * Determines the form destination after installed projects.
- */
- function installer_browser_get_destination_after_install() {
- $types = installer_browser_get_installed_types();
-
- $layout = in_array('layout', $types);
- $theme = in_array('theme', $types);
- $module = in_array('module', $types);
-
- $layout_message = t('Installation finished successfully. All newly-added layout templates have been enabled and are available for use in your layouts. You can manage them on the <a href="@link">Layout templates</a> page.', array('@link' => url('admin/structure/layouts/settings')));
-
- if ($layout) {
-
-
- if ($theme || $module) {
- if (!$theme) {
- backdrop_set_message($layout_message);
- backdrop_goto('admin/installer/install/enable');
- }
- else {
- backdrop_set_message($layout_message);
- backdrop_goto('admin/installer/install/theme');
- }
- }
-
- else {
- backdrop_set_message($layout_message);
- backdrop_goto('admin/structure/layouts');
- }
- }
-
- elseif ($theme && $module) {
- backdrop_goto('admin/installer/install/theme');
- }
-
- elseif ($theme && !$module) {
- backdrop_set_message(t('One or more themes were installed. You may enable them now.'));
- backdrop_goto('admin/appearance');
- }
-
- else {
- backdrop_goto('admin/installer/install/enable');
- }
- }
-
- * Gets the dependencies for installed projects.
- */
- function installer_browser_get_missing_dependencies($projects) {
- $modules = system_rebuild_module_data();
-
- $missing = array();
-
- foreach ($projects as $project) {
- if ($project['type'] == 'module') {
- $dependencies = array();
- if (isset($modules[$project['name']])) {
- foreach ($modules[$project['name']]->requires as $requires) {
- $dependency = $requires['name'];
- if (!isset($modules[$dependency])) {
- $dependencies[] = $dependency;
- }
- }
- if (count($dependencies) > 0) {
- $missing[$project['name']] = $dependencies;
- }
- }
- else {
- backdrop_set_message(t('There was an error getting information for @module',
- array('@module' => $project['name'])), 'error');
- }
- }
- }
-
- return $missing;
- }
-
- * Builds the add/remove project to install queue link.
- */
- function installer_browser_add_remove_queue_link($project_name, $title = NULL, $id_prefix = 'add-to-queue-link') {
- $queued_projects = installer_browser_get_queued_projects();
- if (!$title) {
- $title = isset($queued_projects[$project_name]) ? t('Remove from Installation queue') : t('Add to Installation queue');
- }
- $op = isset($queued_projects[$project_name]) ? 'remove' : 'add';
-
- if (backdrop_is_dialog()) {
- $form = backdrop_get_form('installer_browser_add_remove_queue_dialog_link', $project_name, $op, $title);
- return backdrop_render($form);
- }
- else {
- $build['ajax_link'] = array(
- '#type' => 'link',
- '#title' => $title,
- '#href' => 'admin/installer/queue/nojs/' . $op . '/'. $project_name,
- '#options' => array(
- 'query' => backdrop_get_destination(),
- ),
- '#id' => $id_prefix . '-' . $project_name,
- '#ajax' => array(
- 'effect' => 'fade',
- 'speed' => 1000,
- 'progress' => array(
- 'type' => 'throbber',
- ),
- ),
- );
-
- }
-
- return backdrop_render($build);
- }
-
- * Builds an "add-to-queue-link" button for project detail dialog.
- */
- function installer_browser_add_remove_queue_dialog_link($form, &$form_state, $project_name, $op, $title) {
- form_load_include($form_state, 'inc', 'installer', 'installer.browser');
- $form['#attached']['js'][] = backdrop_get_path('module', 'layout') . '/js/layout.admin.js';
- $form['#attached']['css'][] = backdrop_get_path('module', 'layout') . '/css/layout.admin.css';
-
- if (empty($form_state['project_name'])) {
- $form_state['project_name'] = $project_name;
- $form_state['op'] = $op;
- $form_state['title'] = $title;
- }
-
- $form['ajax_link'] = array(
- '#type' => 'submit',
- '#value' => $form_state['title'],
- '#attributes' => array('class' => array('layout-link-button')),
- '#ajax' => array(
- 'callback' => 'installer_browser_add_remove_queue_dialog_link_ajax',
- ),
- '#submit' => array(
- 'installer_browser_add_remove_queue_dialog_link_submit',
- ),
- );
-
- return $form;
- }
-
- * AJAX submit handler for installer_browser_add_remove_queue_dialog_link().
- */
- function installer_browser_add_remove_queue_dialog_link_ajax($form, &$form_state) {
- $commands = array();
-
- $commands[] = ajax_command_replace('.installer-browser-install-queue', installer_browser_get_install_list());
-
- $commands[] = ajax_command_replace('#add-to-queue-link-' . $form_state['project_name'], installer_browser_add_remove_queue_link($form_state['project_name']));
-
- $form_html = backdrop_render($form);
- $commands[] = ajax_command_replace('.installer-browser-add-remove-queue-dialog-link', $form_html);
- return array('#type' => 'ajax', '#commands' => $commands);
- }
-
- * Submit handler for installer_browser_add_remove_queue_dialog_link().
- */
- function installer_browser_add_remove_queue_dialog_link_submit($form, &$form_state) {
-
- $form_state['redirect'] = installer_browser_install_queue_callback('form', $form_state['op'], $form_state['project_name']);
-
-
- if ($form_state['op'] == 'add') {
- $form_state['op'] = 'remove';
- $form_state['title'] = t('Remove from Installation queue');
- }
- else {
- $form_state['op'] = 'add';
- $form_state['title'] = t('Add to Installation queue');
- }
- $form_state['rebuild'] = TRUE;
- }
-
- *
- * Checks if PHP zip extension loaded on webserver.
- */
- function installer_browser_check_zip_loaded() {
- $zip_loaded = array_key_exists('zip', archiver_get_info());
- if (!$zip_loaded) {
- backdrop_set_message(t('The Zip PHP extension is not loaded on your server. You will not be able to download any projects using Project Installer until this is fixed.'), 'warning', FALSE);
- }
- return $zip_loaded;
- }