<?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\module\property
 * @copyright Copyright (c) 2016 - 2017 clearFusionCMS. All rights reserved.
 * @link http://clearfusioncms.com
 */

/**
 * propertyBackendRgnfieldsAction Class
 *
 * Backend controller action for managing region fields.
 *
 * @package clearFusionCMS\module\property
 */
class propertyBackendRgnfieldsAction extends cfBackendControllerAction {
	/**
	 * Render the page.
	 *
	 * @param string $id The current item.
	 * @param string $content The page content.
	 */
	function renderAdminPage($id, $content) {

		$rootTree = new flWidgetTreeView();

		// Build tree
		$tree = new flWidgetTreeView();
		$results = $this->db->query('SELECT rgnfldid,fieldname FROM cf_property_rgnflds_' . clearFusionCMS::getSite() . ' ORDER BY disporder');
		while($row = $results->fetch()) {
			$tree->addNode(new flWidgetTreeLinkNode($row['fieldname'] . " [$row[rgnfldid]]", $this->assemble('property', 'rgnfields', array('edit', strtolower($row['rgnfldid']))), flWidgetTreeNode::NODE))
				->setLastNodeActive($id == $row['rgnfldid']);
		}

		$rootTree->addNode($results->numRows() ? new flWidgetTreeChildNode(__('Region Fields', 'propertyBackend'), $tree, null) : new flWidgetTreeNode(__('Region Fields', 'propertyBackend'), flWidgetTreeNode::CONTAINER));

		// Create the toolbar
		$fam = new flWidgetFloatingActionMenu();
		$fam->setCSS('[[+css]]');

		$fam->addAction('add', __('Add Field', 'propertyBackend'), $this->assemble('property', 'rgnfields', array('add')));
		$this->tpl->registerChunk('fam', $fam->render());

		// Render the page
		$this->renderPage(__('Region Fields', 'propertyBackend'), $content, $this->renderBlock('', $rootTree->render($this->tpl->getCodeBuffer())));
	}

