admin-plugins.php 8.35 KB
Newer Older
Scott committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	Description: Controller for admin page listing plugins and showing their options


	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	More about this license: http://www.question2answer.org/license.php
*/

Scott committed
22
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
23
	header('Location: ../../../');
Scott committed
24 25
	exit;
}
Scott committed
26

Scott committed
27
require_once QA_INCLUDE_DIR . 'app/admin.php';
Scott committed
28 29


Scott committed
30
// Check admin privileges
Scott committed
31

Scott committed
32 33
if (!qa_admin_check_privileges($qa_content))
	return $qa_content;
Scott committed
34

Scott committed
35
// Prepare content for theme
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

$qa_content = qa_content_prepare();

$qa_content['title'] = qa_lang_html('admin/admin_title') . ' - ' . qa_lang_html('admin/plugins_title');

$qa_content['error'] = qa_admin_page_error();

$qa_content['script_rel'][] = 'qa-content/qa-admin.js?' . QA_VERSION;


$pluginManager = new Q2A_Plugin_PluginManager();
$pluginManager->cleanRemovedPlugins();

$enabledPlugins = $pluginManager->getEnabledPlugins();
$fileSystemPlugins = $pluginManager->getFilesystemPlugins();

$pluginHashes = $pluginManager->getHashesForPlugins($fileSystemPlugins);

$showpluginforms = true;
if (qa_is_http_post()) {
	if (!qa_check_form_security_code('admin/plugins', qa_post_text('qa_form_security_code'))) {
		$qa_content['error'] = qa_lang_html('misc/form_security_reload');
		$showpluginforms = false;
	} else {
		if (qa_clicked('dosave')) {
			$enabledPluginHashes = qa_post_text('enabled_plugins_hashes');
			$enabledPluginHashesArray = explode(';', $enabledPluginHashes);
			$pluginDirectories = array_keys(array_intersect($pluginHashes, $enabledPluginHashesArray));
			$pluginManager->setEnabledPlugins($pluginDirectories);

			qa_redirect('admin/plugins');
		}
	}
}
Scott committed
70

Scott committed
71
// Map modules with options to their containing plugins
Scott committed
72

Scott committed
73
$pluginoptionmodules = array();
Scott committed
74

Scott committed
75 76
$tables = qa_db_list_tables();
$moduletypes = qa_list_module_types();
Scott committed
77

Scott committed
78 79
foreach ($moduletypes as $type) {
	$modules = qa_list_modules($type);
Scott committed
80

Scott committed
81 82
	foreach ($modules as $name) {
		$module = qa_load_module($type, $name);
Scott committed
83

Scott committed
84 85 86 87 88 89 90
		if (method_exists($module, 'admin_form')) {
			$info = qa_get_module_info($type, $name);
			$dir = rtrim($info['directory'], '/');
			$pluginoptionmodules[$dir][] = array(
				'type' => $type,
				'name' => $name,
			);
Scott committed
91 92
		}
	}
Scott committed
93
}
Scott committed
94

Scott committed
95 96
foreach ($moduletypes as $type) {
	$modules = qa_load_modules_with($type, 'init_queries');
Scott committed
97

Scott committed
98 99
	foreach ($modules as $name => $module) {
		$queries = $module->init_queries($tables);
Scott committed
100

Scott committed
101 102 103
		if (!empty($queries)) {
			if (qa_is_http_post())
				qa_redirect('install');
Scott committed
104

Scott committed
105 106 107 108 109 110 111
			else {
				$qa_content['error'] = strtr(qa_lang_html('admin/module_x_database_init'), array(
					'^1' => qa_html($name),
					'^2' => qa_html($type),
					'^3' => '<a href="' . qa_path_html('install') . '">',
					'^4' => '</a>',
				));
Scott committed
112 113 114
			}
		}
	}
Scott committed
115 116 117
}


