<?php

/**
 * Class file for user management action.
 *
 * 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
 */

/**
 * cfBackendAdduserAction Class
 *
 * Action class to add a new user to the system.
 *
 * @package clearFusionCMS
 */
class cfBackendAdduserAction extends cfBackendControllerAction {
	/**
	 * Process the action.
	 */
	function process() {
		$this->testPermission(array('core.users', 'core.usersadd'));
		$this->breadcrumbTrail->addCrumb(__('Users', 'cfBackend'), $this->assemble('', 'listusers'));
		$this->breadcrumbTrail->addCrumb(__('Add User', 'cfBackend'), $this->assemble('', 'adduser'));

		$acMgr = new flAcMgr($this->db);
		$uMgr = clearFusionCMS::getUserMgr();

		$form = new flForm($this->request, 'adduseform', $this->assemble('', 'adduser'), true);

		$username = new flFormElementText($form, 'username');
		$username->setLabel(__('Username', 'cfBackend'))
				->setDescription(__('The username for the new user.', 'cfBackend'))
				->setRequired()
				->autocompleteOff()
				->addValidator(new flFormValidatorRequired())
				->addValidator(new flFormValidatorMinLength(3))
				->addValidator(new flFormValidatorMaxLength(100))
				->addValidator(new flFormValidatorRegex('/^[0-9a-zA-Z._-]+$/', __('The username can only contain numbers, letters and the characters ., - and _.', 'cfBackend')))
				->addValidator(new cfValidatorUsername());

		$displayName = new flFormElementText($form, 'displayname');
		$displayName->setLabel(__('Display Name', 'cfBackend'))
			->setDescription(__('Optional display name for the user.', 'cfBackend'))
			->addValidator(new flFormValidatorMaxLength(32));

		$email = new flFormElementText($form, 'email');
		$email->setLabel(__('Email', 'cfBackend'))
				->setDescription(__('The email address for the user.', 'cfBackend'))
				->setRequired()
				->addValidator(new flFormValidatorRequired())
				->addValidator(new flFormValidatorMaxLength(200))
				->addValidator(new flFormValidatorEmail())
				->addValidator(new cfValidatorUserEmail());

		$password = new flFormElementPassword($form, 'password');
		$password->setLabel(__('Password', 'cfBackend'))
			->setRequired()
			->setDescription(__('The password must be at least 8 characters long.', 'cfBackend'))
			->addValidator(new flFormValidatorRequired())
			->addValidator(new flFormValidatorMinLength(8));

		$bio = new flFormElementTextArea($form, 'bio');
		$bio->setLabel(__('Bio', 'cfBackend'))
			->setRows(4)
			->addValidator(new flFormValidatorMaxLength(4096));

		$cfg = clearFusionCMS::getSiteConfig('cfSystemTZ');
		$tz = new flFormElementSelect($form, 'tz', $cfg->timezone, flDateTzMenu::get());
		$tz->setLabel(__('Timezone', 'cfBackend'));

		$form->groupElements('user', array($username, $displayName, $bio, $email, $password, $tz))
			->setGroupLabel('user', __('Account Details', 'cfBackend'));

		$userProfile = new cfUserProfile($this->db, null, cfUserProfile::ADMIN);
		$userProfile->addFields($form);

		$state = new flFormElementSelect($form, 'userstate', 'active', array('active' => __('Active', 'cfBackend'), 'disabled' => __('Disabled', 'cfBackend'), 'pending' => __('Pending', 'cfBackend')));
		$state->setLabel(__('Account State', 'cfBackend'));

		if($this->user->hasPermission('core.usersroles')) {
			$roles = new flFormElementChecklist($form, 'roles', array(), $roleList = $acMgr->getRoles());
			$roles->setLabel(__('Assign User Roles', 'cfBackend'));
			if($uMgr->remoteAuth())
				$roles->setDescription($this->alertMessage('Info', __('This system is using remote authentication therefore roles not available on the master will be ignored.', 'cfBackend')));
		}

		$submit = new flFormElementSubmit($form, 'adduser');
		$submit->setCaption(__('Create User', 'cfBackend'))->setCSS('primary');

		$form->groupElements('state', array($state))
			->setGroupLabel('state', __('Account State', 'cfBackend'));
		if(isset($roles)) {
			$form->groupElements('roles', array($roles))
				->setGroupLabel('roles', __('Role Assignment', 'cfBackend'));
		}
		$form->groupElements('submit', array($submit), new flFormDecoratorList(new flFormDecoratorDl()));

		$form->focusElement($username);

		$msg = '';
		if($form->isSubmitted() && $form->isValid()) {

			$dn = trim($displayName->getCleanedValue());
			if($dn == $username->getValue())
				$dn = '';

			// Create the user
			if(!($uid = $uMgr->create($username->getValue(), $email->getValue(), $password->getValue(), $state->getValue(), $tz->getValue(), $dn, $bio->getValue())))
				$username->forceError(__('Unable to create the user, please try again.', 'cfBackend'));
			else {
				// Set the users roles
				$auditRoles = [];
				if(isset($roles)) {
					$uMgr->setUserRoles($uid, $roles->getValue());

					foreach($roles->getValue() as $v) {
						$auditRoles[] = $roleList[$v];
					}
				}
				cfUserAudit::newUser($uid, $username->getValue(), $auditRoles);

				$userProfile->setUser($uid)->processFields($form);
				$this->session->flashSet('cfManagerOpSuccess', $this->alertMessage('Success', __('The user has been added to the system.', 'cfBackend')));
				$this->response->redirectTo($this->assemble('', 'edituser', array($uid), true));
			}
		}

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

		// Build the search form
		$data = $this->session->flashGet('cfManager.user.search');
		$this->session->flashKeep('cfManager.user.search');

		$this->confirmLeavePage();
		$form = new flForm($this->request, 'searchform', $this->assemble('', 'listusers'), true);

		$searchfor = new flFormElementText($form, 'searchfor', $data === null ? null : $data['for']);
		$searchfor->setLabel(__('Search For', 'cfBackend'));

		$searchin = new flFormElementChecklist($form, 'searchin', $data === null ? array('username', 'email') : $data['in'], array(
			'username' => __('Username', 'cfBackend'),
			'email' => __('Email', 'cfBackend')));
		$searchin->setLabel(__('Search In', 'cfBackend'))
			->addValidator(new flFormValidatorMinChecklist(1));

		$ac = new flAcMgr($this->db);
		$roleLim = new flFormElementSelect($form, 'rolelim', $data === null ? '' : $data['rolelim'], array(0 => __('[All Roles]', 'cfBackend')) + $ac->getRoles());
		$roleLim->setLabel(__('Limit to Role', 'cfBackend'));

		$exact = new flFormElementCheckbox($form, 'exact', $data === null ? 0 : $data['exact']);
		$exact->setLabel(__('Exact Match', 'cfBackend'));

		$submit = new flFormElementSubmit($form, 'Search');
		$submit->setCaption(__('Search', 'cfBackend'))->setCSS('primary');

		// Build floating action menu
		$fam = new flWidgetFloatingActionMenu();
		$fam->setCSS('[[+css]]');

		if($this->user->hasPermission('core.usersadd'))
			$fam->addAction('person_add', __('Add User', 'cfBackend'), $this->assemble('', 'adduser'));
		$fam->addAction('lock_open', __('Clear IP Blocks', 'cfBackend'), $this->assemble('', 'clearipblocks'));

		$this->tpl->registerChunk('fam', $fam->render());

		$this->renderPage(__('Add User', 'cfBackend'), $this->renderBlock(__('Add User', 'cfBackend'), $content, __('Complete the form below to create a new user in the system.', 'cfBackend'), $msg), $this->renderBlock('', $form->render($this->tpl->getCodeBuffer())));
	}
}
