Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/administrator/components/com_jea/models/ |
| [Home] [System Details] [Kill Me] |
<?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 '';
}
}