<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjBaseOptions extends pjBase
{
	private function isValidCsrfToken()
	{
		$token = '';
		if ($this->_post->check('csrf_token')) {
			$token = $this->_post->toString('csrf_token');
		} elseif ($this->_get->check('csrf_token')) {
			$token = $this->_get->toString('csrf_token');
		} elseif (!empty($_SERVER['HTTP_X_CSRF_TOKEN'])) {
			$token = $_SERVER['HTTP_X_CSRF_TOKEN'];
		}
		return !empty($_SESSION['csrf_token']) && !empty($token) && hash_equals($_SESSION['csrf_token'], $token);
	}

	public function pjActionOptionsUpdate()
	{
		if (self::isPost())
		{
			if (!$this->isValidCsrfToken())
			{
				pjUtil::redirect($_SERVER['PHP_SELF'] . '?controller=pjBaseOptions&action=' . $this->_post->toString('next_action') . '&err=PBCSRF');
			}

			$pjBaseOptionModel = new pjBaseOptionModel();
			
			foreach ($this->_post->raw() as $key => $value)
			{
				if (preg_match('/value-(string|text|int|float|enum|bool|color)-(.*)/', $key) === 1)
				{
					list(, $type, $k) = explode("-", $key);
					if (!empty($k))
					{
						$_value = ':NULL';
						if ($value)
						{
							switch ($type)
							{
								case 'string':
								case 'text':
								case 'enum':
								case 'color':
									if (in_array($k, array('o_failed_login_send_sms_message', 'o_failed_login_send_email_message', 'o_secure_login_send_password_to_email_message', 'o_secure_login_send_password_to_sms_message')))
									{
										$_value = $this->_post->toI18n($key);
									}
									else
									{
										$_value = $this->_post->raw($key);
									}
									break;
								case 'int':
								case 'bool':
									$_value = $this->_post->toInt($key);
									break;
								case 'float':
									$_value = $this->_post->toFloat($key);
									break;
							}
						}
				
						$pjBaseOptionModel
							->reset()
							->where('foreign_id', $this->getForeignId())
							->where('`key`', $k)
							->limit(1)
							->modifyAll(array('value' => $_value));
					}
				}
			}
			$i18n_arr = $this->_post->toI18n('i18n');
			if (!empty($i18n_arr))
			{
				pjBaseMultiLangModel::factory()->updateMultiLang($i18n_arr, 1, 'pjBaseOption');
			}
			
			switch ($this->_post->toString('next_action'))
			{
				case 'pjActionIndex':
					$err = 'PBS01';
					break;
				case 'pjActionVisual':
					$err = 'PBS02';
					break;
				case 'pjActionEmailSettings':
					$err = 'PBS03';
					break;
				case 'pjActionLoginProtection':
					$err = 'PBS04';
					break;
				case 'pjActionCaptchaSpam':
					$err = 'PBS05';
					break;
				case 'pjActionApiKeys':
					$err = 'PBS06';
					break;
				case 'pjActionImages':
					$err = 'PBS01';
					break;
			}
			pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjBaseOptions&action=" . $this->_post->toString('next_action') . "&err=$err");
		}
	}

	public function pjActionRegenerateImages()
	{
		$this->setAjax(true);

		if (!pjAuth::factory('pjBaseOptions', 'pjActionImages')->hasAccess())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Access denied.'));
		}

		if (!self::isPost())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => 'Invalid request.'));
		}
		if (!$this->isValidCsrfToken())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 403, 'text' => 'Invalid CSRF token.'));
		}

		if (function_exists('session_write_close'))
		{
			@session_write_close();
		}

		$offset = $this->_post->check('offset') ? $this->_post->toInt('offset') : 0;
		$limit = $this->_post->check('limit') ? max(1, $this->_post->toInt('limit')) : 5;
		$result = $this->regenerateGalleryImagesFromSettings($offset, $limit);
		if (!empty($result['error']))
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 102, 'text' => $result['error']));
		}

		$nextOffset = $offset + $limit;
		$isDone = $nextOffset >= $result['total'];

		self::jsonResponse(array(
			'status' => 'OK',
			'code' => 200,
			'text' => $isDone
				? sprintf('Images regenerated successfully. %u image records updated, %u already current, %u skipped.', $result['updated'], $result['unchanged'], $result['skipped'])
				: sprintf('Regenerated %u of %u image records...', min($nextOffset, $result['total']), $result['total']),
			'updated' => $result['updated'],
			'unchanged' => $result['unchanged'],
			'skipped' => $result['skipped'],
			'total' => $result['total'],
			'next_offset' => $nextOffset,
			'done' => $isDone
		));
	}

	private function parseImageMode($value, $default='crop')
	{
		if (strpos($value, '::') !== false)
		{
			$parts = explode('::', $value);
			$value = end($parts);
		}

		return in_array($value, array('crop', 'resize'), true) ? $value : $default;
	}

	private function getConfiguredImageSizes()
	{
		$options = pjBaseOptionModel::factory()->getPairs($this->getForeignId());
		$getInt = function ($key, $fallback) use ($options) {
			return !empty($options[$key]) ? (int) $options[$key] : $fallback;
		};

		return array(
			'small' => array(
				'width' => $getInt('o_thumb_width', 90),
				'height' => $getInt('o_thumb_height', 68),
				'mode' => $this->parseImageMode(isset($options['o_thumb_crop']) ? $options['o_thumb_crop'] : 'crop', 'crop')
			),
			'medium' => array(
				'width' => $getInt('o_medium_width', 215),
				'height' => $getInt('o_medium_height', 161),
				'mode' => $this->parseImageMode(isset($options['o_medium_crop']) ? $options['o_medium_crop'] : 'crop', 'crop')
			),
			'large' => array(
				'width' => $getInt('o_large_width', 800),
				'height' => $getInt('o_large_height', 800),
				'mode' => $this->parseImageMode(isset($options['o_large_crop']) ? $options['o_large_crop'] : 'resize', 'resize')
			)
		);
	}

	private function getFullImagePath($path)
	{
		if (empty($path))
		{
			return null;
		}
		if (is_file($path))
		{
			return $path;
		}

		$fullPath = PJ_INSTALL_PATH . $path;
		return is_file($fullPath) ? $fullPath : null;
	}

	private function regenerateGalleryImagesFromSettings($offset=0, $limit=5)
	{
		if (!class_exists('pjGalleryModel') || !class_exists('pjImage'))
		{
			return array('total' => 0, 'updated' => 0, 'unchanged' => 0, 'skipped' => 0, 'error' => 'Gallery image module is not available.');
		}

		@ignore_user_abort(true);
		@set_time_limit(300);
		$sizes = $this->getConfiguredImageSizes();
		$total = (int) pjGalleryModel::factory()->findCount()->getData();
		$rows = pjGalleryModel::factory()
			->orderBy('t1.id ASC')
			->limit($limit, $offset)
			->findAll()
			->getData();

		if (empty($rows))
		{
			return array('total' => $total, 'updated' => 0, 'unchanged' => 0, 'skipped' => 0, 'error' => null);
		}

		$Image = new pjImage();
		if ($Image->getErrorCode() === 200)
		{
			return array('total' => $total, 'updated' => 0, 'unchanged' => 0, 'skipped' => count($rows), 'error' => 'GD image library is not available.');
		}

		$updated = 0;
		$unchanged = 0;
		$skipped = 0;
		foreach ($rows as $row)
		{
			$sourceFull = $this->getFullImagePath($row['source_path']);
			if ($sourceFull === null)
			{
				$skipped++;
				continue;
			}

			$data = array();
			$rowChanged = false;
			foreach ($sizes as $key => $settings)
			{
				if ($this->galleryImageMatchesSettings($row, $key, $settings))
				{
					continue;
				}

				$field = $key . '_path';
				$dstRel = !empty($row[$field]) ? $row[$field] : str_replace(PJ_UPLOAD_PATH . 'source/', PJ_UPLOAD_PATH . $key . '/', $row['source_path']);
				$dstFull = PJ_INSTALL_PATH . $dstRel;
				$dir = dirname($dstFull);
				if (!is_dir($dir))
				{
					@mkdir($dir, 0755, true);
				}

				$Image->loadImage($sourceFull);
				if ($settings['mode'] === 'crop')
				{
					$Image->resizeSmart($settings['width'], $settings['height']);
				} else {
					$Image->resizeToWidth($settings['width']);
				}

				if (!$Image->saveImage($dstFull))
				{
					continue;
				}

				$size = @getimagesize($dstFull);
				if ($size !== false)
				{
					$data[$key . '_path'] = $dstRel;
					$data[$key . '_size'] = filesize($dstFull);
					$data[$key . '_width'] = $size[0];
					$data[$key . '_height'] = $size[1];
					$rowChanged = true;
				}
			}

			if (!empty($data))
			{
				pjGalleryModel::factory()
					->reset()
					->where('id', $row['id'])
					->limit(1)
					->modifyAll($data);
				$updated++;
			} elseif (!$rowChanged) {
				$unchanged++;
			} else {
				$skipped++;
			}
		}

		return array('total' => $total, 'updated' => $updated, 'unchanged' => $unchanged, 'skipped' => $skipped, 'error' => null);
	}

	private function galleryImageMatchesSettings($row, $key, $settings)
	{
		if (empty($row[$key . '_path']) || empty($row[$key . '_width']) || empty($row[$key . '_height']))
		{
			return false;
		}

		if ($settings['mode'] === 'crop')
		{
			return (int) $row[$key . '_width'] === (int) $settings['width']
				&& (int) $row[$key . '_height'] === (int) $settings['height'];
		}

		return (int) $row[$key . '_width'] === (int) $settings['width'];
	}
	
	public function pjActionIndex()
	{
		if (!pjAuth::factory()->hasAccess())
		{
			$this->sendForbidden();
			return;
		}
		
		$arr = pjBaseOptionModel::factory()
			->where('t1.foreign_id', $this->getForeignId())
			->where('t1.tab_id', 1)
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
		
		$this->set('arr', $arr);
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}

	public function pjActionImages()
	{
		if (!pjAuth::factory('pjBaseOptions', 'pjActionIndex')->hasAccess())
		{
			$this->sendForbidden();
			return;
		}

		$imageOptionKeys = array(
			'o_thumb_width', 'o_thumb_height',
			'o_medium_width', 'o_medium_height',
			'o_default_width', 'o_default_height',
			'o_large_width', 'o_large_height',
			'o_thumb_crop', 'o_medium_crop',
			'o_default_crop', 'o_large_crop'
		);
		$arr = pjBaseOptionModel::factory()
			->where('t1.foreign_id', $this->getForeignId())
			->where('t1.tab_id', 1)
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
		$arr = array_values(array_filter($arr, function ($option) use ($imageOptionKeys) {
			return in_array($option['key'], $imageOptionKeys, true);
		}));

		$this->set('arr', $arr);
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}
	
	public function pjActionLoginProtection()
	{
		if (!pjAuth::factory()->hasAccess())
		{
			$this->sendForbidden();
			return;
		}

		$arr = pjBaseOptionModel::factory()
			->where('t1.foreign_id', $this->getForeignId())
			->whereIn('t1.tab_id', array(4, 5, 6, 7))
			->orderBy('t1.tab_id ASC, t1.order ASC, t1.key ASC')
			->findAll()
			->getData();
		$arr['i18n'] = pjBaseMultiLangModel::factory()->getMultiLang(1, 'pjBaseOption');

		$tmp = pjBaseOptionModel::factory()->reset()->where('foreign_id', $this->getForeignId())->whereIn('t1.tab_id', array(4, 5, 6, 7))->findAll()->getData();
		$o_arr = array();
		foreach ($tmp as $item)
		{
			$o_arr[$item['key']] = $item;
		}
		$this->set('o_arr', $o_arr);
		
		$this->set('arr', $arr);

		$this->setLocalesData();
		
		$this->set('has_access_password', pjAuth::factory('pjBaseOptions', 'pjActionLoginProtection')->hasAccess('password'));
		$this->set('has_access_secure_login', pjAuth::factory('pjBaseOptions', 'pjActionLoginProtection')->hasAccess('secure_login'));
		$this->set('has_access_failed_login', pjAuth::factory('pjBaseOptions', 'pjActionLoginProtection')->hasAccess('failed_login'));
		$this->set('has_access_forgot', pjAuth::factory('pjBaseOptions', 'pjActionLoginProtection')->hasAccess('forgot'));

		$this->appendJs('jquery.multilang.js', $this->getConstant('pjBase', 'PLUGIN_JS_PATH'), false, false);
		$this->appendJs('tinymce.min.js', PJ_THIRD_PARTY_PATH . 'tinymce/');
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}
	
	public function pjActionVisual()
	{
		if (!pjAuth::factory()->hasAccess())
		{
			$this->sendForbidden();
			return;
		}
		pjUtil::ensureAdminSidebarLogoOption($this->getForeignId());

		if (self::isPost() && $this->_post->toInt('pj_save_colors'))
		{
			pjAppController::validateCsrfToken();

			$foreignId = $this->getForeignId();
			$keys = array(
				'o_admin_primary',
				'o_admin_secondary',
				'o_admin_sidebar',
				'o_admin_success',
				'o_admin_warning',
				'o_admin_info',
				'o_admin_danger',
				'o_admin_table_density',
				'o_admin_brand_title',
				'o_admin_brand_subtitle',
				// Sidebar sub-colors
				'o_admin_sidebar_secondary',
				'o_admin_sidebar_active',
				'o_admin_sidebar_text',
				'o_admin_sidebar_muted',
				// Content area colors
				'o_admin_main_bg',
				'o_admin_card_bg2',
				'o_admin_table_border',
				'o_admin_input_border',
				'o_admin_main_text',
				// Accent colors
				'o_admin_accent',
				'o_admin_link_color',
				// Independent table colors
				'o_admin_table_header_bg',
				'o_admin_table_row_bg',
				'o_admin_table_row_alt',
				'o_admin_table_row_hover',
				'o_admin_table_text',
				// Independent typography & icons
				'o_admin_heading_text',
				'o_admin_muted_text',
				'o_admin_link_text',
				'o_admin_sidebar_icon',
				'o_admin_icon_color',
				// Topbar
				'o_admin_topbar_bg',
				// Form inputs
				'o_admin_input_bg',
				// Card / ibox border
				'o_admin_card_border',
			);

			foreach ($keys as $key)
			{
				if (!$this->_post->has($key))
				{
					continue;
				}
				$value = $this->_post->toString($key);
				if ($key === 'o_admin_table_density')
				{
					if (!in_array($value, array('compact', 'default', 'spacious'), true))
					{
						continue;
					}
				} elseif (in_array($key, array('o_admin_brand_title', 'o_admin_brand_subtitle'), true)) {
					$value = trim(strip_tags($value));
					if (strlen($value) > 80)
					{
						$value = substr($value, 0, 80);
					}
				} elseif (!preg_match('/^#[0-9a-fA-F]{6}$/', $value)) {
					continue;
				}

				$exists = (int) pjBaseOptionModel::factory()
					->where('t1.foreign_id', $foreignId)
					->where('t1.`key`', $key)
					->findCount()
					->getData();
				if ($exists > 0)
				{
					pjBaseOptionModel::factory()
						->where('foreign_id', $foreignId)
						->where('`key`', $key)
						->limit(1)
						->modifyAll(array('value' => $value));
				} else {
					pjBaseOptionModel::factory()->setAttributes(array(
						'foreign_id' => $foreignId,
						'key' => $key,
						'tab_id' => 2,
						'value' => $value,
						'label' => '',
						'type' => 'string',
						'order' => 0,
						'is_visible' => 0,
						'style' => NULL
					))->insert();
				}
			}

			pjUtil::redirect($_SERVER['PHP_SELF'] . '?controller=pjBaseOptions&action=pjActionVisual&err=PBS02');
			return;
		}

		$arr = pjBaseOptionModel::factory()
			->where('t1.foreign_id', $this->getForeignId())
			->where('t1.tab_id', 2)
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
		
		$this->set('arr', $arr);
		$this->set('adminPrimary',          isset($this->option_arr['o_admin_primary'])           ? $this->option_arr['o_admin_primary']           : '#F97316');
		$this->set('adminSecondary',        isset($this->option_arr['o_admin_secondary'])         ? $this->option_arr['o_admin_secondary']         : '#64748B');
		$this->set('adminSidebar',          isset($this->option_arr['o_admin_sidebar'])           ? $this->option_arr['o_admin_sidebar']           : '#FFFFFF');
		$this->set('adminSuccess',          isset($this->option_arr['o_admin_success'])           ? $this->option_arr['o_admin_success']           : '#10B981');
		$this->set('adminWarning',          isset($this->option_arr['o_admin_warning'])           ? $this->option_arr['o_admin_warning']           : '#F59E0B');
		$this->set('adminInfo',             isset($this->option_arr['o_admin_info'])              ? $this->option_arr['o_admin_info']              : '#3B6FA8');
		$this->set('adminDanger',           isset($this->option_arr['o_admin_danger'])            ? $this->option_arr['o_admin_danger']            : '#EF4444');
		$this->set('adminTableDensity',     isset($this->option_arr['o_admin_table_density'])     ? $this->option_arr['o_admin_table_density']     : 'default');
		$this->set('adminBrandTitle',       isset($this->option_arr['o_admin_brand_title'])       ? $this->option_arr['o_admin_brand_title']       : __('script_name', true));
		$this->set('adminBrandSubtitle',    isset($this->option_arr['o_admin_brand_subtitle'])    ? $this->option_arr['o_admin_brand_subtitle']    : 'by PHPJabbers.com');
		// Sidebar sub-colors
		$this->set('adminSidebarSecondary', isset($this->option_arr['o_admin_sidebar_secondary']) ? $this->option_arr['o_admin_sidebar_secondary'] : '#F8FAFC');
		$this->set('adminSidebarActive',    isset($this->option_arr['o_admin_sidebar_active'])    ? $this->option_arr['o_admin_sidebar_active']    : '#FFF1E6');
		$this->set('adminSidebarText',      isset($this->option_arr['o_admin_sidebar_text'])      ? $this->option_arr['o_admin_sidebar_text']      : '#64748B');
		$this->set('adminSidebarMuted',     isset($this->option_arr['o_admin_sidebar_muted'])     ? $this->option_arr['o_admin_sidebar_muted']     : '#94A3B8');
		// Content area colors
		$this->set('adminMainBg',           isset($this->option_arr['o_admin_main_bg'])           ? $this->option_arr['o_admin_main_bg']           : '#F8FAFC');
		$this->set('adminCardBg2',          isset($this->option_arr['o_admin_card_bg2'])          ? $this->option_arr['o_admin_card_bg2']          : '#FFFFFF');
		$this->set('adminTableBorder',      isset($this->option_arr['o_admin_table_border'])      ? $this->option_arr['o_admin_table_border']      : '#E2E8F0');
		$this->set('adminInputBorder',      isset($this->option_arr['o_admin_input_border'])      ? $this->option_arr['o_admin_input_border']      : '#E2E8F0');
		$this->set('adminMainText',         isset($this->option_arr['o_admin_main_text'])         ? $this->option_arr['o_admin_main_text']         : '#0F172A');
		// Accent colors
		$this->set('adminAccent',           isset($this->option_arr['o_admin_accent'])            ? $this->option_arr['o_admin_accent']            : '#F97316');
		$this->set('adminLinkColor',        isset($this->option_arr['o_admin_link_color'])        ? $this->option_arr['o_admin_link_color']        : '#F97316');
		// Independent table colors
		$this->set('adminTableHeaderBg',    isset($this->option_arr['o_admin_table_header_bg'])   ? $this->option_arr['o_admin_table_header_bg']   : '#F8FAFC');
		$this->set('adminTableRowBg',       isset($this->option_arr['o_admin_table_row_bg'])      ? $this->option_arr['o_admin_table_row_bg']      : '#FFFFFF');
		$this->set('adminTableRowAlt',      isset($this->option_arr['o_admin_table_row_alt'])     ? $this->option_arr['o_admin_table_row_alt']     : '#F8FAFC');
		$this->set('adminTableRowHover',    isset($this->option_arr['o_admin_table_row_hover'])   ? $this->option_arr['o_admin_table_row_hover']   : '#FFF7ED');
		$this->set('adminTableText',        isset($this->option_arr['o_admin_table_text'])        ? $this->option_arr['o_admin_table_text']        : '#334155');
		// Independent typography
		$this->set('adminHeadingText',      isset($this->option_arr['o_admin_heading_text'])      ? $this->option_arr['o_admin_heading_text']      : '#0F172A');
		$this->set('adminMutedText',        isset($this->option_arr['o_admin_muted_text'])        ? $this->option_arr['o_admin_muted_text']        : '#64748B');
		$this->set('adminLinkText',         isset($this->option_arr['o_admin_link_text'])         ? $this->option_arr['o_admin_link_text']         : '#F97316');
		$this->set('adminSidebarIcon',      isset($this->option_arr['o_admin_sidebar_icon'])      ? $this->option_arr['o_admin_sidebar_icon']      : '#64748B');
		$this->set('adminIconColor',        isset($this->option_arr['o_admin_icon_color'])        ? $this->option_arr['o_admin_icon_color']        : '#64748B');
		$this->set('adminTopbarBg',         isset($this->option_arr['o_admin_topbar_bg'])         ? $this->option_arr['o_admin_topbar_bg']         : '#FFFFFF');
		$this->set('adminInputBg',          isset($this->option_arr['o_admin_input_bg'])          ? $this->option_arr['o_admin_input_bg']          : '#FFFFFF');
		$this->set('adminCardBorder',       isset($this->option_arr['o_admin_card_border'])       ? $this->option_arr['o_admin_card_border']       : '#E2E8F0');
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}
	
	public function pjActionCaptchaSpam()
	{
		$auth = pjAuth::factory();
		if (!$auth->hasAccess())
		{
			$this->sendForbidden();
			return;
		}

		$pjBaseOptionModel = pjBaseOptionModel::factory();
		
		$arr = $pjBaseOptionModel
			->where('t1.foreign_id', $this->getForeignId())
			->where('t1.tab_id', 8)
			->orderBy('t1.order ASC')
			->findAll()
			->getDataPair('key');
		$arr['i18n'] = pjBaseMultiLangModel::factory()->getMultiLang(1, 'pjBaseOption');
		
		$this->setLocalesData();
		
		$this->set('_arr', $arr);

		$this->set('has_access_captcha', $auth->hasAccess('captcha'));
		$this->set('has_access_spam', $auth->hasAccess('spam'));

		$this->appendJs('jquery.multilang.js', $this->getConstant('pjBase', 'PLUGIN_JS_PATH'), false, false);
		$this->appendCss('css/select2.css', PJ_THIRD_PARTY_PATH . 'select2/');
		$this->appendJs('js/select2.min.js',  PJ_THIRD_PARTY_PATH . 'select2/');
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}
	
	public function pjActionUpdateTheme()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if (!self::isPost())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => 'HTTP method not allowed.'));
		}
		
		if (!$this->_post->has('theme'))
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 102, 'text' => 'Missing, empty or invalid parameters.'));
		}
		
		pjBaseOptionModel::factory()
			->where('foreign_id', $this->getForeignId())
			->where('`key`', 'o_base_theme')
			->limit(1)
			->modifyAll(array('value' => 'theme1|theme2|theme3::' . $this->_post->toString('theme')));
			
		self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'Theme has been changed.'));
	}
	
	public function pjActionEmailSettings()
	{
		if (!pjAuth::factory()->hasAccess())
		{
			$this->sendForbidden();
			return;
		}

		$arr = pjBaseOptionModel::factory()
			->where('t1.foreign_id', $this->getForeignId())
			->where('t1.tab_id', 3)
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
		
		$this->set('arr', $arr);
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}
	
	public function pjActionApiKeys()
	{
		if (!pjAuth::factory()->hasAccess())
		{
			$this->sendForbidden();
			return;
		}

		$arr = pjBaseOptionModel::factory()
			->where('t1.foreign_id', $this->getForeignId())
			->where('t1.tab_id', 10)
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
		
		$this->set('arr', $arr);
		$this->appendJs('pjBaseOptions.js', $this->getConst('PLUGIN_JS_PATH'));
	}
	
	public function pjActionAjaxSmtp()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => __('plugin_base_email_text_ARRAY_1', true)));
		}
		
		if (!self::isPost())
		{
		    self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => __('plugin_base_email_text_ARRAY_2', true)));
		}
		
		$post = array();
		foreach ($this->_post->raw() as $key => $value)
		{
			if (!preg_match('/value-(string|text|int|float|enum|bool|color)-(.*)/', $key))
			{
				continue;
			}
			
			list(, $type, $k) = explode("-", $key);
			if (empty($k))
			{
				continue;
			}
			
			$_value = NULL;
			if ($value)
			{
				switch ($type)
				{
					case 'string':
					case 'text':
					case 'color':
						$_value = $this->_post->toString($key);
						break;
					case 'enum':
						list(,$_value) = explode('::', $this->_post->toString($key));
						break;
					case 'int':
					case 'bool':
						$_value = $this->_post->toInt($key);
						break;
					case 'float':
						$_value = $this->_post->toFloat($key);
						break;
				}
			}

			$post[$k] = $_value;
		}
		
		if (!(isset($post['o_smtp_host'], $post['o_smtp_port'], $post['o_smtp_user'], $post['o_smtp_pass'], $post['o_smtp_auth'], $post['o_smtp_secure'])
			&& !empty($post['o_smtp_host'])
			&& !empty($post['o_smtp_port'])
			&& !empty($post['o_smtp_user'])
			&& !empty($post['o_smtp_auth'])
		))
		{
		    self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => __('plugin_base_email_text_ARRAY_3', true)));
		}

		$mail = new pjPHPMailer(true);
		$mail->isSMTP();
		$mail->Host = $post['o_smtp_host'];
		$mail->Port = $post['o_smtp_port'];
		if (in_array($post['o_smtp_secure'], array('ssl', 'tls')))
		{
			$mail->SMTPSecure = $post['o_smtp_secure'];
		}
		if (!empty($post['o_smtp_user']))
		{
			$mail->SMTPAuth = true;
			$mail->AuthType = $post['o_smtp_auth'];
			$mail->Username = $post['o_smtp_user'];
			$mail->Password = $post['o_smtp_pass'];
		}

		try {
			$result = $mail->smtpConnect();
			$mail->smtpClose();
		} catch (pjException $e) {
			$result = false;
			$message = $e->getMessage();
		} catch (Exception $e) {
			$result = false;
			$message = $e->getMessage();
		}
		
		if ($result)
		{
		    self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => __('plugin_base_email_text_ARRAY_4', true)));
		}
		self::jsonResponse(array('status' => 'ERR', 'code' => 102, 'text' => __('plugin_base_email_text_ARRAY_5', true), 'message' => $message));
	}
	
	public function pjActionAjaxSend()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
		    self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => __('plugin_base_email_text_ARRAY_1', true)));
		}
		
		if (!self::isPost())
		{
		    self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => __('plugin_base_email_text_ARRAY_2', true)));
		}
		
		if (!$this->_post->check('email'))
		{
		    self::jsonResponse(array('status' => 'ERR', 'code' => 102, 'text' => __('plugin_base_email_text_ARRAY_6', true)));
		} else {
			if (!pjValidation::pjActionEmail($this->_post->toString('email')))
			{
			    self::jsonResponse(array('status' => 'ERR', 'code' => 103, 'text' => __('plugin_base_email_text_ARRAY_7', true)));
			}
		}
		
		$post = array();
		foreach ($this->_post->raw() as $key => $value)
		{
			if (!preg_match('/value-(string|text|int|float|enum|bool|color)-(.*)/', $key))
			{
				continue;
			}
			
			list(, $type, $k) = explode("-", $key);
			if (empty($k))
			{
				continue;
			}
			
			$_value = NULL;
			if ($value)
			{
				switch ($type)
				{
					case 'string':
					case 'text':
					case 'color':
						$_value = $this->_post->toString($key);
						break;
					case 'enum':
						list(,$_value) = explode('::', $this->_post->toString($key));
						break;
					case 'int':
					case 'bool':
						$_value = $this->_post->toInt($key);
						break;
					case 'float':
						$_value = $this->_post->toFloat($key);
						break;
				}
			}

			$post[$k] = $_value;
		}
		
		$subject = __('plugin_base_test_email_subject', true);
		$message = __('plugin_base_test_email_message', true);
		if (!empty($subject) && !empty($message)) {
			$pjEmail = self::getMailer($post);
			$pjEmail->setDebugger($this);
			$pjEmail->setTo($this->_post->toString('email'));
			$pjEmail->setSubject(stripslashes($subject));
			
			if ($pjEmail->send($message))
			{
			    self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => __('plugin_base_email_text_ARRAY_9', true) . ' ' . $this->_post->toString('email')));
			}
		}
		self::jsonResponse(array('status' => 'ERR', 'code' => 104, 'text' => __('plugin_base_email_text_ARRAY_8', true)));
	}

	public function pjActionUploadSidebarLogo()
	{
		$this->checkLogin();
		if (!pjAuth::factory('pjBaseOptions', 'pjActionVisual')->hasAccess()) {
			$this->sendForbidden();
			exit;
		}
		pjAppController::validateCsrfToken();
		pjUtil::ensureAdminSidebarLogoOption($this->getForeignId());
		pjUtil::handleAdminSidebarLogoUpload($this->getForeignId());
	}

	public function pjActionRemoveSidebarLogo()
	{
		$this->checkLogin();
		if (!pjAuth::factory('pjBaseOptions', 'pjActionVisual')->hasAccess()) {
			$this->sendForbidden();
			exit;
		}
		pjAppController::validateCsrfToken();
		pjUtil::ensureAdminSidebarLogoOption($this->getForeignId());
		pjUtil::handleAdminSidebarLogoRemove($this->getForeignId());
	}
}
?>
