K. Carpeta « api »

Versión para imprimir.

A. api / archivo.php

1
<?php
2
3
require_once __DIR__ . "/../libservidorphp/recibeEnteroObligatorio.php";
4
require_once __DIR__ . "/../libservidorphp/validaEntidadObligatoria.php";
5
require_once __DIR__ . "/Bd.php";
6
7
// Evita que la imagen se cargue en el caché del navegador.
8
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
9
header("Cache-Control: post-check=0, pre-check=0", false);
10
header("Pragma: no-cache");
11
12
$archId = recibeEnteroObligatorio("id");
13
14
$bd = Bd::conexion();
15
16
$stmt = $bd->prepare("SELECT * FROM ARCHIVO WHERE ARCH_ID = :ARCH_ID");
17
$stmt->execute([":ARCH_ID" => $archId]);
18
$archivo = $stmt->fetch(PDO::FETCH_ASSOC);
19
20
$archivo = validaEntidadObligatoria("Archivo",  $archivo);
21
22
$bytes = $archivo["ARCH_BYTES"];
23
$contentType = (new finfo(FILEINFO_MIME_TYPE))->buffer($bytes);
24
header("Content-Type: $contentType");
25
echo $bytes;
26

B. api / archivoAgrega.php

1
<?php
2
3
function archivoAgrega(PDO $bd, string $bytes)
4
{
5
 $stmt = $bd->prepare(
6
  "INSERT INTO ARCHIVO (
7
    ARCH_BYTES
8
   ) values (
9
    :ARCH_BYTES
10
   )"
11
 );
12
 $stmt->execute([
13
  ":ARCH_BYTES" => $bytes
14
 ]);
15
 $archId = $bd->lastInsertId();
16
 return $archId;
17
}
18

C. api / Bd.php

1
<?php
2
3
class Bd
4
{
5
 private static ?PDO $pdo = null;
6
7
 static function conexion(): PDO
8
 {
9
  if (self::$pdo === null) {
10
11
   self::$pdo = new PDO(
12
    // cadena de conexión
13
    "sqlite:" . __DIR__ . "/srvarchivos.db",
14
    // usuario
15
    null,
16
    // contraseña
17
    null,
18
    // Opciones: pdos no persistentes y lanza excepciones.
19
    [PDO::ATTR_PERSISTENT => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
20
   );
21
22
   self::$pdo->exec(
23
    'CREATE TABLE IF NOT EXISTS ARCHIVO (
24
      ARCH_ID INTEGER,
25
      ARCH_BYTES BLOB NOT NULL,
26
      CONSTRAINT PK_ARCH PRIMARY KEY(ARCH_ID)
27
     )'
28
   );
29
   self::$pdo->exec(
30
    'CREATE TABLE IF NOT EXISTS PRODUCTO (
31
      PRD_ID INTEGER,
32
      PRD_NOMBRE TEXT NOT NULL,
33
      PRD_ARCH_ID INTEGER NOT NULL,
34
      CONSTRAINT PK_PRD PRIMARY KEY(PRD_ID),
35
      CONSTRAINT UQ_PRD_NOM UNIQUE(PRD_NOMBRE),
36
      CONSTRAINT CHK_PRD_NOM CHECK(LENGTH(PRD_NOMBRE) > 0),
37
      CONSTRAINT FK_PRD_ARCH
38
       FOREIGN KEY (PRD_ARCH_ID) REFERENCES ARCHIVO(ARCH_ID)
39
      )'
40
   );
41
  }
42
43
  return self::$pdo;
44
 }
45
}
46

D. api / producto-agrega.php

1
<?php
2
3
require_once __DIR__ . "/../libservidorphp/manejaErrores.php";
4
require_once __DIR__ . "/../libservidorphp/recibeTextoObligatorio.php";
5
require_once __DIR__ . "/../libservidorphp/recibeBytesObligatorios.php";
6
require_once __DIR__ . "/../libservidorphp/devuelveCreated.php";
7
require_once __DIR__ . "/Bd.php";
8
require_once __DIR__ . "/archivoAgrega.php";
9
10
$nombre = recibeTextoObligatorio("nombre");
11
$bytes = recibeBytesObligatorios("imagen");
12
13
$bd = Bd::conexion();
14
$bd->beginTransaction();
15
16
$archId = archivoAgrega($bd, $bytes);
17
18
$stmt = $bd->prepare(
19
 "INSERT INTO PRODUCTO (
20
    PRD_NOMBRE, PRD_ARCH_ID
21
   ) values (
22
    TRIM(:PRD_NOMBRE), :PRD_ARCH_ID
23
   )"
