1<?php
2/*
3 * Gallery - a web based photo album viewer and editor
4 * Copyright (C) 2000-2008 Bharat Mediratta
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21GalleryCoreApi::requireOnce('modules/core/classes/GalleryRepository.class');
22GalleryCoreApi::requireOnce(
23    'modules/core/classes/AdminRepositoryDownloadAndInstallController.class');
24
25/**
26 * This controller will handle an administration request for a module
27 * @package GalleryCore
28 * @subpackage UserInterface
29 * @author Jozef Selesi <selesi at gmail dot com>
30 * @version $Revision: 17580 $
31 */
32class AdminRepositoryController extends AdminRepositoryDownloadAndInstallController {
33
34    /**
35     * Get the repositories, but allow tests to inject their own version.
36     * @see GalleryRepository::getRepositories
37     * @access private
38     */
39    function _getRepositories() {
40	if (isset($this->_repositories)) {
41	    return array(null, $this->_repositories);
42	}
43	return GalleryRepository::getRepositories();
44    }
45
46    /**
47     * @see GalleryController::handleRequest
48     */
49    function handleRequest($form) {
50	global $gallery;
51
52	$ret = GalleryCoreApi::assertUserIsSiteAdministrator();
53	if ($ret) {
54	    return array($ret, null);
55	}
56
57	$status = $error = array();
58	if (isset($form['action']['update'])) {
59	    /**
60	     * @todo refactor this repository update such that it can be used from Language
61	     * manager.
62	     */
63	    foreach (array('module', 'theme') as $pluginType) {
64		list ($ret, $pluginStatus[$pluginType]) =
65		    GalleryCoreApi::fetchPluginStatus($pluginType, true);
66		if ($ret) {
67		    return array($ret, null);
68		}
69	    }
70
71	    if (empty($form['repositories'])) {
72		$form['repositories'] = array('released' => 1);
73	    }
74
75	    /* filter the form values through our list of valid keys to avoid exploits */
76	    $data = array();
77	    foreach (array('released', 'experimental', 'community') as $key) {
78		if (isset($form['repositories'][$key])) {
79		    $data[$key] = 1;
80		}
81	    }
82	    $ret = GalleryCoreApi::setPluginParameter(
83		'module', 'core', 'core.repositories', serialize($data));
84	    if ($ret) {
85		return array($ret, null);
86	    }
87
88	    /* Remove the default repositories from the data cache */
89	    GalleryRepository::clearRepositoryCache();
90	    list ($ret, $repositories) = $this->_getRepositories();
91	    if ($ret) {
92		return array($ret, null);
93	    }
94
95	    $templateAdapter =& $gallery->getTemplateAdapter();
96
97	    $templateAdapter->registerTrailerCallback(
98		array($this, 'updatePluginStatus'),
99		array($pluginStatus, $repositories,
100		      array('view' => 'core.SiteAdmin', 'subView' => 'core.AdminRepository')));
101	    $delegate['view'] = 'core.ProgressBar';
102	} else if (isset($form['action']['upgradeAll'])) {
103	    list ($ret, $repositories) = $this->_getRepositories();
104	    if ($ret) {
105		return array($ret, null);
106	    }
107
108	    /* Get list of upgradeable packages in repository */
109	    foreach ($repositories as $source => $repository) {
110		list ($ret, $tmp) = $repository->getAllUpgradeablePackages();
111		if ($ret) {
112		    return array($ret, null);
113		}
114
115		if (!empty($tmp)) {
116		    $packages[$source] = $tmp;
117		}
118	    }
119
120	    if (empty($packages)) {
121		$status['noUpgradeAvailable'] = 1;
122	    } else {
123		/* Start upgrade process and show progress bar. */
124		GalleryCoreApi::requireOnce('modules/core/AdminRepositoryDownload.inc');
125		$templateAdapter =& $gallery->getTemplateAdapter();
126		$templateAdapter->registerTrailerCallback(
127		    array($this, 'performDownloadAndInstallation'),
128		    array($packages, $repositories));
129		$delegate['view'] = 'core.ProgressBar';
130	    }
131	}
132
133	if (!empty($redirect)) {
134	    $results['redirect'] = $redirect;
135	} else {
136	    if (empty($delegate)) {
137		$results['delegate']['view'] = 'core.SiteAdmin';
138		$results['delegate']['subView'] = 'core.AdminRepository';
139	    } else {
140		$results['delegate'] = $delegate;
141	    }
142	}
143	$results['status'] = $status;
144	$results['error'] = $error;
145
146	return array(null, $results);
147    }
148
149}
150
151/**
152 * This view will show all repository-related features.
153 */
154class AdminRepositoryView extends GalleryView {
155
156    /**
157     * @see GalleryView::loadTemplate
158     */
159    function loadTemplate(&$template, &$form) {
160	global $gallery;
161	$platform =& $gallery->getPlatform();
162	$session =& $gallery->getSession();
163
164	$ret = GalleryCoreApi::assertUserIsSiteAdministrator();
165	if ($ret) {
166	    return array($ret, null);
167	}
168
169	$AdminRepository = array();
170
171	/* Init repository. */
172	list ($ret, $repositories, $repositoryInitErrorCount) =
173	    GalleryRepository::getRepositories();
174	if ($ret) {
175	    return array($ret, null);
176	}
177
178	if ($form['formName'] != 'AdminRepository') {
179	    /* Set some defaults */
180	    $form['formName'] = 'AdminRepository';
181	    list ($ret, $sources) =
182		GalleryCoreApi::getPluginParameter('module', 'core', 'core.repositories');
183	    if ($ret) {
184		return array($ret, null);
185	    }
186	    @$form['repositories'] = unserialize($sources);
187	}
188	if (empty($form['repositories'])) {
189	    $form['repositories'] = array('released' => 1);
190	}
191
192	/* Check if incompatible plugins should be shown. */
193	$coreApis = array();
194	$showIncompatible = GalleryUtilities::getRequestVariables('showIncompatible');
195	if ($showIncompatible == 'true') {
196	    list ($coreApiVersion, $themeApiVersion, $moduleApiVersion) =
197		GalleryUtilities::getRequestVariables('coreApi', 'themeApi', 'moduleApi');
198	    if (empty($coreApiVersion) || empty($themeApiVersion) || empty($moduleApiVersion)) {
199		return array(GalleryCoreApi::error(
200				 ERROR_BAD_PARAMETER, __FILE__, __LINE__,
201				 "[$coreApiVersion] [$themeApiVersion] [$moduleApiVersion]"),
202			     null);
203	    }
204	    $coreApis['core'] = explode('.', $coreApiVersion);
205	    $coreApis['module'] = explode('.', $moduleApiVersion);
206	    $coreApis['theme'] = explode('.', $themeApiVersion);
207	    $AdminRepository['showIncompatible'] = 1;
208	}
209
210	$AdminRepository['OS'] = strncasecmp(PHP_OS, 'win', 3) ? 'unix' : 'winnt';
211
212	$AdminRepository['isCoreUpgradeAvailable'] = false;
213	$AdminRepository['upgradesAvailable'] = false;
214	foreach ($repositories as $source => $repository) {
215	    if (!$repository->localIndexExists()) {
216		break;
217	    }
218
219	    /**
220	     * Note: this merges modules and themes instead of treating themes separately.
221	     * @todo: separate themes into their own group, like we do elsewhere
222	     */
223	    foreach (array('module', 'theme') as $pluginType) {
224		/* Get list of plugins to show in the repository browser. */
225		list ($ret, $browseData[$pluginType]) = $repository->getRepositoryPluginList(
226		    $pluginType, $showIncompatible, $coreApis);
227		if ($ret) {
228		    return array($ret, null);
229		}
230
231		foreach ($browseData[$pluginType] as $pluginId => $browseInfo) {
232		    if (empty($AdminRepository['browseData'][$pluginId]) ||
233			(empty($AdminRepository['browseData'][$pluginId]['action']) &&
234			 !empty($browseInfo['action'])) ||
235			version_compare(
236			    $browseInfo['repositoryVersion'],
237			    $AdminRepository['browseData'][$pluginId]['repositoryVersion'],
238			    '>')) {
239			$AdminRepository['browseData'][$pluginId] = $browseInfo;
240		    }
241		}
242	    }
243
244	    /* Get local index meta data. */
245	    list ($ret, $indexMetaData) = $repository->getIndexMetaData();
246	    if ($ret) {
247		return array($ret, null);
248	    }
249
250	    list ($ret, $message) = GalleryRepository::translateRepositoryName($source);
251	    if ($ret) {
252		return array($ret, null);
253	    }
254
255	    $AdminRepository['indexMetaData'][$source] =
256		array_merge(array('name' => $message), $indexMetaData);
257
258	    list ($ret, $tmp) = $repository->getAllUpgradeablePackages();
259	    if ($ret) {
260		return array($ret, null);
261	    }
262
263	    if (!empty($tmp)) {
264		$AdminRepository['upgradesAvailable'] = true;
265	    }
266
267	    /* Get core upgrade info. */
268	    if ($source == 'released') {
269		list ($ret, $AdminRepository['isCoreUpgradeAvailable'], $apiVersions) =
270		    $repository->isCoreUpgradeAvailable();
271		if ($ret) {
272		    return array($ret, null);
273		}
274		if ($AdminRepository['isCoreUpgradeAvailable']) {
275		    $AdminRepository['latestCoreApiVersion'] = $apiVersions['core'];
276		    $AdminRepository['latestThemeApiVersion'] = $apiVersions['theme'];
277		    $AdminRepository['latestModuleApiVersion'] = $apiVersions['module'];
278		}
279	    }
280	}
281
282	if (!empty($AdminRepository['browseData'])) {
283	    GalleryCoreApi::requireOnce('modules/core/AdminPlugins.inc');
284	    uasort($AdminRepository['browseData'], array($this, 'pluginSort'));
285	}
286
287	$AdminRepository['basePath'] = dirname(dirname(dirname(__FILE__)));
288	$AdminRepository['writeable'] = array(
289	    'modules' => $platform->is_writeable($AdminRepository['basePath'] . '/modules'),
290	    'themes' => $platform->is_writeable($AdminRepository['basePath'] .'/themes'));
291	$AdminRepository['authToken'] = $session->getAuthToken();
292
293	/* Render the HTML body */
294	$template->setVariable('AdminRepository', $AdminRepository);
295	$template->setVariable('controller', 'core.AdminRepository');
296
297	if ($repositoryInitErrorCount) {
298	    $status =& $template->getVariableByReference('status');
299	    $status['error']['repositoryInitErrorCount'] = $repositoryInitErrorCount;
300	}
301
302	$template->javascript('lib/yui/utilities.js');
303	$template->javascript('lib/yui/container-min.js');
304	$template->javascript('modules/core/templates/AdminRepository.js');
305	return array(null, array('body' => 'modules/core/templates/AdminRepository.tpl'));
306    }
307
308    /**
309     * @todo: combine this with AdminPluginsView::pluginSort
310     */
311    function pluginSort($a, $b) {
312	if (($cmp = strcmp($a['groupLabel'], $b['groupLabel'])) == 0) {
313	    $cmp = strcmp($a['name'], $b['name']);
314	}
315	return $cmp;
316    }
317}
318?>
319