Various improvements and optimizations in the models

Common functions (links, images, etc.) have also been moved to myhelper.
This commit is contained in:
Alfonso Saavedra "Son Link" 2024-04-07 22:27:36 +02:00
parent da15a23dd5
commit a035e46a59
No known key found for this signature in database
GPG Key ID: D3594BCF897F74D8
5 changed files with 332 additions and 146 deletions

View File

@ -4,7 +4,7 @@ use App\Models\UsersModel;
use App\Models\TracksModel; use App\Models\TracksModel;
use App\Models\CarsModel; use App\Models\CarsModel;
function get_header($title, $css=[]) function get_header($title, $css=[], $dasboard=false)
{ {
if (!is_array($css)) $css = []; if (!is_array($css)) $css = [];
$data = [ $data = [
@ -12,12 +12,13 @@ function get_header($title, $css=[])
'custom_css' => $css, 'custom_css' => $css,
]; ];
if ($dasboard) return view('dashboard/header', $data);
return view('templates/header', $data); return view('templates/header', $data);
} }
/** /**
* Esta función muestra la plantilla del pie de la página. * Esta función muestra la plantilla del pie de la página.
* @param Array $css Un array con los scripts opcionales. * @param array $js Un array con los scripts opcionales.
* @return * La vista del pie o false en caso de error. * @return * La vista del pie o false en caso de error.
*/ */
function get_footer($js=[]) function get_footer($js=[])
@ -50,6 +51,7 @@ function xmlObj($xmlstring)
################################### ###################################
## extract content of a json txt file an d return an object of the json string ## extract content of a json txt file an d return an object of the json string
################################### ###################################
/*
function jsonTxtFileToObj($fileUrl, $objClass) function jsonTxtFileToObj($fileUrl, $objClass)
{ {
$myfile = fopen($fileUrl, "r") or die("Unable to open file!"); $myfile = fopen($fileUrl, "r") or die("Unable to open file!");
@ -104,10 +106,7 @@ function getTrackCats()
{ {
return jsonTxtFileToObj(WRITEPATH . "/data/trackCategories.txt", 'TrackCategory'); return jsonTxtFileToObj(WRITEPATH . "/data/trackCategories.txt", 'TrackCategory');
} }
*/
###################################
##
###################################
function secondsToTime($seconds) function secondsToTime($seconds)
{ {
/* /*
@ -140,9 +139,6 @@ function secondsToTime($seconds)
return $str; return $str;
} }
###################################
##
###################################
function formatLaptime($seconds) function formatLaptime($seconds)
{ {
$seconds = $seconds *1; $seconds = $seconds *1;
@ -162,9 +158,6 @@ function formatLaptime($seconds)
return $str; return $str;
} }
###################################
##
###################################
function percentStr($smallvalue, $bigvalue) function percentStr($smallvalue, $bigvalue)
{ {
if($bigvalue==0) return '-%'; if($bigvalue==0) return '-%';
@ -173,33 +166,24 @@ function percentStr($smallvalue, $bigvalue)
return $percent.'%'; return $percent.'%';
} }
###################################
##
###################################
function weatherTag($value) function weatherTag($value)
{ {
switch($value) switch($value)
{ {
case 0: case 0:
return '<i class="wi wi-day-sunny"></i>'; return '<i class="wi wi-day-sunny"></i>';
break;
case 1: case 1:
return '<i class="wi wi-rain"></i>'; return '<i class="wi wi-rain"></i>';
break;
case 2: case 2:
return '<i class="wi wi-rain"></i>'; return '<i class="wi wi-rain"></i>';
break;
case 3: case 3:
return '<i class="wi wi-rain"></i>'; return '<i class="wi wi-rain"></i>';
break;
} }
} }
###################################
## // This will rewrite the current url
################################### // and modify the given param if needed
//this will rewrite the current url
//and modify the given param if needed
function rewriteUrl($paramName, $paramValue) function rewriteUrl($paramName, $paramValue)
{ {
$query = $_GET; $query = $_GET;
@ -208,10 +192,10 @@ function rewriteUrl($paramName, $paramValue)
// rebuild url // rebuild url
$query_result = http_build_query($query); $query_result = http_build_query($query);
// new link // new link
return base_url().'?'.$query_result; return base_url() . '?' .$query_result;
} }
/*
function getCar($carId) function getCar($carId)
{ {
$cars = getCars(); $cars = getCars();
@ -256,7 +240,7 @@ function getTrack($trackId)
return $fakeTrack; return $fakeTrack;
} }
} }
*/
function generateConditions($conditions, $separator = ',') function generateConditions($conditions, $separator = ',')
{ {
$txt=''; $txt='';
@ -275,10 +259,11 @@ function generateConditions($conditions, $separator = ',')
return $txt; return $txt;
} }
/*
class CarCategory class CarCategory
{ {
function CarCategory($category){ function category($category)
{
$this->import($category); $this->import($category);
} }
@ -291,7 +276,7 @@ class CarCategory
class TrackCategory class TrackCategory
{ {
function TrackCategory($category){ function category($category){
$this->import($category); $this->import($category);
} }
public function import($properties){ public function import($properties){
@ -300,12 +285,17 @@ class TrackCategory
} }
} }
} }
*/
function racetype($num){ function racetype($num)
{
switch ($num){ switch ($num){
case 0: return 'practice';break; case 0:
case 1: return 'qualify';break; return 'practice';
case 2: return 'race';break; case 1:
return 'qualify';
case 2:
return 'race';
} }
} }
@ -334,11 +324,7 @@ function getBestTimesTrack($trackId)
$builder->orderBy('l.laptime'); $builder->orderBy('l.laptime');
$query = $builder->get(10); $query = $builder->get(10);
if (!$query || $query->getNumRows() == 0) if (!$query || $query->getNumRows() == 0) return [];
{
echo "No laps to show for this tracks";
return [];
}
return $query->getResult(); return $query->getResult();
} }
@ -353,3 +339,103 @@ function getCarBetsLaps($carId)
GROUP BY r.id GROUP BY r.id
ORDER BY l.laptime"; ORDER BY l.laptime";
} }
function getOS() {
$user_agent = $_SERVER['HTTP_USER_AGENT'];
log_message('debug', "HTTP_USER_AGENT: $user_agent");
$os_platform = "Unknown Operative System";
$os_array = array(
'/windows nt 10/i' => 'Windows 10',
'/windows nt 6.3/i' => 'Windows 8.1',
'/windows nt 6.2/i' => 'Windows 8',
'/windows nt 6.1/i' => 'Windows 7',
'/windows nt 6.0/i' => 'Windows Vista',
'/windows nt 5.2/i' => 'Windows Server 2003/XP x64',
'/windows nt 5.1/i' => 'Windows XP',
'/windows xp/i' => 'Windows XP',
'/windows nt 5.0/i' => 'Windows 2000',
'/windows me/i' => 'Windows ME',
'/win98/i' => 'Windows 98',
'/win95/i' => 'Windows 95',
'/win16/i' => 'Windows 3.11',
'/macintosh|mac os x/i' => 'Mac OS X',
'/mac_powerpc/i' => 'Mac OS 9',
'/linux/i' => 'Linux',
'/ubuntu/i' => 'Ubuntu',
'/iphone/i' => 'iPhone',
'/ipod/i' => 'iPod',
'/ipad/i' => 'iPad',
'/android/i' => 'Android',
'/blackberry/i' => 'BlackBerry',
'/webos/i' => 'Mobile',
'/libcurl-agent/i' => 'Unknown (Curl)'
);
foreach ( $os_array as $regex => $value )
if ( preg_match($regex, $user_agent ) ) $os_platform = $value;
log_message('debug', "Operative System: $os_platform");
return $os_platform;
}
/**
* Returns if the current user if log in
* @return bool The user level if logged in
*/
function ifLoggedIn(): bool
{
//$db = \Config\Database::connect();
$session = session();
if ($session->get('logged_in')) return true;
return false;
}
function findObjectById($array, $id)
{
foreach ( $array as $element )
{
if ( $id == $element->id ) return true;
}
return false;
}
function imgTag(string $img, string $width, string $title): string
{
$img = str_replace('./', '/', $img);
$url = base_url($img);
return "<img width='$width' src='$url' alt='$title' title='$title'>";
}
function imgTagFull(string $img, string $class, string $alt)
{
$img = str_replace('./', '/', $img);
$url = base_url($img);
return "<img src='$url' class='$class' alt='$alt'>";
}
function clickableName(string $id, string $type, string $content): string
{
return linkTag($id, $type, $content);
}
function clickableImgTag(string $id, string $size, string $type, string $title): string
{
return linkTag($id, $type, imgTag($id, $size, $title));
}
function linkTag(string $id, string $type , string $content): string
{
$url = base_url("$type/$id");
return "<a href='$url'>$content</a>";
}
function linkTitleImgTag(string $id, string $type, string $name, string $img): string
{
if ($type != 'car' && $type != 'track') return '';
$url = base_url("$type/$id");
$content = $name . '<br />' . imgTag($img, '80px', $name);
return "<a href='$url'>$content</a>";
}