	/**
	 * Process the request
	 */
	function process() {
		$this->testPermission('cfProperty.fields');
		$this->breadcrumbTrail->addCrumb(__('Region Fields', 'propertyBackend'), $this->assemble('property', 'rgnfields'));

		$currid = '';
		$content = '';
		$msg = $this->session->flashGet('cfManagerOpSuccess', '');

		// Build routes
		$addRoute = new flRouterRoute('add');
		$editRoute = new flRouterRoute('edit/:id', array(), array('id' => '\d+'));
		$deleteRoute = new flRouterRoute('delete/:id', array(), array('id' => '\d+'));

		// If adding
		if($params = $addRoute->match($this->request->getParam('*', array()))) {
			$this->breadcrumbTrail->addCrumb(__('Add Field', 'propertyBackend'), $this->assemble('property', 'rgnfields', array('add')));

			$form = new flForm($this->request, 'addfieldform', $this->assemble('property', 'rgnfields', array('add')), true);
			$form->setCSS('metaSSubmit');

			$name = new flFormElementText($form, 'name');
			$name->setLabel(__('Field Name', 'propertyBackend'))
				->setRequired()
				->addValidator(new flFormValidatorRequired())
				->addValidator(new flFormValidatorMaxLength(255));

			$order = new flFormElementNumber($form, 'order', null, null, 0);
			$order->setLabel(__('Display Order', 'propertyBackend'))
				->setRequired()
				->addValidator(new flFormValidatorRequired())
				->setDescription(__('The order to display fields in, the lower the number the sooner the field is shown.', 'propertyBackend'));

			$fldtype = new flFormElementSelect($form, 'fldtype', '', array(
				0 => __('WYSIWYG HTML Editor (Small)', 'propertyBackend'),
				1 => __('WYSIWYG HTML Editor', 'propertyBackend'),
				2 => __('Text', 'propertyBackend'),
				3 => __('HTML Editor (Small)', 'propertyBackend'),
				4 => __('HTML Editor', 'propertyBackend')
			));
			$fldtype->setLabel(__('Field Type', 'propertyBackend'));

			$el = cfEditor::getAvailable(true);
			$editor = new flFormElementSelect($form, 'editor', '', $el);
			$editor->setLabel(__('Editor for Field', 'propertyBackend'));

			$submit = new flFormElementSubmit($form, 'addfield');
			$submit->setCaption(__('Add Field', 'propertyBackend'))->setCSS('primary');

			$form->groupElements('info', array($name, $order, $fldtype, $editor))
				->setGroupLabel('info', __('Field Information', 'propertyBackend'))
				->groupElements('submit', array($submit), new flFormDecoratorList(new flFormDecoratorDl()));

			$form->focusElement($name);

			// Capture ctrl+s for save, implement select all/none, check user really wants to leave page
			$this->tpl->getCodeBuffer()->bufferHeadJS('system/app/js/cfMetaS.js');
			$this->confirmLeavePage();

			if($form->isSubmitted() && $form->isValid()) {
				// Create
				if($this->db->insert('cf_property_rgnflds_' . clearFusionCMS::getSite(), array(
					'fieldname' => $name->getValue(),
					'disporder' => $order->getValue(),
					'fldtype' => $fldtype->getValue(),
					'editor' => $editor->getValue(),
					'snippet' => cfEditor::getFilter($editor->getValue())
				))) {
					$currid = $this->db->insertID();
					propertyAudit::createRgnField($currid, $name->getValue());

					// Add field to product table
					$this->db->query('ALTER TABLE cf_property_region_' . clearFusionCMS::getSite() . " ADD COLUMN content{$currid} MEDIUMTEXT NOT NULL");

					$this->cache->flush();

					$this->session->flashSet('cfManagerOpSuccess', $this->alertMessage('Success', __('The new field has been added.', 'propertyBackend')));
					$this->response->redirectTo($this->assemble('property', 'rgnfields', array('edit', $currid), true));
				}
				else
					$msg = $this->alertMessage('Error', __('Unable to add the new field, please try again.', 'propertyBackend'));
			}

			$content = $this->renderBlock(__('Add Field', 'propertyBackend'), $form->render($this->tpl->getCodeBuffer()), '', $msg);
		}
		// If editing
		else if($params = $editRoute->match($this->request->getParam('*', array()))) {
			$currid = $params['id'];
			if(($content = $this->lockObject('property.rgnfields', $params['id'])) === true) {
				$this->breadcrumbTrail->addCrumb(__('Edit Field', 'propertyBackend'), $this->assemble('property', 'rgnfields', array('edit', $currid)));

				$data = $this->db->fetchRow('SELECT * FROM cf_property_rgnflds_' . clearFusionCMS::getSite() .' WHERE rgnfldid=?', $currid);

				$form = new flForm($this->request, 'editfieldform', $this->assemble('property', 'rgnfields', array('edit', $currid)), true);
				$form->setCSS('metaSSubmit');

				$name = new flFormElementText($form, 'name', $data['fieldname']);
				$name->setLabel(__('Field Name', 'propertyBackend'))
					->setRequired()
					->addValidator(new flFormValidatorRequired())
					->addValidator(new flFormValidatorMaxLength(255));

				$order = new flFormElementNumber($form, 'order', null, null, $data['disporder']);
				$order->setLabel(__('Display Order', 'propertyBackend'))
					->setRequired()
					->addValidator(new flFormValidatorRequired())
					->setDescription(__('The order to display fields in, the lower the number the sooner the field is shown.', 'propertyBackend'));

				$fldtype = new flFormElementSelect($form, 'fldtype', $data['fldtype'], array(
					0 => __('WYSIWYG HTML Editor (Small)', 'propertyBackend'),
					1 => __('WYSIWYG HTML Editor', 'propertyBackend'),
					2 => __('Text', 'propertyBackend'),
					3 => __('HTML Editor (Small)', 'propertyBackend'),
					4 => __('HTML Editor', 'propertyBackend')
				));
				$fldtype->setLabel(__('Field Type', 'propertyBackend'));

				$el = cfEditor::getAvailable(true);
				$editor = new flFormElementSelect($form, 'editor', $data['editor'], $el);
				$editor->setLabel(__('Editor for Field', 'propertyBackend'));

				$submit = new flFormElementSubmit($form, 'updatefield');
				$submit->setCaption(__('Update Field', 'propertyBackend'))->setCSS('primary');

				$delete = new flFormElementSubmit($form, 'deletefield');
				$delete->setCaption(__('Delete Field', 'propertyBackend'))
					->setCSS('danger');

				$form->groupElements('info', array($name, $order, $fldtype, $editor))
					->setGroupLabel('info', __('Field Information', 'propertyBackend'))
					->groupElements('submit', array($submit, $delete), new flFormDecoratorList(new flFormDecoratorDl()));

				$form->focusElement($name);

				// Capture ctrl+s for save, implement select all/none, check user really wants to leave page
				$this->tpl->getCodeBuffer()->bufferHeadJS('system/app/js/cfMetaS.js');
				$this->confirmLeavePage();

				if($form->isSubmitted() && $form->isValid()) {

					if($delete->getValue())
						$this->response->redirectTo($this->assemble('property', 'rgnfields', array('delete', $currid), true));

					// Update the field
					if($this->db->update('cf_property_rgnflds_' . clearFusionCMS::getSite(), array(
						'fieldname' => $name->getValue(),
						'disporder' => $order->getValue(),
						'fldtype' => $fldtype->getValue(),
						'editor' => $editor->getValue(),
						'snippet' => cfEditor::getFilter($editor->getValue())
					), 'rgnfldid=?', $currid)) {
						propertyAudit::updateRgnField($currid, $name->getValue(), $data);

						$this->cache->flush();

						$this->session->flashSet('cfManagerOpSuccess', $this->alertMessage('Success', __('The field information has been updated.', 'propertyBackend')));
						$this->response->redirectTo($this->assemble('property', 'rgnfields', array('edit', $currid), true));
					}
					else
						$msg = $this->alertMessage('Error', __('Unable to update the field information, please try again.', 'propertyBackend'));
				}

				$content = $this->renderBlock(sprintf(__('Edit Field: %s', 'propertyBackend'), $data['fieldname']), $form->render($this->tpl->getCodeBuffer()), '', $msg);
			}
		}
		// If deleting
		else if($params = $deleteRoute->match($this->request->getParam('*', array()))) {
			$currid = $params['id'];
			if(($content = $this->lockObject('property.rgnfields', $params['id'])) === true) {
				$this->breadcrumbTrail->addCrumb(__('Delete Field', 'propertyBackend'), $this->assemble('property', 'rgnfields', array('delete', $currid)));

				$data = $this->db->fetchRow('SELECT * FROM cf_property_rgnflds_' . clearFusionCMS::getSite() .' WHERE rgnfldid=?', $currid);

				$form = new flForm($this->request, 'delfieldform', $this->assemble('property', 'rgnfields', array('delete', $currid)), true);

				$name = new flFormElementText($form, 'name', $data['fieldname']);
				$name->setLabel(__('Field Name', 'propertyBackend'))
					->setDisabled()
					->setReadonly();

				$delSubmit = new flFormElementSubmit($form, 'deletefield');
				$delSubmit->setCaption(__('Permanently Delete The Field', 'propertyBackend'))
					->setCSS('danger')
					->setDescription($this->alertMessage('Warning', __('This action cannot be undone and will delete all data from all regions that use this field.', 'propertyBackend')));

				if($form->isSubmitted() && $form->isValid()) {
					propertyAudit::deleteRgnField($currid, $data);

					$this->db->delete('cf_property_rgnflds_' . clearFusionCMS::getSite(), 'rgnfldid=?', $currid);
					$this->db->query('ALTER TABLE cf_property_region_' . clearFusionCMS::getSite() . " DROP COLUMN content{$currid}");
					$this->db->query('OPTIMIZE TABLE cf_property_region_' . clearFusionCMS::getSite() . ', cf_property_rgnflds_' . clearFusionCMS::getSite());

					$this->cache->flush();
					$this->response->redirectTo($this->assemble('property', 'rgnfields', array(), true));
				}

				$content = $this->renderBlock(sprintf(__('Delete Field: %s', 'propertyBackend'), $data['fieldname']), $form->render($this->tpl->getCodeBuffer()), '', $msg);

			}
		}

		$this->renderAdminPage($currid, $content);
	}
}