118
if (!empty($fileSystemPlugins)) {
Scott committed
119 120 121
	$metadataUtil = new Q2A_Util_Metadata();
	$sortedPluginFiles = array();

122
	foreach ($fileSystemPlugins as $pluginDirectory) {
123 124
		$pluginDirectoryPath = QA_PLUGIN_DIR . $pluginDirectory;
		$metadata = $metadataUtil->fetchFromAddonPath($pluginDirectoryPath);
Scott committed
125
		if (empty($metadata)) {
126
			$pluginFile = $pluginDirectoryPath . '/qa-plugin.php';
127

Scott committed
128
			// limit plugin parsing to first 8kB
129
			$contents = file_get_contents($pluginFile, false, null, 0, 8192);
Scott committed
130
			$metadata = qa_addon_metadata($contents, 'Plugin');
131
		}
132

Scott committed
133 134 135
		$metadata['name'] = isset($metadata['name']) && !empty($metadata['name'])
			? qa_html($metadata['name'])
			: qa_lang_html('admin/unnamed_plugin');
136
		$sortedPluginFiles[$pluginDirectory] = $metadata;
Scott committed
137
	}
138

Scott committed
139
	qa_sort_by($sortedPluginFiles, 'name');
Scott committed
140

Scott committed
141
	$pluginIndex = -1;
142
	foreach ($sortedPluginFiles as $pluginDirectory => $metadata) {
Scott committed
143
		$pluginIndex++;
144 145 146

		$pluginDirectoryPath = QA_PLUGIN_DIR . $pluginDirectory;
		$hash = $pluginHashes[$pluginDirectory];
Scott committed
147
		$showthisform = $showpluginforms && (qa_get('show') == $hash);
Scott committed
148

Scott committed
149
		$namehtml = $metadata['name'];
Scott committed
150

Scott committed
151 152
		if (isset($metadata['uri']) && strlen($metadata['uri']))
			$namehtml = '<a href="' . qa_html($metadata['uri']) . '">' . $namehtml . '</a>';
Scott committed
153

Scott committed
154
		$namehtml = '<b>' . $namehtml . '</b>';
Scott committed
155

Scott committed
156 157 158
		$metaver = isset($metadata['version']) && strlen($metadata['version']);
		if ($metaver)
			$namehtml .= ' v' . qa_html($metadata['version']);
Scott committed
159

Scott committed
160 161
		if (isset($metadata['author']) && strlen($metadata['author'])) {
			$authorhtml = qa_html($metadata['author']);
Scott committed
162

Scott committed
163 164
			if (isset($metadata['author_uri']) && strlen($metadata['author_uri']))
				$authorhtml = '<a href="' . qa_html($metadata['author_uri']) . '">' . $authorhtml . '</a>';
Scott committed
165

Scott committed
166
			$authorhtml = qa_lang_html_sub('main/by_x', $authorhtml);
Scott committed
167

Scott committed
168 169
		} else
			$authorhtml = '';
Scott committed
170

Scott committed
171
		if ($metaver && isset($metadata['update_uri']) && strlen($metadata['update_uri'])) {
172
			$elementid = 'version_check_' . md5($pluginDirectory);
Scott committed
173

Scott committed
174
			$updatehtml = '(<span id="' . $elementid . '">...</span>)';
Scott committed
175

Scott committed
176
			$qa_content['script_onloads'][] = array(
177
				"qa_version_check(" . qa_js($metadata['update_uri']) . ", " . qa_js($metadata['version'], true) . ", " . qa_js($elementid) . ", false);"
Scott committed
178
			);
Scott committed
179 180
		}
		else
Scott committed
181 182 183 184 185 186
			$updatehtml = '';

		if (isset($metadata['description']))
			$deschtml = qa_html($metadata['description']);
		else
			$deschtml = '';
Scott committed
187

188 189 190 191
		if (isset($pluginoptionmodules[$pluginDirectoryPath]) && !$showthisform) {
			$deschtml .= (strlen($deschtml) ? ' - ' : '') . '<a href="' . qa_admin_plugin_options_path($pluginDirectory) . '">' .
				qa_lang_html('admin/options') . '</a>';
		}
Scott committed
192

193
		$allowDisable = isset($metadata['load_order']) && $metadata['load_order'] === 'after_db_init';
194
		$beforeDbInit = isset($metadata['load_order']) && $metadata['load_order'] === 'before_db_init';
195 196
		$enabled = $beforeDbInit || !$allowDisable || in_array($pluginDirectory, $enabledPlugins);

197 198 199
		$pluginhtml = $namehtml . ' ' . $authorhtml . ' ' . $updatehtml . '<br>';
		$pluginhtml .= $deschtml . (strlen($deschtml) > 0 ? '<br>' : '');
		$pluginhtml .= '<small style="color:#666">' . qa_html($pluginDirectoryPath) . '/</small>';
Scott committed
200

Scott committed
201 202 203
		if (qa_qa_version_below(@$metadata['min_q2a']))
			$pluginhtml = '<s style="color:#999">'.$pluginhtml.'</s><br><span style="color:#f00">'.
				qa_lang_html_sub('admin/requires_q2a_version', qa_html($metadata['min_q2a'])).'</span>';
Scott committed
204

Scott committed
205 206 207
		elseif (qa_php_version_below(@$metadata['min_php']))
			$pluginhtml = '<s style="color:#999">'.$pluginhtml.'</s><br><span style="color:#f00">'.
				qa_lang_html_sub('admin/requires_php_version', qa_html($metadata['min_php'])).'</span>';
Scott committed
208

Scott committed
209 210
		$qa_content['form_plugin_'.$pluginIndex] = array(
			'tags' => 'id="'.qa_html($hash).'"',
Scott committed
211 212
			'style' => 'tall',
			'fields' => array(
213 214 215 216
				array(
					'type' => 'checkbox',
					'label' => qa_lang_html('admin/enabled'),
					'value' => $enabled,
217
					'tags' => sprintf('id="plugin_enabled_%s"%s', $hash, $allowDisable ? '' : ' disabled'),
218
				),
Scott committed
219 220 221
				array(
					'type' => 'custom',
					'html' => $pluginhtml,
222
				),
Scott committed
223 224
			),
		);
Scott committed
225

226 227
		if ($showthisform && isset($pluginoptionmodules[$pluginDirectoryPath])) {
			foreach ($pluginoptionmodules[$pluginDirectoryPath] as $pluginoptionmodule) {
Scott committed
228 229
				$type = $pluginoptionmodule['type'];
				$name = $pluginoptionmodule['name'];
Scott committed
230

Scott committed
231
				$module = qa_load_module($type, $name);
Scott committed
232

Scott committed
233
				$form = $module->admin_form($qa_content);
Scott committed
234

Scott committed
235
				if (!isset($form['tags']))
236
					$form['tags'] = 'method="post" action="' . qa_admin_plugin_options_path($pluginDirectory) . '"';
Scott committed
237

Scott committed
238 239
				if (!isset($form['style']))
					$form['style'] = 'tall';
Scott committed
240

Scott committed
241
				$form['boxed'] = true;
Scott committed
242

Scott committed
243
				$form['hidden']['qa_form_security_code'] = qa_get_form_security_code('admin/plugins');
Scott committed
244

Scott committed
245 246 247 248 249 250 251 252
				$qa_content['form_plugin_options'] = $form;
			}
		}
	}
}

$qa_content['navigation']['sub'] = qa_admin_sub_navigation();

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
$qa_content['form'] = array(
	'tags' => 'method="post" action="' . qa_self_html() . '" name="plugins_form" onsubmit="qa_get_enabled_plugins_hashes(); return true;"',

	'style' => 'wide',

	'buttons' => array(
		'dosave' => array(
			'tags' => 'name="dosave"',
			'label' => qa_lang_html('admin/save_options_button'),
		),
	),

	'hidden' => array(
		'qa_form_security_code' => qa_get_form_security_code('admin/plugins'),
		'enabled_plugins_hashes' => '',
	),
);

Scott committed
271 272

return $qa_content;