admin-plugins.php 8.39 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 22
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	File: qa-include/qa-page-admin-plugins.php
	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
23 24 25 26
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
	header('Location: ../');
	exit;
}
Scott committed
27

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


Scott committed
31
// Check admin privileges
Scott committed
32

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

Scott committed
36
// Prepare content for theme
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 70

$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
71

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

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

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

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

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

Scott committed
85 86 87 88 89 90 91
		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
92 93
		}
	}
Scott committed
94
}
Scott committed
95

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

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

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

Scott committed
106 107 108 109 110 111 112
			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
113 114 115
			}
		}
	}
Scott committed
116 117 118
}


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Scott committed
202 203 204
		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
205

Scott committed
206 207 208
		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
209

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

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

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

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

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

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

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

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

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

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

254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
$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
272 273

return $qa_content;