25
app/Models/BaseModel.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class BaseModel extends Model
{
protected $primaryKey = 'id';
protected $returnType = 'object';
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
public function data($id)
{
$builder = $this->builder();
$builder->where('id', $id);
$query = $builder->get(1);
if ($query) return $query->getRow();
}
}

View File

@ -1,27 +1,29 @@
<?php <?php
namespace App\Models; namespace App\Models;
use App\Models\BaseModel;
class CarsModel class CarsModel extends BaseModel
{ {
public function __construct($car) private $data;
protected $table = 'cars';
protected $allowedFields = ['id', 'name', 'img', 'category', 'width', 'length', 'mass', 'fueltank', 'engine', 'drivetrain'];
/*
public function __construct($car=null)
{ {
$this->import($car); if ($car) $this->data = $this->data($car);
} }
public function import($properties){ public function getLink(string $text=null): string
foreach($properties as $key => $value)
{ {
$this->{$key} = $value; if(!$text) $text = $this->data->name;
} return "<a href='". base_url() . "'/car/{$this->data->id}'>$text</a>";
}
public function getLink($text='')
{
if($text == '') $text = $this->username;
return "<a href='". base_url() . "'/car/{$this->id}'>$text</a>";
} }
public function card($text='') { public function card() {
return $this->name.$this->img; return $this->data->name . $this->data->img;
} }
public function imgTag() public function imgTag()
@ -54,4 +56,5 @@ class CarsModel
$content = $this->name . '<br />' . $this->imgTag(); $content = $this->name . '<br />' . $this->imgTag();
return "<a href='" . base_url() . "/car/{$this->id}'>$content</a>"; return "<a href='" . base_url() . "/car/{$this->id}'>$content</a>";
} }
*/
} }

