<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package clearFusionCMS
 * @copyright Copyright (c) 2012 - 2016 clearFusionCMS. All rights reserved.
 * @link http://clearfusioncms.com
 */

/**
 * cfModuleSettingsInterface Interface
 *
 * Interface for module settings classes.
 *
 * @package clearFusionCMS
 */
interface cfModuleSettingsInterface {
	/**
	 * Get a list of settings groups.
	 *
	 * @return array Array of setting groups, name => func name
	 */
	function getSettingsGroups();
}

/**
 * cfBackendSettingsAction Class
 *
 * Action class to list and edit settings.
 *
 * @package clearFusionCMS
 */
class cfBackendSettingsAction extends cfBackendControllerAction {
	/**
	 * Process the action.
	 */
	function process() {
		$this->testPermission('core.settings');
		$this->breadcrumbTrail->addCrumb(__('Settings', 'cfBackend'), $this->assemble('', 'settings'));

		// Get the selected item if any
		$selected = $this->request->getParam('*');
		if($selected !== null && count($selected) == 2 && preg_match('/^[a-z0-9]+$/', $selected[0]) && preg_match('/^[a-z0-9]+$/', $selected[1])) {
			$module = $selected[0];
			$action = $selected[1];
		}
		else
			$module = $action = null;

		// Build the settings tree form the modules
		$mm = new flModuleMgr($this->db);
		$modules = $mm->getInstalled('Settings');
		$activeModule = $activeGroups = null;
		$settingsTree = new flWidgetTreeView('cfSettingsTreeView');

		$hasNodes = false;
		foreach($modules as $n => $v) {
			try {
				class_exists($className = "{$n}Settings");
				$settings = new $className($this->tpl);
				$grps = $settings->getSettingsGroups();
				if(count($grps)) {
					$hasNodes = true;
					if($n == $module) {
						$activeModule = $settings;
						$activeGroups = $grps;
					}
					$st = new flWidgetTreeView();
					foreach($grps as $name => $grp) {
						$st->addNode(new flWidgetTreeLinkNode($name, $this->assemble('', 'settings', array($n, $grp)), flWidgetTreeNode::PREF))
							->setLastNodeActive($n === $module && $grp === $action);
					}

					$info = $mm->getInfo($n);
					$settingsTree->addNode(new flWidgetTreeChildNode(__($info->name == 'clearFusionCMS' ? 'CMS' : $info->name, $n . 'Backend'), $st, false));
				}
			} catch(flExceptionLoadClass $e) {
			}
		}

		// Get the active setting if any
		$content = $title = $result = '';
		if($activeModule !== null) {
			$actionFn = "{$action}Setting";

			// Build the settings form
			$form = new flForm($this->request, 'settingform', $this->assemble('', 'settings', array($selected[0], $selected[1])), true, null, new flFormDecoratorList(new flFormDecoratorDl()));
			$res = $activeModule->$actionFn($form, $this->db);
			if($res === true) {
				$info = $mm->getInfo($module);
				$t = array_flip($activeGroups);
				$result = $this->alertMessage('Success', __('The settings have been updated.', 'cfBackend'));
			}
			else if($res === false)
				$result = $this->alertMessage('Error', __('Unable to update the settings.', 'cfBackend'));

			$content = $form->render($this->tpl->getCodeBuffer());

			// Make the titles
			foreach($activeGroups as $n => $m) {
				if($m == $selected[1]) {
					$info = $mm->getInfo($selected[0]);
					$title = __($info->name == 'clearFusionCMS' ? 'CMS' : $info->name, $module . 'Backend') . " / $n";
					$this->breadcrumbTrail->addCrumb(__($info->name == 'clearFusionCMS' ? 'CMS' : $info->name, $module . 'Backend') . " : $n", null);
					break;
				}
			}
		}

		$this->renderPage(__('Settings', 'cfBackend'),
			empty($content) ? '' : $this->renderBlock($title, $content, '', $result),
			$this->renderBlock(__('Settings', 'cfBackend'), $settingsTree->render($this->tpl->getCodeBuffer()))
		);
	}
}
