Mejora de productos

This commit is contained in:
2020-05-29 18:36:56 -04:00
parent 6744b8aa90
commit 3d270b1e8d
17 changed files with 593 additions and 147 deletions

View File

@ -74,5 +74,15 @@ return [
},
ProVM\KI\Common\Service\Indicadores::class => function(Container $c) {
return new ProVM\KI\Common\Service\Indicadores($c->get('urls.indicadores'));
},
ProVM\Common\Factory\Model::class => function(Container $c) {
return new ProVM\Common\Factory\Model(
$c->get('folders.data'),
implode(DIRECTORY_SEPARATOR, [
$c->get('folders.public'),
'assets',
'images'
])
);
}
];

View File

@ -6,24 +6,27 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
use Carbon\Carbon;
use ProVM\Common\Factory\Model as ModelFactory;
use ProVM\KI\Producto;
class Productos {
public function __invoke(Request $request, Response $response, View $view, Container $container): Response {
$filename = implode(DIRECTORY_SEPARATOR, [
public function __invoke(Request $request, Response $response, View $view, ModelFactory $factory): Response {
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
$productos = json_decode(trim(file_get_contents($filename)));
$productos = json_decode(trim(file_get_contents($filename)));*/
$productos = $factory->find(Producto::class)->many();
return $view->render($response, 'admin.productos', compact('productos'));
}
public function edit(Request $request, Response $response, View $view, Container $container, $producto): Response {
$filename = implode(DIRECTORY_SEPARATOR, [
public function edit(Request $request, Response $response, View $view, Container $container, ModelFactory $factory, $producto): Response {
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
$id = $producto;
$productos = json_decode(trim(file_get_contents($filename)));
$producto = $productos[$producto];
$producto = $productos[$id];
$producto->id = $id;
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
@ -50,7 +53,8 @@ class Productos {
}
$producto->images []= $file->getFilename();
}
}
}*/
$producto = $factory->find(Producto::class)->where([['id', $producto]])->one();
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
@ -59,18 +63,18 @@ class Productos {
$segmentos = json_decode(trim(file_get_contents($filename)));
return $view->render($response, 'admin.producto', compact('producto', 'segmentos'));
}
public function do_edit(Request $request, Response $response, Container $container, $producto): Response {
public function do_edit(Request $request, Response $response, ModelFactory $factory, $producto): Response {
$post = $request->getParsedBody();
$filename = implode(DIRECTORY_SEPARATOR, [
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
$id = $producto;
$productos = json_decode(trim(file_get_contents($filename)));
$producto = $productos[$producto];
$changed = false;
$producto = $productos[$producto];*/
$producto = $factory->find(Producto::class)->where([['id', $producto]])->one();
$fields = ['nombre', 'segmento', 'direccion', 'comuna', 'ciudad', 'bono', 'rentabilidad', 'estado',
/*$fields = ['nombre', 'segmento', 'direccion', 'comuna', 'ciudad', 'bono', 'rentabilidad', 'estado',
'cuota', 'unidades', 'modelos', 'descripcion', 'entrega'];
foreach ($fields as $field) {
if (!isset($producto->$field) or $post[$field] != $producto->$field) {
@ -87,28 +91,39 @@ class Productos {
if (!isset($producto->tamaño) or $producto->tamaño != $tamaño) {
$producto->tamaño = $tamaño;
$changed = true;
}*/
if (isset($post['destacado']) and $post['destacado'] == 'on') {
$producto->destacado(true);
}
$post['tamaños'] = implode(' ', [
$post['tamaño_min'],
'-',
$post['tamaño_max'],
'm²'
]);
$producto->map((object) $post);
$status1 = false;
/*$status1 = false;
if ($changed) {
$productos[$id] = $producto;
$status1 = (file_put_contents($filename, json_encode($productos, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES)) !== false);
}
}*/
$producto->save();
$filename = implode(DIRECTORY_SEPARATOR, [
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'destacados.json'
]);
$destacados = json_decode(trim(file_get_contents($filename)));
$changed = false;
if (isset($post['destacado']) and $post['destacado'] == 'on') {
if (array_search($id, $destacados) === false) {
$destacados []= $id;
if (array_search($producto->id, $destacados) === false) {
$destacados []= $producto->id;
sort($destacados);
$changed = true;
}
} else {
if (($i = array_search($id, $destacados)) !== false) {
if (($i = array_search($producto->id, $destacados)) !== false) {
unset($destacados[$i]);
$destacados = array_values($destacados);
$changed = true;
@ -117,7 +132,7 @@ class Productos {
$status2 = false;
if ($changed) {
$status2 = (file_put_contents($filename, json_encode($destacados)) !== false);
}
}*/
return $response
->withHeader('Location', implode('/', [$container->get('urls')->admin, 'productos']));
@ -130,10 +145,10 @@ class Productos {
$segmentos = json_decode(trim(file_get_contents($filename)));
return $view->render($response, 'admin.productos.add', compact('segmentos'));
}
public function do_add(Request $request, Response $response, Container $container): Response {
public function do_add(Request $request, Response $response, ModelFactory $factory): Response {
$post = $request->getParsedBody();
$producto = (object) [];
/*$producto = (object) [];
$fields = ['nombre', 'segmento', 'direccion', 'comuna', 'ciudad', 'bono', 'rentabilidad', 'estado',
'cuota', 'unidades', 'modelos', 'descripcion', 'entrega'];
foreach ($fields as $field) {
@ -158,26 +173,32 @@ class Productos {
]);
$productos = json_decode(trim(file_get_contents($filename)));
$productos []= $producto;
file_put_contents($filename, json_encode($productos, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES));
file_put_contents($filename, json_encode($productos, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES));*/
$producto = $factory->create(Producto::class, (object) $post);
if (isset($post['destacado']) and $post['destacado'] == 'on') {
$id = count($productos) - 1;
$producto->destacado(true);
}
$producto->save();
/*if (isset($post['destacado']) and $post['destacado'] == 'on') {
//$id = count($productos) - 1;
$id = $producto->id;
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'destacados.json'
]);
$destacados = json_decode(trim(file_get_contents($filename)));
$destacados []= $id;
$destacados []= $proyecto->id;
sort($destacados);
file_put_contents($filename, json_encode($destacados));
}
}*/
return $response
->withHeader('Location', implode('/', [$container->get('urls')->admin, 'productos']));
}
public function delete(Request $request, Response $response, Container $container): Response {
public function delete(Request $request, Response $response, ModelFactory $factory): Response {
$post = $request->getParsedBody();
$filename = implode(DIRECTORY_SEPARATOR, [
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
@ -191,6 +212,7 @@ class Productos {
mb_strtolower($producto->nombre)
]);
unset($productos[$id]);
$productos = array_values($productos);
$status = false;
$status |= (file_put_contents($filename, json_encode($productos, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES)) !== false);
if (file_exists($folder)) {
@ -205,7 +227,10 @@ class Productos {
unset($destacados[$i]);
$destacados = array_values($destacados);
$status |= (file_put_contents($filename, json_encode($destacados)) !== false);
}
}*/
$producto = $factory->find(Producto::class)->where([['id', $post['id']]])->one();
$status = $producto->delete();
$output = [
'information' => $post,
'estado' => $status
@ -215,11 +240,11 @@ class Productos {
->withHeader('Content-Type', 'application/json')
->withStatus(201);
}
public function add_image(Request $request, Response $response, Container $container, $producto): Response {
public function add_image(Request $request, Response $response, ModelFactory $factory, $producto): Response {
$post = $request->getParsedBody();
$files = $request->getUploadedFiles();
$file = $files['imagen'];
$filename = implode(DIRECTORY_SEPARATOR, [
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
@ -239,11 +264,13 @@ class Productos {
$folder,
$file->getClientFilename()
]);
$file->moveTo($filename);
$file->moveTo($filename);*/
$producto = $factory->find(Producto::class)->where([['id', $producto]])->one();
$status = $producto->addImagen($file);
$output = [
'informacion' => $id,
'estado' => file_exists($filename)
'estado' => $status
];
$response->getBody()->write(json_encode($output));
return $response
@ -262,9 +289,9 @@ class Productos {
mb_strtolower($producto->nombre)
]);
}
public function delete_image(Request $request, Response $response, Container $container, $producto): Response {
public function delete_image(Request $request, Response $response, ModelFactory $factory, $producto): Response {
$post = $request->getParsedBody();
$filename = implode(DIRECTORY_SEPARATOR, [
/*$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
@ -281,7 +308,9 @@ class Productos {
$folder,
$post['imagen']
]);
$status = unlink($filename);
$status = unlink($filename);*/
$producto = $factory->find(Producto::class)->where([['id', $producto]])->one();
$status = $producto->deleteImagen($post['imagen']);
$output = [
'estado' => $status
@ -299,5 +328,6 @@ class Productos {
'images',
mb_strtolower($producto->nombre)
]);
return $response;
}
}

View File

@ -5,6 +5,8 @@ use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
use ProVM\Common\Factory\Model as ModelFactory;
use ProVM\KI\Producto;
class Productos {
public function __invoke(Request $request, Response $response, Container $container, View $view): Response {
@ -15,59 +17,23 @@ class Productos {
$segmentos = json_decode(trim(file_get_contents($filename)));
return $view->render($response, 'productos.list', compact('segmentos'));
}
public function show(Request $request, Response $response, Container $container, View $view, $producto): Response {
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
$productos = json_decode(trim(file_get_contents($filename)));
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'destacados.json'
]);
$destacados = json_decode(trim(file_get_contents($filename)));
$destacado = false;
if (array_search($producto, $destacados) !== false) {
$destacado = true;
}
$id = $producto;
$producto = $productos[$producto];
$producto->destacado = $destacado;
$producto->id = $id;
$folder = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.public'),
'assets',
'images',
mb_strtolower($producto->nombre)
]);
$producto->images = [];
if (file_exists($folder)) {
$files = new \DirectoryIterator($folder);
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
$producto->images []= $file->getFilename();
}
}
public function show(Request $request, Response $response, View $view, ModelFactory $factory, $producto): Response {
$producto = $factory->find(Producto::class)->where([['id', $producto]])->one();
return $view->render($response, 'productos.show', compact('producto'));
}
public function segmento(Request $request, Response $response, Container $container, $segmento): Response {
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
$productos = json_decode(trim(file_get_contents($filename)));
public function segmento(Request $request, Response $response, ModelFactory $factory, $segmento): Response {
$productos = $factory->find(Producto::class);
if ($segmento != 'todo') {
$productos = array_filter($productos, function($item) use ($segmento) {
return (str_replace(' ', '_', mb_strtolower($item->segmento)) == $segmento);
});
$productos = $productos->where([['segmento', ucwords($segmento)]]);
}
$productos = $productos->many();
$output = [
'information' => [
'segmento' => $segmento
],
'productos' => array_keys($productos)
'productos' => array_map(function($item) {
return $item->id;
}, $productos)
];
$response->getBody()->write(json_encode($output));
return $response
@ -87,7 +53,8 @@ class Productos {
],
'destacados' => []
];
for ($i = ($page - 1) * 4; $i < $page * 4; $i ++) {
$n = min(4, count($destacados));
for ($i = ($page - 1) * $n; $i < $page * $n; $i ++) {
$output['destacados'] []= $destacados[$i];
}
$response->getBody()->write(json_encode($output));
@ -95,42 +62,8 @@ class Productos {
->withHeader('Content-Type', 'application/json')
->withStatus(201);
}
public function ficha(Request $request, Response $response, Container $container, View $view, $producto): Response {
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'productos.json'
]);
$productos = json_decode(trim(file_get_contents($filename)));
$filename = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.data'),
'destacados.json'
]);
$destacados = json_decode(trim(file_get_contents($filename)));
$destacado = false;
if (array_search($producto, $destacados) !== false) {
$destacado = true;
}
$id = $producto;
$producto = $productos[$producto];
$producto->destacado = $destacado;
$producto->id = $id;
$folder = implode(DIRECTORY_SEPARATOR, [
$container->get('folders.public'),
'assets',
'images',
mb_strtolower($producto->nombre)
]);
$producto->imagen = 'default.jpg';
if (file_exists($folder)) {
$files = new \DirectoryIterator($folder);
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
$producto->imagen = implode('/', [mb_strtolower($producto->nombre), $file->getFilename()]);
break;
}
}
public function ficha(Request $request, Response $response, View $view, ModelFactory $factory, $producto): Response {
$producto = $factory->find(Producto::class)->where([['id', $producto]])->one();
return $view->render($response, 'productos.ficha', compact('producto'));
}
}

View File

@ -27,7 +27,8 @@
"autoload": {
"psr-4": {
"ProVM\\KI\\Common\\": "common",
"ProVM\\KI\\": "src"
"ProVM\\KI\\": "src",
"ProVM\\Common\\": "provm/common"
}
}
}

View File

@ -0,0 +1,148 @@
<?php
namespace ProVM\Common\Factory;
use ProVM\Common\Implementation\Model as BaseModel;
class Model {
protected $data_folder;
protected $image_folder;
public function __construct(string $data_folder, string $image_folder) {
$this->data_folder = $data_folder;
$this->image_folder = $image_folder;
}
public function getFolder(): string {
return $this->data_folder;
}
public function get($file) {
$filename = implode(DIRECTORY_SEPARATOR, [
$this->data_folder,
$file
]);
return json_decode(trim(file_get_contents($filename)));
}
protected function reset() {
$this->class = null;
$this->conditions = null;
$this->limits = null;
}
protected $class;
public function find(string $class): Model {
if (!class_exists($class) or !is_subclass_of($class, \ProVM\Common\Implementation\Model::class)) {
throw new \InvalidArgumentException($class . ' is not defined.');
}
$this->reset();
$this->class = $class;
return $this;
}
/**
* JSON
* [
* {
* <field>,
* <value>,
* <operator>
* },
* ...
* ]
* @var array
*/
protected $conditions;
public function where(array $conditions): Model {
if ($this->conditions === null) {
$this->conditions = [];
}
foreach ($conditions as $condition) {
$c = ['field' => $condition[0], 'value' => $condition[1], 'operator' => '=='];
if (isset($condition[2])) {
$c['operator'] = $condition[2];
}
$this->conditions []= (object) $c;
}
return $this;
}
protected function parseWhere(array $data): array {
if ($this->conditions === null) {
return $data;
}
foreach ($this->conditions as $condition) {
$str = implode(' ', [
$condition->field,
$condition->operator,
(is_string($condition->value)) ? "'" . $condition->value . "'" : $condition->value
]);
return array_filter($data, function($item) use ($str) {
$bool = true;
eval("\$bool = (\$item->" . $str . ');');
return $bool;
});
}
}
protected $limits;
public function limit(int $limit): Model {
if ($this->limits === null) {
$this->limits = (object) ['limit' => null, 'offset' => 0];
}
$this->limits->limit = $limit;
return $this;
}
public function offset(int $offset): Model {
if ($this->limits === null) {
$this->limits = (object) ['limit' => null, 'offset' => 0];
}
$this->limits->offset = $offset;
return $this;
}
protected function parseLimits(array $data): array {
if ($this->limits === null or $this->limits->limit === null) {
return $data;
}
return array_slice($data, $this->limits->offset, $this->limits->limit);
}
protected function getFilename(): string {
$data = explode("\\", $this->class);
return implode(DIRECTORY_SEPARATOR, [
$this->data_folder,
str_replace(' ', '_', mb_strtolower(array_pop($data))) . 's.json'
]);
}
protected function build(): array {
$filename = $this->getFilename();
$data = json_decode(trim(file_get_contents($filename)));
$data = $this->parseWhere($data);
$data = $this->parseLimits($data);
return $data;
}
protected function fillObject($data): BaseModel {
$obj = new $this->class;
$obj->map($data);
$obj->setFactory($this);
$obj->setImageFolder($this->image_folder);
return $obj;
}
public function one(): BaseModel {
$data = $this->limit(1)->build();
$item = $data[0];
$obj = $this->fillObject($item);
return $obj;
}
public function many(): array {
$data = $this->build();
foreach ($data as &$item) {
$obj = $this->fillObject($item);
$item = $obj;
}
return $data;
}
public function array(): array {
return $this->build();
}
public function create(string $class, $data) {
$obj = new $class;
$obj->map($data);
$obj->setFactory($this);
$obj->setImageFolder($this->image_folder);
return $obj;
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace ProVM\Common\Implementation;
use ProVM\Common\Factory\Model as ModelFactory;
abstract class Model implements \JsonSerializable {
abstract public function map($data): Model;
protected $factory;
public function setFactory(ModelFactory $factory) {
$this->factory = $factory;
}
public function __get(string $name) {
if (!property_exists($this, $name)) {
throw new \InvalidArgumentException($name . ' is not a property of ' . get_called_class());
}
return $this->$name;
}
public function save() {
$filename = $this->getFilename();
$data = json_decode(trim(file_Get_contents($filename)));
if ($this->id === null) {
$this->id = array_reduce($data, function($max, $item) {
return (($max < $item->id) ? $item->id : $max);
}, 0) + 1;
$data []= $this->jsonSerialize();
} else {
foreach ($data as $i => $item) {
if ($item->id == $this->id) {
$data[$i] = $this->jsonSerialize();
}
}
}
$data = array_values($data);
return (file_put_contents($filename, json_encode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)) !== false);
}
public function delete() {
$filename = $this->getFilename();
$data = json_decode(trim(file_Get_contents($filename)));
foreach ($data as $i => $item) {
if ($item->id == $this->id) {
unset($data[$i]);
}
}
$data = array_values($data);
return (file_put_contents($filename, json_encode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)) !== false);
}
protected function getFilename(): string {
$data = explode("\\", get_called_class());
$folder = $this->factory->getFolder();
return implode(DIRECTORY_SEPARATOR, [
$folder,
str_replace(' ', '_', mb_strtolower(array_pop($data))) . 's.json'
]);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 153 KiB

View File

@ -16,15 +16,15 @@
<div class="fields">
<div class="field">
<label>Direcci&oacute;n</label>
<input type="text" name="direccion" value="{{$producto->direccion ?? ''}}" />
<input type="text" name="direccion" value="{{$producto->direccion->calle ?? ''}}" />
</div>
<div class="field">
<label>Comuna</label>
<input type="text" name="comuna" value="{{$producto->comuna ?? ''}}" />
<input type="text" name="comuna" value="{{$producto->direccion->comuna ?? ''}}" />
</div>
<div class="field">
<label>Ciudad</label>
<input type="text" name="ciudad" value="{{$producto->ciudad ?? ''}}" />
<input type="text" name="ciudad" value="{{$producto->direccion->ciudad ?? ''}}" />
</div>
</div>
</div>
@ -105,11 +105,11 @@
<div class="fields">
<div class="field">
<label>Tamaño M&iacute;nimo</label>
<input type="text" name="tamaño_min" value="{{(isset($producto->tamaño)) ? explode(' - ', rtrim($producto->tamaño, ' m²'))[0] : ''}}" />
<input type="text" name="tamaño_min" value="{{(property_exists($producto, 'tamaños')) ? explode(' - ', rtrim($producto->tamaños, ' m²'))[0] : ''}}" />
</div>
<div class="field">
<label>Tamaño M&aacute;ximo</label>
<input type="text" name="tamaño_max" value="{{(isset($producto->tamaño)) ? explode(' - ', rtrim($producto->tamaño, ' m²'))[1] : ''}}" />
<input type="text" name="tamaño_max" value="{{(property_exists($producto, 'tamaños')) ? explode(' - ', rtrim($producto->tamaños, ' m²'))[1] : ''}}" />
</div>
</div>
</div>
@ -208,7 +208,7 @@
var entrega = new Date('{{str_pad(implode('-', array_reverse(explode('/', $producto->entrega))), 7, '20', STR_PAD_LEFT)}}-01T01:00')
$('.calendar').calendar('set date', entrega)
$('.checkbox').checkbox()
@if ($producto->destacado)
@if ($producto->destacado())
$('.checkbox').checkbox('set checked')
@endif
$("input[name='imagen']").change(function() {
@ -228,7 +228,7 @@
}
})
})
@foreach ($producto->images as $image)
@foreach ($producto->imagenes() as $image)
listImage('{{$image}}')
@endforeach
$("input[name='video']").change(function() {

View File

@ -22,19 +22,19 @@
</tr>
</thead>
<tbody>
@foreach ($productos as $i => $producto)
@foreach ($productos as $producto)
<tr>
<td>
<a href="{{$urls->admin}}/producto/{{$i}}">
<a href="{{$urls->admin}}/producto/{{$producto->id}}">
{{$producto->nombre}}
</a>
</td>
<td class="center aligned">
<a href="{{$urls->admin}}/producto/{{$i}}">
<a href="{{$urls->admin}}/producto/{{$producto->id}}">
<i class="edit icon"></i>
</a>
</td>
<td class="center aligned"><i class="trash alternate outline icon" data-id="{{$i}}"></i></td>
<td class="center aligned"><i class="trash alternate outline icon" data-id="{{$producto->id}}"></i></td>
</tr>
@endforeach
</tbody>

View File

@ -89,7 +89,7 @@
$('<div></div>').attr('class', 'value').html(data.valor)
)
)
div.find('.header').popup(9)
div.find('.header').popup()
$(indicadores.id).find('.slideshow').append(div)
},
setup: () => {

View File

@ -7,19 +7,19 @@
{{$producto->segmento}}
</div>
<div class="descripcion">
{{$producto->comuna}}
{{$producto->direccion->comuna}}
</div>
</div>
<div class="medium image">
@if ($producto->destacado)
@if ($producto->destacado())
<div class="overlay">Destacado</div>
@endif
<img src="{{$urls->images}}/{{$producto->imagen}}" />
<img src="{{$urls->images}}/{{$producto->imagen()}}" />
</div>
<div class="content">
<div class="ui basic segment">
<span class="right floated">
{{$producto->valor}} UF
{{$producto->valor()}} UF
</span>
Valor depto
</div>

View File

@ -55,6 +55,10 @@
$(".tab[data-tab='" + segmento + "']").find('.grid').append(
$('<div></div>').attr('class', 'ui active centered inline loader')
)
if (data.productos.length == 0) {
$(".tab[data-tab='" + segmento + "']").find('.grid').html('No hay productos en este segmento.')
return
}
$.each(data.productos, (i, el) => {
getProducto(segmento, el)
})

View File

@ -15,7 +15,7 @@
Precio:
</div>
<div class="column">
{{$producto->valor ?? ''}} UF
{{$producto->valor() ?? ''}} UF
</div>
</div>
<div class="row">
@ -39,7 +39,11 @@
Ubicaci&oacute;n:
</div>
<div class="column">
{{$producto->comuna ?? ''}}, {{$producto->ciudad ?? ''}}
{{implode(', ', [
$producto->direccion->calle,
$producto->direccion->comuna ?? '',
$producto->direccion->ciudad ?? ''
])}}
</div>
</div>
<div class="row">
@ -63,7 +67,7 @@
Tama&ntilde;o
</div>
<div class="column">
{{$producto->tamaño ?? ''}}
{{$producto->tamaños ?? ''}}
</div>
</div>
</div>
@ -75,9 +79,9 @@
</div>
<div class="ui bottom attached basic segment tab" data-tab="mapa">
<div class="ui embed" id="map" data-source="Google Maps"
data-url="https://maps.google.com/maps?hl=es&amp;amp;q={{(isset($producto->direccion)) ? str_replace(' ', '%20', implode(', ', [
$producto->direccion, $producto->comuna
])) : 'Santiago,%20Chile'}}&amp;amp;ie=UTF8&amp;amp;z={{(isset($producto->direccion)) ? 16 : 11}}&amp;amp;iwloc=B&amp;amp;output=embed"></div>
data-url="https://maps.google.com/maps?hl=es&amp;amp;q={{($producto->direccion) ? str_replace(' ', '%20', implode(', ', [
$producto->direccion->calle, $producto->direccion->comuna
])) : 'Santiago,%20Chile'}}&amp;amp;ie=UTF8&amp;amp;z={{($producto->direccion) ? 16 : 11}}&amp;amp;iwloc=B&amp;amp;output=embed"></div>
</div>
@if (isset($producto->descripcion))
<div class="ui bottom attached basic segment tab" data-tab="descripcion">

View File

@ -1,10 +1,10 @@
<div id="galeria">
@if (count($producto->images))
@if (count($producto->imagenes()))
<div class="ui image" data-id="0">
<img src="{{$urls->images}}/{{mb_strtolower($producto->nombre)}}/{{$producto->imagen}}" />
<img src="{{$urls->images}}/{{mb_strtolower($producto->nombre)}}/{{$producto->imagen()}}" />
</div>
<div class="ui grid" id="thumbnails">
@foreach ($producto->images as $i => $image)
@foreach ($producto->imagenes() as $i => $image)
@if ($i == 0)
@continue
@endif
@ -21,7 +21,7 @@
@push('scripts')
<script type="text/javascript">
var images = [
@foreach ($producto->images as $image)
@foreach ($producto->imagenes() as $image)
'{{$urls->images}}/{{mb_strtolower($producto->nombre)}}/{{$image}}',
@endforeach
]

View File

@ -10,7 +10,7 @@
{{$producto->nombre}}
</span>
<span class="direccion">
{{$producto->direccion ?? ''}}, {{$producto->comuna ?? ''}}, {{$producto->ciudad ?? ''}}
{{'' . ($producto->direccion ?? '')}}
</span>
<div class="publicado">
Publicado el {{$producto->publicacion ?? ''}}

30
src/Direccion.php Normal file
View File

@ -0,0 +1,30 @@
<?php
namespace ProVM\KI;
use ProVM\Common\Implementation\Model;
class Direccion extends Model {
public function map($data): Model {
$this->calle = $data->calle;
$this->comuna = $data->comuna ?? '';
$this->ciudad = $data->ciudad ?? '';
return $this;
}
public function __toString(): string {
$str = [$this->calle];
if ($this->comuna != '') {
$str []= $this->comuna;
}
if ($this->ciudad != '') {
$str []= $this->ciudad;
}
return implode(', ', $str);
}
public function jsonSerialize() {
return [
'calle' => $this->calle,
'comuna' => $this->comuna,
'ciudad' => $this->ciudad
];
}
}

231
src/Producto.php Normal file
View File

@ -0,0 +1,231 @@
<?php
namespace ProVM\KI;
use Carbon\Carbon;
use ProVM\Common\Implementation\Model;
class Producto extends Model {
protected $id;
protected $nombre;
protected $segmento;
protected $direccion;
protected $valor;
protected $bono;
protected $rentabilidad;
protected $cuota;
protected $entrega;
protected $estado;
protected $unidades;
protected $modelos;
protected $tamaños;
protected $descripcion;
protected $publicacion;
public function valor(float $valor = -1) {
if ($valor == -1) {
return $this->valor;
}
$this->valor = number_format($valor, 0, ',', '.');
}
public function tamaños(int $min = -1, int $max = -1) {
if ($min == -1) {
return $this->tamaños;
}
if ($max == -1) {
$max = $min;
}
$this->tamaños = $min . ' - ' . $max . ' m²';
}
public function entrega(\DataTime $fecha = null) {
if ($fecha === null) {
return Carbon::parse(implode('-', array_reverse(explode('/', $this->entrega))) . '-01');
}
$this->entrega = $fecha->format('%m/%Y');
}
public function publicacion(\DateTime $fecha = null) {
if ($fecha === null) {
return Carbon::parse($this->publicacion);
}
$this->publicacion = implode(' ', [
$fecha->day,
'de',
ucwords($fecha->locale('es')->isoFormat('MMMM')) . ',',
$fecha->year
]);
}
protected $destacado;
public function destacado(bool $destacado = null): bool {
if ($destacado === null) {
if ($this->destacado === null) {
$destacados = $this->factory->get('destacados.json');
$this->destacado = (array_search($this->id, $destacados) !== false);
}
return $this->destacado;
}
$this->destacado = $destacado;
}
protected $image_folder;
public function setImageFolder(string $folder) {
$this->image_folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'assets',
'images',
mb_strtolower($this->nombre)
]);
}
protected $imagenes;
public function imagenes() {
if ($this->imagenes === null) {
$folder = $this->image_folder;
if (!file_exists($folder)) {
$this->imagenes = [];
return [];
}
if (file_exists($folder)) {
$files = new \DirectoryIterator($folder);
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
$producto->imagenes []= $file->getFilename();
}
sort($producto->imagenes);
}
}
return $this->imagenes;
}
public function addImagen($file) {
if (!file_exists($this->image_folder)) {
mkdir($this->image_folder);
}
$filename = implode(DIRECTORY_SEPARATOR, [
$this->image_folder,
$file->getClientFilename()
]);
$file->moveTo($filename);
if ($this->imagenes === null) {
$this->imagenes = [];
}
$this->imagenes []= $file->getClientFilename();
return file_exists($filename);
}
public function deleteImagen(string $file) {
$filename = implode(DIRECTORY_SEPARATOR, [
$this->image_folder,
$imagen
]);
if (!file_exists($filename)) {
return false;
}
$status = unlink($filename);
if (count(scandir($dir)) == 2) {
rmdir($this->image_folder);
}
return $status;
}
protected $imagen;
public function imagen() {
if ($this->imagen === null) {
$this->imagen = 'default.jpg';
$img = $this->imagenes();
if (count($img) > 0) {
$this->imagen = $img[0];
}
}
return $this->imagen;
}
public function map($data): Model {
$this->id = $data->id;
$this->nombre = $data->nombre;
$this->segmento = $data->segmento;
$this->direccion = new Direccion();
$this->direccion->map($data);
$this->valor($data->valor);
$this->bono = $data->bono;
$this->rentabilidad = $data->rentabilidad;
$this->cuota = $data->cuota;
$this->entrega = $data->entrega;
$this->estado = $data->estado;
$this->unidades = $data->unidades;
$this->modelos = $data->modelos;
$this->tamaños = $data->tamaños;
$this->descripcion = $data->descripcion;
$this->publicacion = $data->publicacion;
return $this;
}
public function jsonSerialize() {
$arr = [
'id' => $this->id,
'nombre' => $this->nombre,
'segmento' => $this->segmento,
'valor' => $this->valor,
'bono' => $this->bono,
'rentabilidad' => $this->rentabilidad,
'cuota' => $this->cuota,
'entrega' => $this->entrega,
'estado' => $this->estado,
'unidades' => $this->unidades,
'modelos' => $this->modelos,
'tamaños' => $this->tamaños,
'descripcion' => $this->descripcion,
'publicacion' => $this->publicacion
];
$arr = array_merge($arr, $this->direccion->jsonSerialize());
return $arr;
}
public function save() {
$this->changeDestacado();
return parent::save();
}
public function delete() {
$filename = implode(DIRECTORY_SEPARATOR, [
$this->factory->getFolder(),
'destacados.json'
]);
$destacados = json_decode(trim(file_get_contents($filename)));
foreach ($destacados as $i => $id) {
if ($id == $this->id) {
unset($destacados[$i]);
}
}
foreach ($this->imagenes() as $imagen) {
$this->deleteImagen($imagen);
}
return parent::delete();
}
public function changeDestacado() {
$filename = implode(DIRECTORY_SEPARATOR, [
$this->factory->getFolder(),
'destacados.json'
]);
$destacados = json_decode(trim(file_get_contents($filename)));
$changed = false;
if ($this->destacado()) {
foreach ($destacados as $i => $id) {
if ($id == $this->id) {
unset($destacados[$i]);
$changed = true;
break;
}
}
} else {
$found = false;
foreach ($destacados as $i => $id) {
if ($id == $this->id) {
$found = true;
break;
}
}
if (!$found) {
$destacados []= $this->id;
sort($destacados);
$changed = true;
}
}
file_put_contents($filename, json_encode($destacados));
}
}