View File

@ -1,33 +1,40 @@
<?php <?php
namespace App\Models; namespace App\Models;
use CodeIgniter\Model; use App\Models\BaseModel;
# use App\Libraries\Usuarios;
class TracksModel extends Model class TracksModel extends BaseModel
{ {
protected $table = 'tracks';
protected $db; protected $db;
protected $allowedFields = ['id', 'name', 'img', 'category', 'author', 'description'];
public function __construct($track) /*
public function __construct($track=null)
{ {
$this->import($track); if ($track) $this->import($track);
} }
public function import($properties){ public function import($properties)
foreach($properties as $key => $value){ {
$this->{$key} = $value; foreach($properties as $key => $value) $this->{$key} = $value;
} }
}
public function getLink($text='') { public function getLink($text='')
{
if($text == '') $text = $this->username; if($text == '') $text = $this->username;
return '<a href="track/'.$this->id.'">'.$text.'</a>'; return '<a href="track/'.$this->id.'">'.$text.'</a>';
} }
public function card($text='') {
public function card($text='')
{
return $this->name.$this->img; return $this->name.$this->img;
} }
public function imgTag() { public function imgTag() {
return "<img width='80' src='". base_url() ."/".$this->img."' alt='".$this->name."' title='".$this->name."'>"; return "<img width='80' src='". base_url() ."/".$this->img."' alt='".$this->name."' title='".$this->name."'>";
} }
public function imgTagFull() { public function imgTagFull() {
return "<img src='". base_url() ."/".$this->img."' class='track-img' alt='".$this->name."'>"; return "<img src='". base_url() ."/".$this->img."' class='track-img' alt='".$this->name."'>";
} }
@ -47,4 +54,5 @@ class TracksModel extends Model
$content = $this->name . '<br />' . $this->imgTag(); $content = $this->name . '<br />' . $this->imgTag();
return "<a href='" . base_url() . "/track/{$this->id}'>$content</a>"; return "<a href='" . base_url() . "/track/{$this->id}'>$content</a>";
} }
*/
} }

