<?php
/**
* @version	$Id: categories_item.php 14719 2011-11-01 16:12:02Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class CategoriesItem extends kDBItem
	{
		/**
		 * Builds parent path for this category
		 *
		 * @return string
		 * @access public
		 */
		public function buildParentPath()
		{
			$parent_id = $this->GetDBField('ParentId');

			if ( $parent_id == 0 ) {
				$parent_path = '|';
			}
			else {
				$sql = 'SELECT ParentPath
						FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . ' WHERE
						CategoryId = ' . $parent_id;
				$parent_path = $this->Conn->GetOne($sql);
			}

			return $parent_path . $this->GetID() . '|';
		}

		/**
		 * replace not allowed symbols with "_" chars + remove duplicate "_" chars in result
		 *
		 * @param string $string
		 * @return string
		 * @access protected
		 */
		protected function stripDisallowed($string)
		{
			$filenames_helper =& $this->Application->recallObject('FilenamesHelper');
			/* @var $filenames_helper kFilenamesHelper */

			$string = $filenames_helper->replaceSequences($string);

			return $this->checkAutoFilename($string);
		}

		public function checkFilename()
		{
			if ( $this->GetDBField('AutomaticFilename') ) {
				// filename will be generated from scratch, don't check anything here
				return;
			}
			elseif ( $this->GetDBField('Type') == PAGE_TYPE_TEMPLATE ) {
				// system page with AutomaticFilename checkbox unchecked -> compatibility with Proj-CMS <= 4.3.9 (when "/" were allowed in Filename)
				return;
			}

			$filename = $this->GetDBField('Filename');
			$this->SetDBField('Filename', $this->stripDisallowed($filename));
		}

		protected function checkAutoFilename($filename)
		{
			static $current_theme = null;

			if (!$filename) {
				return $filename;
			}

			if (!isset($current_theme)) {
				$themes_helper =& $this->Application->recallObject('ThemesHelper');
				/* @var $themes_helper kThemesHelper */

				$current_theme = (int)$themes_helper->getCurrentThemeId();
			}

			$escape_char = $this->Application->ConfigValue('FilenameSpecialCharReplacement');

			$item_id = !$this->GetID() ? 0 : $this->GetID();
			$item_theme = $this->GetDBField('ThemeId');

			if (!$item_theme) {
				// user creates category manually, that's why ThemeId = 0 -> use current admin theme instead
				$item_theme = $current_theme;
			}

			$unique_clause = '(Filename = %s) AND (ThemeId = ' . $item_theme . ' OR ThemeId = 0) AND (ParentId = ' . $this->GetDBField('ParentId') . ')';

			$sql_mask = '	SELECT ' . $this->IDField . '
							FROM %s
							WHERE ' . sprintf($unique_clause, $this->Conn->qstr($filename));

			// check temp table
			$sql_temp = sprintf($sql_mask, $this->TableName);
			$found_temp_ids = $this->Conn->GetCol($sql_temp);

			// check live table
			$sql_live = sprintf($sql_mask, $this->Application->GetLiveName($this->TableName));
			$found_live_ids = $this->Conn->GetCol($sql_live);

			$found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) );

			$has_page = preg_match('/(.*)_([\d]+)([a-z]*)$/', $filename, $rets);
			$duplicates_found = (count($found_item_ids) > 1) || ($found_item_ids && $found_item_ids[0] != $item_id);

			if ($duplicates_found || $has_page) {// other category has same filename as ours OR we have filename, that ends with _number
				$append = $duplicates_found ? $escape_char . 'a' : '';
				if ($has_page) {
					$filename = $rets[1].'_'.$rets[2];
					$append = $rets[3] ? $rets[3] : $escape_char . 'a';
				}

				// check live & temp table
				$sql_temp = '	SELECT ' . $this->IDField . '
								FROM ' . $this->TableName . '
								WHERE ' . $unique_clause . ' AND (' . $this->IDField . ' != ' . $item_id . ')';

				$sql_live = '	SELECT ' . $this->IDField . '
								FROM ' . $this->Application->GetLiveName($this->TableName) . '
								WHERE ' . $unique_clause . ' AND (' . $this->IDField . ' != ' . $item_id . ')';

				while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 ||
				$this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 )
				{
					if (mb_substr($append, -1) == 'z') $append .= 'a';
					$append = mb_substr($append, 0, mb_strlen($append) - 1) . chr( ord( mb_substr($append, -1) ) + 1 );
				}

				return $filename . $append;
			}

			return $filename;
		}

		/**
		 * Generate item's filename based on it's title field value
		 *
		 * @return void
		 * @access public
		 */
		public function generateFilename()
		{
			if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) {
				return ;
			}

			$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
			/* @var $ml_formatter kMultiLanguage */

			$name = $this->stripDisallowed( $this->GetDBField($ml_formatter->LangFieldName('Name', true)) );

			if ( $name != $this->GetDBField('Filename') ) {
				$this->SetDBField('Filename', $name);
			}
		}

		/**
		 * Allows to detect if root category being edited
		 *
		 * @return int
		 * @access public
		 */
		public function IsRoot()
		{
			return $this->Application->RecallVar('IsRootCategory_'.$this->Application->GetVar('m_wid'));
		}


		/**
		 * Sets correct name to Home category while editing it
		 *
		 * @return bool
		 * @access public
		 */
		public function IsNewItem()
		{
			if ( $this->IsRoot() && $this->Prefix == 'c' ) {
				$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
				$category_name = $this->Application->Phrase(($this->Application->isAdmin ? 'la_' : 'lu_') . 'rootcategory_name');
				$this->SetDBField($title_field, $category_name);

				return false;
			}

			return parent::IsNewItem();
		}

		/**
		 * Sets new name for item in case if it is being copied in same table
		 *
		 * @param array $master Table data from TempHandler
		 * @param int $foreign_key ForeignKey value to filter name check query by
		 * @param string $title_field FieldName to alter, by default - TitleField of the prefix
		 * @param string $format sprintf-style format of renaming pattern, by default Copy %1$s of %2$s which makes it Copy [Number] of Original Name
		 * @access public
		 */
		public function NameCopy($master=null, $foreign_key=null, $title_field=null, $format='Copy %1$s of %2$s')
		{
			if (!isset($title_field)) {
				$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
				if (!$title_field || isset($this->CalculatedFields[$title_field]) ) return;
			}

			$new_name = $this->GetDBField($title_field);
			$cat_id = $this->Application->GetVar('m_cat_id');
			$this->SetDBField('ParentId', $cat_id);
			$original_checked = false;
			do {
				if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) {
					$new_name = 'Copy '.($regs[1]+1).' of '.$regs[2];
				}
				elseif ($original_checked) {
					$new_name = 'Copy of '.$new_name;
				}

				// if we are cloning in temp table this will look for names in temp table,
				// since object' TableName contains correct TableName (for temp also!)
				// if we are cloning live - look in live
				$query = '	SELECT ' . $title_field . '
							FROM ' . $this->TableName . '
							WHERE ParentId = ' . (int)$cat_id . ' AND ' . $title_field . ' = ' . $this->Conn->qstr($new_name);

				$foreign_key_field = getArrayValue($master, 'ForeignKey');
				$foreign_key_field = is_array($foreign_key_field) ? $foreign_key_field[ $master['ParentPrefix'] ] : $foreign_key_field;

				if ($foreign_key_field && isset($foreign_key)) {
					$query .= ' AND '.$foreign_key_field.' = '.$foreign_key;
				}

				$res = $this->Conn->GetOne($query);

				/*// if not found in live table, check in temp table if applicable
				if ($res === false && $object->Special == 'temp') {
					$query = 'SELECT '.$name_field.' FROM '.$this->GetTempName($master['TableName']).'
										WHERE '.$name_field.' = '.$this->Conn->qstr($new_name);
					$res = $this->Conn->GetOne($query);
				}*/

				$original_checked = true;
			} while ($res !== false);
			$this->SetDBField($title_field, $new_name);
		}
	}