<?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
 */

/**
 * cfBackendContentpermsAction Class
 *
 * Action class to manage the content access permissions within the system.
 *
 * @package clearFusionCMS
 */
class cfBackendContentpermsAction extends cfBackendControllerAction {
	/**
	 * Process the action.
	 */
	function process() {
		$this->testPermission('cfContent.permissions');
		$this->breadcrumbTrail->addCrumb(__('Content Permissions', 'cfBackend'), $this->assemble('', 'contentperms'));

		$acMgr = new flAcMgr($this->db);

		// Get the perm that we're currently editing
		$edPerm = $this->request->getParam('*');
		$delPerm = '';
		$addPerm = false;
		if($edPerm !== null && count($edPerm) == 1 && preg_match('/^[a-z0-9]+\.[a-z0-9]+$/', $edPerm[0]))
			$edPerm = $edPerm[0];
		else if($edPerm !== null && count($edPerm) == 2 && preg_match('/^[a-z0-9]+\.[a-z0-9]+$/', $edPerm[0]) && $edPerm[1] == 'delete') {
			$delPerm = $edPerm[0];
			$edPerm = '';
		}
		else if($edPerm !== null && count($edPerm) == 1 && $edPerm[0] == 'add') {
			$addPerm = true;
			$edPerm = '';
		}
		else
			$edPerm = '';

		$edmsg = $this->session->flashGet('cfManagerOpSuccess', '');

		if($addPerm) {
			// Build form for adding perms
			$formAdd = new flForm($this->request, 'addpermform', $this->assemble('', 'contentperms', array('add')), true);

			$newName = new flFormElementText($formAdd, 'newname');
			$newName->setLabel(__('Permission Short Name', 'cfBackend'))
				->setDescription(__('Short name for the permission, used to access the permission via code.', 'cfBackend'))
				->setRequired()
				->addValidator(new flFormValidatorRequired())
				->addValidator(new flFormValidatorMinLength(3))
				->addValidator(new flFormValidatorMaxLength(24))
				->addValidator(new flFormValidatorRegex('/^[a-z0-9]+$/', __('The permission name can only contain letters a-z and 0-9.', 'cfBackend')));

			$newDesc = new flFormElementText($formAdd, 'newdesc');
			$newDesc->setLabel(__('Permission Description', 'cfBackend'))
				->setRequired()
				->addValidator(new flFormValidatorRequired())
				->addValidator(new flFormValidatorMinLength(3))
				->addValidator(new flFormValidatorMaxLength(255));

			$type = new flFormElementSelect($formAdd, 'permtype', '1', array(
				'0' => __('Edit Permission', 'cfBackend'),
				'1' => __('Access Permission', 'cfBackend')
			));
			$type->setLabel(__('Permission Type', 'cfBackend'));

			$addSubmit = new flFormElementSubmit($formAdd, 'addperm');
			$addSubmit->setCaption(__('Add Permission', 'cfBackend'))->setCSS('primary');

			$formAdd->focusElement($newName);

			$formAdd->groupElements('submit', array($addSubmit), new flFormDecoratorList(new flFormDecoratorDl()));

			if($formAdd->isSubmitted() && $formAdd->isValid()) {
				if($type->getValue())
					$acMgr->createPermissionGroup('content', __noop('Content Access'));
				else
					$acMgr->createPermissionGroup('ctntedt', __noop('Content Edit'));

				if($acMgr->createPermission($pname = ($type->getValue() ? 'content.' : 'ctntedt.') . $newName->getValue(), $newDesc->getValue())) {
					cfCtntPermAudit::created($pname, $newDesc->getValue());
					$this->session->flashSet('cfManagerOpSuccess', $this->alertMessage('Success', __('The new content permission has been added.', 'cfBackend')));
					$this->response->redirectTo($this->assemble('', 'contentperms', array($pname), true));
				}
				else
					$edmsg = $this->alertMessage('Error', __('Unable to create new permission.', 'cfBackend'));
			}

			$content = $this->renderBlock(__('Add Permission', 'cfBackend'), $formAdd->render($this->tpl->getCodeBuffer()), '', $edmsg);
		}
		else if($edPerm) {
			$oldDesc = $acMgr->getPermissionDisplayName($edPerm);

			// Build the edit form
			$form = new flForm($this->request, 'edpermform', $this->assemble('', 'contentperms', array($edPerm)), true, null, new flFormDecoratorList(new flFormDecoratorDl()));

			$name = new flFormElementText($form, 'name', $edPerm);
			$name->setLabel(__('Permission Short Name', 'cfBackend'))
				->setRequired()
				->setDisabled()
				->setReadonly();

			$desc = new flFormElementText($form, 'desc', $oldDesc);
			$desc->setLabel(__('Permission Description', 'cfBackend'))
				->setRequired()
				->addValidator(new flFormValidatorRequired())
				->addValidator(new flFormValidatorMinLength(3))
				->addValidator(new flFormValidatorMaxLength(255));

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

			$delPermSub = new flFormElementSubmit($form, 'delete');
			$delPermSub->setCaption(__('Delete Permission', 'cfBackend'))
				->setCSS('danger');

			$form->focusElement($name);

			$form->groupElements('submit', array($submit, $delPermSub), new flFormDecoratorList(new flFormDecoratorDl()));

			if($form->isSubmitted() && $form->isValid()) {
				if($acMgr->updatePermission($edPerm, $desc->getValue())) {
					cfCtntPermAudit::update($edPerm, $desc->getValue(), $oldDesc);
					$edmsg = $this->alertMessage('Success', __('The access permission description has been updated.', 'cfBackend'));
				}
				else
					$edmsg = $this->alertMessage('Error', __('Unable to update the permission description, please try again.', 'cfBackend'));

				if($delPermSub->getValue())
					$this->response->redirectTo($this->assemble('', 'contentperms', array($edPerm, 'delete')));
			}
		}
		else if($delPerm) {
			$desc = $acMgr->getPermissionDisplayName($delPerm);

			$form = new flForm($this->request, 'delpermform', $this->assemble('', 'contentperms', array($delPerm, 'delete')), true);

			$name = new flFormElementText($form, 'permname', $desc);
			$name->setLabel(__('Delete Permission', 'cfBackend'))
				->setDisabled()
				->setReadonly();

			$delSubmit = new flFormElementSubmit($form, 'deleteperm');
			$delSubmit->setCaption(__('Permanently Delete Permission', 'cfBackend'))
				->setCSS('danger')
				->setDescription($this->alertMessage('Warning', __('All content that requires this permission in order to be viewed or edited will no longer be accessible. This action cannot be undone!', 'cfBackend')));

			if($form->isSubmitted() && $form->isValid()) {
				$acMgr->deletePermission($delPerm);
				cfCtntPermAudit::delete($delPerm, $name->getValue(), $desc);
				$this->response->redirectTo($this->assemble('', 'contentperms', array(), true));
			}
		}

		$topTree = new flWidgetTreeView('cfContentPermissionTreeView');

		$perms = $acMgr->getPermissionsInGroup('content');
		if(count($perms)) {
			$accessTree = new flWidgetTreeView();
			foreach($perms as $perm => $name) {
				$accessTree->addNode(new flWidgetTreeLinkNode($name, $this->assemble('', 'contentperms', array($perm))))
					->setLastNodeActive($perm == $edPerm || $perm == $delPerm);
			}
			$topTree->addNode(new flWidgetTreeChildNode(__('Access Permissions', 'cfBackend'), $accessTree, true));
		}
		else
			$topTree->addNode(new flWidgetTreeNode(__('Access Permissions', 'cfBackend'), flWidgetTreeNode::CONTAINER));

		$perms = $acMgr->getPermissionsInGroup('ctntedt');
		if(count($perms)) {
			$editTree = new flWidgetTreeView();
			foreach($perms as $perm => $name) {
				$editTree->addNode(new flWidgetTreeLinkNode($name, $this->assemble('', 'contentperms', array($perm))))
					->setLastNodeActive($perm == $edPerm || $perm == $delPerm);
			}
			$topTree->addNode(new flWidgetTreeChildNode(__('Edit Permissions', 'cfBackend'), $editTree, true));
		}
		else
			$topTree->addNode(new flWidgetTreeNode(__('Edit Permissions', 'cfBackend'), flWidgetTreeNode::CONTAINER));

		$tree = $topTree->render($this->tpl->getCodeBuffer());

		if($edPerm || $delPerm) {
			if(($content = $this->lockObject('cfContentPerms', $edPerm ? $edPerm : $delPerm, true)) === true)
				$content = $this->renderBlock($edPerm ? __('Edit Permission Description', 'cfBackend') : __('Delete Permission', 'cfBackend'), $form->render($this->tpl->getCodeBuffer()), '', $edmsg);
		}
		else if(!$addPerm)
			$content = '';

		// Build floating action menu
		$fam = new flWidgetFloatingActionMenu();
		$fam->setCSS('[[+css]]')
			->addAction('add', __('Add Permission', 'cfBackend'), $this->assemble('', 'contentperms', array('add')));

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

		$this->renderPage(__('Content Permissions', 'cfBackend'), $content, $this->renderBlock(__('Content Permissions', 'cfBackend'), $tree));
	}
}
