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

/**
 * searchInstall Class
 *
 * Installer class for search module.
 *
 * @package clearFusionCMS\module\search
 */
class searchInstall implements cfInstallInterface, cfInstallUpdInterface {
	/**
	 * The last error message.
	 *
	 * @var string
	 */
	protected $lastError = '';

	/**
	 * Return the last error.
	 *
	 * @return string The last error string.
	 */
	function getLastError() {
		return $this->lastError;
	}

	/**
	 * Install the module.
	 *
	 * @param flDb The database object to use.
	 * @return bool true if installed; else false.
	 */
	function install($db) {
		// Add search for all sites
		$siteMgr = new cfSiteManager($db);
		$sites = $siteMgr->listSites();
		foreach($sites as $site => $n) {
			$searchManager = new flSearchManager($db, "cf_search_{$site}");
			$searchManager->initializeTables($siteMgr->getLocale($site));
			$searchManager->addField('title');
			$searchManager->addField('content');

			$db->insert("cf_search_{$site}_config", array('keyname' => 'cfFieldDesc', 'value' => serialize(
				array('title' => 'Document Title', 'subtitle' => 'Document Subtitle', 'content' => 'Document Content')
			)));

			$db->insert("cf_search_{$site}_config", array('keyname' => 'cfFieldData', 'value' => serialize(
				array('title' => array('title', 'subtitle'), 'content' => array('content'))
			)));

			$db->insert("cf_search_{$site}_config", array('keyname' => 'cfTagField', 'value' => serialize(
				array()
			)));
		}

		// Add events
		$em = clearFusionCMS::getEventManager();
		$em->addListener('system.beforeSearchReindex', 'searchEvents', 'onBeforeSearchReindex');
		$em->addListener('system.searchIndex', 'searchEvents', 'onSearchIndex');
		$em->addListener('system.searchDeindex', 'searchEvents', 'onSearchDeindex');
		$em->addListener('system.searchDelete', 'searchEvents', 'onSearchDelete');
		$em->addListener('system.searchMove', 'searchEvents', 'onSearchMove');
		$em->addListener('system.moduleRemoved', 'searchEvents', 'onModuleRemoved');

		// Permissions
		$ac = new flAcMgr($db);
		$ac->createPermissionGroup('cfSearch', __noop('Search'), 'searchBackend'); // 6000
		$ac->createPermission('cfSearch.settings', __noop('Can edit search settings.'), 6000, 'searchBackend');

		return true;
	}

	/**
	 * Uninstall the module.
	 *
	 * @param flDb The database object to use.
	 * @return bool true if uninstalled; else false.
	 */
	function uninstall($db) {
		// Remove events
		$em = clearFusionCMS::getEventManager();
		$em->removeListener('system.beforeSearchReindex', 'searchEvents', 'onBeforeSearchReindex');
		$em->removeListener('system.searchIndex', 'searchEvents', 'onSearchIndex');
		$em->removeListener('system.searchDeindex', 'searchEvents', 'onSearchDeindex');
		$em->removeListener('system.searchDelete', 'searchEvents', 'onSearchDelete');
		$em->removeListener('system.searchMove', 'searchEvents', 'onSearchMove');
		$em->removeListener('system.moduleRemoved', 'searchEvents', 'onModuleRemoved');

		// Drop tables for all sites
		$siteMgr = new cfSiteManager($db);
		$sites = $siteMgr->listSites();
		foreach($sites as $site => $n) {
			$searchManager = new flSearchManager($db, "cf_search_{$site}");
			$searchManager->deleteTables();
		}

		// Remove permissions
		$ac = new flAcMgr($db);
		$ac->deletePermissionGroup('cfSearch');

		return true;
	}

	/**
	 * Upgrade the module.
	 *
	 * @param flDb The database object to use.
	 * @param string $installedVer The installed version.
	 * @return bool true if upgraded; else false.
	 */
	function upgrade($db, $installedVer) {
		if(version_compare($installedVer, '1.1.0') < 0) {
			// Permissions
			$ac = new flAcMgr($db);
			$ac->createPermissionGroup('cfSearch', __noop('Search'), 'searchBackend'); // 6000
			$ac->createPermission('cfSearch.settings', __noop('Can edit search settings.'), 6000, 'searchBackend');
		}

		if(version_compare($installedVer, '1.2.0') < 0) {
			$ac = new flAcMgr($db);
			$ac->updatePermissionGroup('cfSearch', __noop('Search'), 'searchBackend');
			$ac->updatePermission('cfSearch.settings', __noop('Can edit search settings.'), 'searchBackend');
		}

		if(version_compare($installedVer, '1.4.0') < 0) {
			$siteMgr = new cfSiteManager($db);
			$sites = $siteMgr->listSites();
			foreach($sites as $site => $n) {
				$db->query("ALTER TABLE cf_search_{$site}_docs ADD lftrgtset LINESTRING NOT NULL AFTER rgt");
				$db->query("UPDATE cf_search_{$site}_docs SET lftrgtset=LineString(Point(-1,lft), Point(1, rgt))");
				$db->query("CREATE SPATIAL INDEX lftrgtset ON cf_search_{$site}_docs (lftrgtset)");
			}
		}

		return true;
	}

	/**
	 * Create a new site.
	 *
	 * @param flDb $db The database object.
	 * @param string $site The short name of the site.
	 * @return bool true if the site was created; else false.
	 */
	function createSite($db, $site) {
		$siteMgr = new cfSiteManager($db);
		$searchManager = new flSearchManager($db, "cf_search_{$site}");
		$searchManager->initializeTables($siteMgr->getLocale($site));
		$searchManager->addField('title');
		$searchManager->addField('content');

		$db->insert("cf_search_{$site}_config", array('keyname' => 'cfFieldDesc', 'value' => serialize(
			array('title' => 'Document Title', 'content' => 'Document Content')
		)));

		$db->insert("cf_search_{$site}_config", array('keyname' => 'cfFieldData', 'value' => serialize(
			array('title' => array('title'), 'content' => array('content'))
		)));

		$db->insert("cf_search_{$site}_config", array('keyname' => 'cfTagField', 'value' => serialize(
			array()
		)));

		return true;
	}

	/**
	 * Delete a site.
	 *
	 * @param flDb $db The database object.
	 * @param string $site The name of the site to delete.
	 * @return bool true if the site was deleted; else false.
	 */
	function deleteSite($db, $site) {
		$searchManager = new flSearchManager($db, "cf_search_{$site}");
		$searchManager->deleteTables();

		return true;
	}

	/**
	 * Update a site.
	 *
	 * @param flDb $db The database object.
	 * @param string $site The name of the site to update.
	 * @return bool true if the site was updated; else false.
	 */
	function updateSite($db, $site) {
		$siteMgr = new cfSiteManager($db);
		$searchManager = new flSearchManager($db, "cf_search_{$site}");
		$searchManager->setLang($siteMgr->getLocale($site));

		return true;
	}
}