24
);
25
$stmt->execute([
26
 ":PRD_NOMBRE" => $nombre,
27
 ":PRD_ARCH_ID" => $archId
28
]);
29
$prodId = $bd->lastInsertId();
30
31
$bd->commit();
32
33
$query = http_build_query(["id" => $prodId]);
34
$queryArch = http_build_query(["id" => $archId]);
35
// Los bytes de las imágenes se descargan con "archivo.php"; no desde aquí.
36
devuelveCreated("/api/producto-vista-modifica.php?$query", [
37
 "id" => ["value" => $prodId],
38
 "nombre" => ["value" => $nombre],
39
 "imagen" => ["data-src" => $archId === "" ? "" : "api/archivo.php?$queryArch"]
40
]);
41

E. api / producto-elimina.php

1
<?php
2
3
require_once __DIR__ . "/../libservidorphp/manejaErrores.php";
4
require_once __DIR__ . "/../libservidorphp/recibeEnteroObligatorio.php";
5
require_once __DIR__ . "/../libservidorphp/devuelveNoContent.php";
6
require_once __DIR__ . "/Bd.php";
7
require_once __DIR__ . "/productoBusca.php";
8
9
$prodId = recibeEnteroObligatorio("id");
10
11
$bd = Bd::conexion();
12
$bd->beginTransaction();
13
14
$producto = productoBusca($bd, $prodId);
15
16
if ($producto !== false) {
17
18
 $archId = $producto["PRD_ARCH_ID"];
19
20
 $stmt = $bd->prepare("DELETE FROM PRODUCTO WHERE PRD_ID = :PRD_ID");
21
 $stmt->execute([":PRD_ID" => $prodId]);
22
23
 if ($archId !== null) {
24
  $stmt = $bd->prepare("DELETE FROM ARCHIVO WHERE ARCH_ID = :ARCH_ID");
25
  $stmt->execute([":ARCH_ID" => $archId]);
26
 }
27
}
28
29
$bd->commit();
30
31
devuelveNoContent();
32

F. api / producto-modifica.php

1
<?php
2
3
require_once __DIR__ . "/../libservidorphp/manejaErrores.php";
4
require_once __DIR__ . "/../libservidorphp/recibeEnteroObligatorio.php";
5
require_once __DIR__ . "/../libservidorphp/recibeTextoObligatorio.php";
6
require_once __DIR__ . "/../libservidorphp/recibeBytesOpcionales.php";
7
require_once __DIR__ . "/../libservidorphp/validaEntidadObligatoria.php";
8
require_once __DIR__ . "/../libservidorphp/devuelveJson.php";
9
require_once __DIR__ . "/Bd.php";
10
require_once __DIR__ . "/productoBusca.php";
11
12
$prodId = recibeEnteroObligatorio("id");
13
$nombre = recibeTextoObligatorio("nombre");
14
$bytes = recibeBytesOpcionales("imagen");
15
16
$bd = Bd::conexion();
17
$bd->beginTransaction();
18
19
$producto = productoBusca($bd, $prodId);
20
$producto = validaEntidadObligatoria("Producto",  $producto);
21
22
$archId = $producto["PRD_ARCH_ID"];
23
24
if ($bytes !== "") {
25
 if ($archId === null) {
26
  $archId = archivoAgrega($bd, $bytes);
27
 } else {
28
  $stmt = $bd->prepare(
29
   "UPDATE ARCHIVO
30
   SET
31
    ARCH_BYTES = :ARCH_BYTES
32
   WHERE
33
    ARCH_ID = :ARCH_ID"
34
  );
35
  $stmt->execute([
36
   ":ARCH_BYTES" => $bytes,
37
   ":ARCH_ID" => $archId,
38
  ]);
39
 }
40
}
41
42
$stmt = $bd->prepare(
43
 "UPDATE PRODUCTO
44
   SET
45
    PRD_NOMBRE = TRIM(:PRD_NOMBRE),
46
    PRD_ARCH_ID = :PRD_ARCH_ID
47
   WHERE
48
    PRD_ID = :PRD_ID"
49
);
50
$stmt->execute([
51
 ":PRD_NOMBRE" => $nombre,
52
 ":PRD_ARCH_ID" => $archId,
53
 ":PRD_ID" => $prodId,
54
]);
55
56
$bd->commit();
57
58
$queryArch = http_build_query(["id" => $archId]);
59
// Los bytes de las imágenes se descargan con "archivo.php"; no desde aquí.
60
devuelveJson([
61
 "id" => ["value" => $prodId],
62
 "nombre" => ["value" => $nombre],
63
 "imagen" => ["data-src" => $archId === "" ? "" : "api/archivo.php?$queryArch"]
64
]);
65