View File

@ -1,30 +1,55 @@
<?php <?php
namespace App\Models; namespace App\Models;
use CodeIgniter\Model; use App\Models\BaseModel;
use App\Models\CarsModel; use App\Models\CarsModel;
use App\Models\TracksModel;
class UsersModel extends Model class UsersModel extends BaseModel
{ {
protected $table = 'users';
protected $allowedFields = ['username', 'email', 'password', 'img', 'nation', 'registrationdate',
'sessionid', 'sessionip', 'sessiontimestamp', 'level'
];
public $id; public $id;
protected $db;
protected $raceTypes; protected $raceTypes;
private $carsModel;
private $tracksModel;
private $session;
private $user;
const HASH = PASSWORD_DEFAULT; const HASH = PASSWORD_DEFAULT;
const COST = 16; const COST = 16;
public function __construct($id = null) public function initialize()
{ {
$this->db = \Config\Database::connect(); $this->session = \Config\Services::session();
$this->id = $id; $this->carsModel = new CarsModel();
$this->tracksModel = new TracksModel();
$this->raceTypes = new \stdClass; $this->raceTypes = new \stdClass;
$this->raceTypes->practice = 0; $this->raceTypes->practice = 0;
$this->raceTypes->qualify = 1; $this->raceTypes->qualify = 1;
$this->raceTypes->race = 2; $this->raceTypes->race = 2;
if ($this->id){
$this->getFromDb();
} }
/*
public function initialize()
{
$this->session = session();
$this->carsModel = new CarsModel;
$this->tracksModel = new TracksModel;
$this->raceTypes = new \stdClass;
$this->raceTypes->practice = 0;
$this->raceTypes->qualify = 1;
$this->raceTypes->race = 2;
} }
public function getUsers() public function getUsers()
@ -35,18 +60,22 @@ class UsersModel extends Model
if ($query && $query->getNumRows() > 0) $users = $query->getResult(); if ($query && $query->getNumRows() > 0) $users = $query->getResult();
return $users; return $users;
} }
*/
public function getUser($username) public function getUser($username)
{ {
$builder = $this->db->table('users'); $builder = $this->builder();
$builder->select('id'); $builder->select('id, email, username, nation, img');
$builder->where('username', $username); $builder->where('username', $username);
$query = $builder->get(1); $query = $builder->get(1);
if ($query && $query->getNumRows() == 1) if ($query && $query->getNumRows() == 1)
{ {
return $query->getRow()->id; $data = $query->getRow();
$this->id = $data->id;
$data->flag = str_replace(' ', '_', $data->nation) . '.png';
return $data;
} }
return false; return false;
} }
@ -54,11 +83,11 @@ class UsersModel extends Model
* Check if the user and/or email is already in use. * Check if the user and/or email is already in use.
* @param string $username The username to check. * @param string $username The username to check.
* @param string $email The email to check. * @param string $email The email to check.
* @return Boolean False if the username and email are not in use * @return boolean False if the username and email are not in use
*/ */
public function compUser($username, $email) public function compUser($username, $email)
{ {
$builder = $this->db->table('users'); $builder = $this->builder();
$builder->select('id'); $builder->select('id');
$builder->where('username', $username); $builder->where('username', $username);
$builder->orWhere('email', $email); $builder->orWhere('email', $email);
@ -72,6 +101,7 @@ class UsersModel extends Model
return false; return false;
} }
/*
private function import($properties) private function import($properties)
{ {
foreach($properties as $key => $value){ foreach($properties as $key => $value){
@ -103,29 +133,34 @@ class UsersModel extends Model
public function getLink($text='') public function getLink($text='')
{ {
if ($text == '') $text=$this->username; if ($text == '') $text=$this->username;
return "<a href='" . base_url() . "/user/{$this->username}'>$text</a>"; return "<a href='" . base_url() . "user/{$this->username}'>$text</a>";
} }
public function getSmallFlagImg() public function getSmallFlagImg()
{ {
return "<img src='" . base_url() . "/img/flags/flags_small/{$this->flag}' alt='{$this->nation}'>"; return "<img src='" . base_url() . "img/flags/flags_small/{$this->flag}' alt='{$this->nation}'>";
} }
public function getMediumFlagImg() public function getMediumFlagImg()
{ {
return "<img src='" . base_url() . "/img/flags/flags_medium/{$this->flag}' alt='{$this->nation}'>"; return "<img src='" . base_url() . "img/flags/flags_medium/{$this->flag}' alt='{$this->nation}'>";
} }
public function getImgFile() public function getImgFile()
{ {
return "<img class='avatar' src='" . base_url() . "/img/users/{$this->img}' alt='{$this->username}'>"; return "<img class='avatar' src='" . base_url() . "img/users/{$this->img}' alt='{$this->username}'>";
} }
*/
public function getRaceSessions() public function getRaceSessions()
{ {
$builder = $this->db->table('races'); $builder = $this->db->table('races r');
$builder->where('user_id', $this->id); $builder->select('r.id, r.user_skill, r.track_id, r.car_id, r.startposition, r.endposition');
$builder->orderBy('id DESC'); $builder->select('r.sdversion, r.timestamp, r.type, t.name as track_name, c.name as car_name');
$builder->join('tracks t', 't.id = r.track_id');
$builder->join('cars c', 'c.id = r.car_id');
$builder->where('r.user_id', $this->id);
$builder->orderBy('r.id DESC');
$query = $builder->get(); $query = $builder->get();
if ($query && $query->getNumRows() > 0) return $query->getResult(); if ($query && $query->getNumRows() > 0) return $query->getResult();
@ -246,7 +281,7 @@ class UsersModel extends Model
$data = new \stdClass; $data = new \stdClass;
if ($query && $query->getNumRows() > 0) if ($query && $query->getNumRows() > 0)
{ {
$data->car = new CarsModel(getCar($query->getRow()->car_id)); $data->car = $this->carsModel->find($query->getRow()->car_id);
$data->total = $query->getRow()->count; $data->total = $query->getRow()->count;
} }
return $data; return $data;
@ -255,48 +290,52 @@ class UsersModel extends Model
public function getMostUsedTrack() public function getMostUsedTrack()
{ {
$builder = $this->db->table('races'); $builder = $this->db->table('races');
$builder->select('track_id, COUNT(*) as count'); $builder->select('track_id, COUNT(*) AS total');
$builder->where([ $builder->where([
'user_id' => $this->id 'user_id' => $this->id
]); ]);
$builder->orderBy('count', 'desc'); $builder->orderBy('total', 'desc');
$builder->groupBy('track_id'); $builder->groupBy('track_id');
$query = $builder->get(1); $query = $builder->get(1);
$data = new \stdClass; $data = new \stdClass;
if ($query && $query->getNumRows() > 0) if ($query && $query->getNumRows() > 0)
{ {
$data->track = new TracksModel(getTrack($query->getRow()->track_id)); $result = $query->getRow();
$data->total = $query->getRow()->total; log_message('debug', json_encode($result));
$data->track = $this->tracksModel->find($result->track_id);
$data->total = $result->total;
} }
return $data; return $data;
} }
public function getTimeOnTracks() public function getTimeOnTracks()
{ {
$builder = $this->db->table('laps A'); $builder = $this->db->table('laps l');
$builder->selectSum('A.laptime'); $builder->selectSum('l.laptime');
$builder->join('races B', 'ON A.race_id = B.id'); $builder->join('races r', 'l.race_id = r.id');
$builder->where([ $builder->where([
'B.user_id' => $this->id 'r.user_id' => $this->id
]); ]);
//$builder->orderBy('count', 'desc'); //$builder->orderBy('count', 'desc');
$query = $builder->get(1); $query = $builder->get(1);
if ($query && $query->getNumRows() > 0) return $query->getRow()->laptime; if ($query && $query->getNumRows() > 0) return $query->getRow()->laptime;
return 0; return 0;
} }
public function getTimeOnRace() public function getTimeOnRace()
{ {
$builder = $this->db->table('laps A'); $builder = $this->db->table('laps l');
$builder->selectSum('A.laptime'); $builder->selectSum('l.laptime');
$builder->join('races B', 'ON A.race_id = B.id'); $builder->join('races r', 'l.race_id = r.id');
$builder->where([ $builder->where([
'B.user_id' => $this->id, 'r.user_id' => $this->id,
'B.type' => $this->raceTypes->race 'r.type' => $this->raceTypes->race
]); ]);
//$builder->orderBy('count', 'desc'); //$builder->orderBy('count', 'desc');
@ -308,12 +347,12 @@ class UsersModel extends Model
public function getTimePractice() public function getTimePractice()
{ {
$builder = $this->db->table('laps A'); $builder = $this->db->table('laps l');
$builder->selectSum('A.laptime'); $builder->selectSum('l.laptime');
$builder->join('races B', 'ON A.race_id = B.id'); $builder->join('races r', 'l.race_id = r.id');
$builder->where([ $builder->where([
'B.user_id' => $this->id, 'r.user_id' => $this->id,
'B.type' => $this->raceTypes->practice 'r.type' => $this->raceTypes->practice
]); ]);
//$builder->orderBy('count', 'desc'); //$builder->orderBy('count', 'desc');
@ -325,12 +364,12 @@ class UsersModel extends Model
public function getTimeQualify() public function getTimeQualify()
{ {
$builder = $this->db->table('laps A'); $builder = $this->db->table('laps l');
$builder->selectSum('A.laptime'); $builder->selectSum('l.laptime');
$builder->join('races B', 'ON A.race_id = B.id'); $builder->join('races r', 'l.race_id = r.id');
$builder->where([ $builder->where([
'B.user_id' => $this->id, 'r.user_id' => $this->id,
'B.type' => $this->raceTypes->qualify 'r.type' => $this->raceTypes->qualify
]); ]);
//$builder->orderBy('count', 'desc'); //$builder->orderBy('count', 'desc');
@ -354,14 +393,13 @@ class UsersModel extends Model
'username' => $data['username'], 'username' => $data['username'],
'email' => $data['email'], 'email' => $data['email'],
'nation' => $data['nation'], 'nation' => $data['nation'],
'username' => $data['username'],
]; ];
// First verify if the user or email // First verify if the user or email
$sql = $this->db->table('users'); $builder = $this->db->table('users');
$sql->where('username', $user['username']); $builder->where('username', $user['username']);
$sql->orWhere('email', $user['email']); $builder->orWhere('email', $user['email']);
$query = $sql->get(1); $query = $builder->get(1);
if ($query && $query->getNumRows() == 1){ if ($query && $query->getNumRows() == 1){
$response['msg'] = 'Username and/or email are registered'; $response['msg'] = 'Username and/or email are registered';
@ -372,24 +410,50 @@ class UsersModel extends Model
$user['password'] = password_hash($data['password'], self::HASH, [self::COST]); $user['password'] = password_hash($data['password'], self::HASH, [self::COST]);
unset($data); unset($data);
// Insert data // Insert data
$sql->insert($user); $this->insert($user);
$error = $this->db->error(); $error = $this->db->error();
if ($error['code'] != 0)
{ if ($error['code'] != 0) $response['msg'] = 'An error ocurred on insert the new user to the database';
$resp['msg'] = 'An error ocurred on insert the new user to the database';
}
else else
{ {
$id = $this->db->insertID(); $id = $this->db->insertID();
$sql->resetQuery(); //$builder->resetQuery();
// Move the file to it's new home // Move the file to it's new home
$filename = $user['username'] . '.' . $image->getExtension(); $filename = $user['username'] . '.' . $image->getExtension();
$image->move(FCPATH . '/img/users/', $filename); $image->move(FCPATH . '/img/users/', $filename);
$sql->where('id', $id)->update(['img' => $filename]); $this->where('id', $id)->update(['img' => $filename]);
$response['ok'] = true; $response['ok'] = true;
} }
} }
return $response; return $response;
} }
public function login($data)
{
$builder = $this->builder();
$builder->select('id, password, level, username');
$builder->where('username', $data['username']);
$query = $builder->get(1);
if ($query && $query->getNumRows() == 1)
{
$user = $query->getRow();
if (password_verify($data['passwd'], $user->password))
{
$sessiondata = [
'userid' => $user->id,
'userlevel' => $user->level,
'username' => $user->username,
'logged_in' => true
];
$this->session->set($sessiondata);
return true;
}
return false;
}
return false;
}
} }