G. api / producto-vista-index.php

1
<?php
2
3
require_once __DIR__ . "/../libservidorphp/manejaErrores.php";
4
require_once __DIR__ . "/../libservidorphp/devuelveJson.php";
5
require_once __DIR__ . "/Bd.php";
6
7
$bd = Bd::conexion();
8
$stmt = $bd->query("SELECT * FROM PRODUCTO ORDER BY PRD_NOMBRE");
9
$lista = $stmt->fetchAll(PDO::FETCH_ASSOC);
10
11
$render = "";
12
foreach ($lista as $modelo) {
13
 $prodId = $modelo["PRD_ID"];
14
 $archId = $modelo["PRD_ARCH_ID"] === null ? "" : $modelo["PRD_ARCH_ID"];
15
 $query = htmlentities(http_build_query(["id" => $prodId]));
16
 $urlModifica = "modifica.html?$query";
17
 $queryArch = htmlentities(http_build_query(["id" => $archId]));
18
 $alt = $archId === "" ? "Sin imagen" : "Imagen del producto";
19
 $src = $archId === "" ? "" : "api/archivo.php?$queryArch";
20
 $prodNombre = htmlentities($modelo["PRD_NOMBRE"]);
21
 // Los bytes de las imágenes se descargan con "archivo.php"; no desde aquí.
22
 $render .=
23
  "<div style='display: flex; flex-direction: row-reverse;
24
      align-items: center; gap: 0.5rem'>
25
     <dt style='flex: 1 1 0'>
26
      <a href='$urlModifica'>$prodNombre</a>
27
     </dt>
28
     <dd style='flex: 1 1 0; margin: 0'>
29
      <a href='$urlModifica'><img
30
        style='width: 100%; aspect-ratio:16/9; object-fit: contain'
31
        alt=$alt src='$src'></a>
32
     </dd>
33
    </div>";
34
}
35
36
devuelveJson(["lista" => ["innerHTML" => $render]]);
37

H. api / producto-vista-modifica.php

1
<?php
2
3
require_once __DIR__ . "/../libservidorphp/manejaErrores.php";
4
require_once __DIR__ . "/../libservidorphp/recibeEnteroObligatorio.php";
5
require_once __DIR__ . "/../libservidorphp/validaEntidadObligatoria.php";
6
require_once __DIR__ . "/../libservidorphp/devuelveJson.php";
7
require_once __DIR__ . "/Bd.php";
8
require_once __DIR__ . "/productoBusca.php";
9
10
$prodId = recibeEnteroObligatorio("id");
11
12
$bd = Bd::conexion();
13
$modelo = productoBusca($bd, $prodId);
14
15
$modelo = validaEntidadObligatoria("Producto",  $modelo);
16
17
$archId = $modelo["PRD_ARCH_ID"] === null ? "" : $modelo["PRD_ARCH_ID"];
18
$queryArch = http_build_query(["id" => $archId]);
19
$src = $archId === "" ? "" : "api/archivo.php?$queryArch";
20
// Los bytes de las imágenes se descargan con "archivo.php"; no desde aquí.
21
devuelveJson([
22
 "id" => ["value" => $prodId],
23
 "nombre" => ["value" => $modelo["PRD_NOMBRE"]],
24
 "imagen" => ["data-src" => $src]
25
]);
26

I. api / productoBusca.php

1
<?php
2
3
function productoBusca(PDO $bd, int $prodId)
4
{
5
 $stmt = $bd->prepare("SELECT * FROM PRODUCTO WHERE PRD_ID = :PRD_ID");
6
 $stmt->execute([":PRD_ID" => $prodId]);
7
 $modelo = $stmt->fetch(PDO::FETCH_ASSOC);
8
 return $modelo;
9
}
10