K. Carpeta « php »

Versión para imprimir.

A. php / archivo.php

1
<?php
2
3
require_once __DIR__ . "/lib/recibeEnteroObligatorio.php";
4
require_once __DIR__ . "/lib/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::pdo();
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. php / 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. php / Bd.php

1
<?php
2
3
class Bd
4
{
5
 private static ?PDO $pdo = null;
6
7
 static function pdo(): 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 ARCH_PK
27
       PRIMARY KEY(ARCH_ID)
28
     )'
29
   );
30
   self::$pdo->exec(
31
    'CREATE TABLE IF NOT EXISTS PRODUCTO (
32
      PROD_ID INTEGER,
33
      PROD_NOMBRE TEXT NOT NULL,
34
      ARCH_ID INTEGER NOT NULL,
35
      CONSTRAINT PROD_PK
36
       PRIMARY KEY(PROD_ID),
37
      CONSTRAINT PROD_NOM_UNQ
38
       UNIQUE(PROD_NOMBRE),
39
      CONSTRAINT PROD_NOM_NV
40
       CHECK(LENGTH(PROD_NOMBRE) > 0),
41
      CONSTRAINT PROD_ARCH_FK
42
       FOREIGN KEY (ARCH_ID) REFERENCES ARCHIVO(ARCH_ID)
43
      )'
44
   );
45
  }
46
47
  return self::$pdo;
48
 }
49
}
50

D. php / producto-agrega.php

1
<?php
2
3
require_once __DIR__ . "/lib/manejaErrores.php";
4
require_once __DIR__ . "/lib/recibeTextoObligatorio.php";
5
require_once __DIR__ . "/lib/recibeBytesObligatorios.php";
6
require_once __DIR__ . "/lib/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::pdo();
14
$bd->beginTransaction();
15
16
$archId = archivoAgrega($bd, $bytes);
17
18
$stmt = $bd->prepare(
19
 "INSERT INTO PRODUCTO (
20
    PROD_NOMBRE, ARCH_ID
21
   ) values (
22
    :PROD_NOMBRE, :ARCH_ID
23
   )"
24
);
25
$stmt->execute([
26
 ":PROD_NOMBRE" => $nombre,
27
 ":ARCH_ID" => $archId
28
]);
29
$prodId = $bd->lastInsertId();
30
31
$bd->commit();
32
33
$encodeId = urlencode($prodId);
34
$encodeArchId = urlencode($archId);
35
$htmlEncodeArchId = htmlentities($encodeArchId);
36
// Los bytes de las imágenes se descargan con "archivo.php"; no desde aquí.
37
devuelveCreated("/php/producto-vista-modifica.php?id=$encodeId", [
38
 "id" => ["value" => $prodId],
39
 "nombre" => ["value" => $nombre],
40
 "imagen" => [
41
  "imagen" => [
42
   "data-src" => $htmlEncodeArchId === ""
43
    ? ""
44
    : "php/archivo.php?id=$htmlEncodeArchId"
45
  ]
46
 ]
47
]);
48

E. php / producto-elimina.php

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

F. php / producto-modifica.php

1
<?php
2
3
require_once __DIR__ . "/lib/manejaErrores.php";
4
require_once __DIR__ . "/lib/recibeEnteroObligatorio.php";
5
require_once __DIR__ . "/lib/recibeTextoObligatorio.php";
6
require_once __DIR__ . "/lib/recibeBytesOpcionales.php";
7
require_once __DIR__ . "/lib/validaEntidadObligatoria.php";
8
require_once __DIR__ . "/lib/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::pdo();
17
$bd->beginTransaction();
18
19
$producto = productoBusca($bd, $prodId);
20
$producto = validaEntidadObligatoria("Producto",  $producto);
21
22
$archId = $producto["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
    PROD_NOMBRE = :PROD_NOMBRE,
46
    ARCH_ID = :ARCH_ID
47
   WHERE
48
    PROD_ID = :PROD_ID"
49
);
50
$stmt->execute([
51
 ":PROD_NOMBRE" => $nombre,
52
 ":ARCH_ID" => $archId,
53
 ":PROD_ID" => $prodId,
54
]);
55
56
$bd->commit();
57
58
$encodeArchId = $archId === null ? "" : urlencode($archId);
59
$htmlEncodeArchId = htmlentities($encodeArchId);
60
// Los bytes de las imágenes se descargan con "archivo.php"; no desde aquí.
61
devuelveJson([
62
 "id" => ["value" => $prodId],
63
 "nombre" => ["value" => $nombre],
64
 "imagen" => [
65
  "data-src" => $htmlEncodeArchId === ""
66
   ? ""
67
   : "php/archivo.php?id=$htmlEncodeArchId"
68
 ]
69
]);
70

G. php / producto-vista-index.php

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

H. php / producto-vista-modifica.php

1
<?php
2
3
require_once __DIR__ . "/lib/manejaErrores.php";
4
require_once __DIR__ . "/lib/recibeEnteroObligatorio.php";
5
require_once __DIR__ . "/lib/validaEntidadObligatoria.php";
6
require_once __DIR__ . "/lib/devuelveJson.php";
7
require_once __DIR__ . "/Bd.php";
8
require_once __DIR__ . "/productoBusca.php";
9
10
$prodId = recibeEnteroObligatorio("id");
11
12
$bd = Bd::pdo();
13
$modelo = productoBusca($bd, $prodId);
14
15
$modelo = validaEntidadObligatoria("Producto",  $modelo);
16
17
$encodeArchId =
18
 $modelo["ARCH_ID"] === null ? "" : urlencode($modelo["ARCH_ID"]);
19
$htmlEncodeArchId = htmlentities($encodeArchId);
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["PROD_NOMBRE"]],
24
 "imagen" => [
25
  "data-src" => $htmlEncodeArchId === ""
26
   ? ""
27
   : "php/archivo.php?id=$htmlEncodeArchId"
28
 ]
29
]);
30

I. php / productoBusca.php

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

J. Carpeta « php / lib »

Versión para imprimir.

1. php / lib / BAD_REQUEST.php

1
<?php
2
3
const BAD_REQUEST = 400;
4

2. php / lib / devuelveCreated.php

1
<?php
2
3
require_once __DIR__ . "/devuelveResultadoNoJson.php";
4
5
function devuelveCreated($urlDelNuevo, $resultado)
6
{
7
 $json = json_encode($resultado);
8
 if ($json === false) {
9
  devuelveResultadoNoJson();
10
 } else {
11
  http_response_code(201);
12
  header("Location: $urlDelNuevo");
13
  header("Content-Type: application/json; charset=utf-8");
14
  echo $json;
15
 }
16
}
17

3. php / lib / devuelveJson.php

1
<?php
2
3
require_once __DIR__ . "/devuelveResultadoNoJson.php";
4
5
function devuelveJson($resultado)
6
{
7
 $json = json_encode($resultado);
8
 if ($json === false) {
9
  devuelveResultadoNoJson();
10
 } else {
11
  header("Content-Type: application/json; charset=utf-8");
12
  echo $json;
13
 }
14
 exit();
15
}
16

4. php / lib / devuelveNoContent.php

1
<?php
2
3
function devuelveNoContent()
4
{
5
 http_response_code(204);
6
}
7

5. php / lib / devuelveResultadoNoJson.php

1
<?php
2
3
require_once __DIR__ . "/INTERNAL_SERVER_ERROR.php";
4
5
function devuelveResultadoNoJson()
6
{
7
 http_response_code(INTERNAL_SERVER_ERROR);
8
 header("Content-Type: application/problem+json; charset=utf-8");
9
10
 echo '{' .
11
  "status: " . INTERNAL_SERVER_ERROR .
12
  '"title": "El resultado no puede representarse como JSON."' .
13
  '"type": "/errors/resultadonojson.html"' .
14
  '}';
15
}
16

6. php / lib / INTERNAL_SERVER_ERROR.php

1
<?php
2
3
const INTERNAL_SERVER_ERROR = 500;

7. php / lib / manejaErrores.php

1
<?php
2
3
require_once __DIR__ . "/INTERNAL_SERVER_ERROR.php";
4
require_once __DIR__ . "/ProblemDetailsException.php";
5
6
// Hace que se lance una excepción automáticamente cuando se genere un error.
7
set_error_handler(function ($severity, $message, $file, $line) {
8
 throw new ErrorException($message, 0, $severity, $file, $line);
9
});
10
11
// Código cuando una excepción no es atrapada.
12
set_exception_handler(function (Throwable $excepcion) {
13
 if ($excepcion instanceof ProblemDetailsException) {
14
  devuelveProblemDetails($excepcion->problemDetails);
15
 } else {
16
  devuelveProblemDetails([
17
   "status" => INTERNAL_SERVER_ERROR,
18
   "title" => "Error interno del servidor",
19
   "detail" => $excepcion->getMessage(),
20
   "type" => "/errors/errorinterno.html",
21
  ]);
22
 }
23
 exit();
24
});
25
26
function devuelveProblemDetails(array $array)
27
{
28
 $json = json_encode($array);
29
 if ($json === false) {
30
  devuelveResultadoNoJson();
31
 } else {
32
  http_response_code(isset($array["status"]) ? $array["status"] : 500);
33
  header("Content-Type: application/problem+json; charset=utf-8");
34
  echo $json;
35
 }
36
}
37

8. php / lib / NOT_FOUND.php

1
<?php
2
3
const NOT_FOUND = 404;
4

9. php / lib / ProblemDetailsException.php

1
<?php
2
3
require_once __DIR__ . "/INTERNAL_SERVER_ERROR.php";
4
5
/**
6
 * Detalle de los errores devueltos por un servicio.
7
 */
8
class ProblemDetailsException extends Exception
9
{
10
11
 public array $problemDetails;
12
13
 public function __construct(
14
  array $problemDetails,
15
 ) {
16
  
17
  parent::__construct(
18
   isset($problemDetails["detail"])
19
    ? $problemDetails["detail"]
20
    : (isset($problemDetails["title"])
21
     ? $problemDetails["title"]
22
     : "Error"),
23
   $problemDetails["status"]
24
    ? $problemDetails["status"]
25
    : INTERNAL_SERVER_ERROR
26
  );
27
28
  $this->problemDetails = $problemDetails;
29
 }
30
}
31

10. php / lib / recibeBytes.php

1
<?php
2
3
require_once __DIR__ . "/INTERNAL_SERVER_ERROR.php";
4
require_once __DIR__ . "/BAD_REQUEST.php";
5
require_once __DIR__ . "/ProblemDetailsException.php";
6
7
function recibeBytes(string $parametro)
8
{
9
 if (isset($_FILES[$parametro])) {
10
11
  $path = $_FILES[$parametro]["tmp_name"];
12
13
  if ($path === "") {
14
15
   return "";
16
  } elseif (is_uploaded_file($path)) {
17
18
   $contents = file_get_contents($path);
19
20
   if ($contents === false) {
21
22
    switch ($_FILES[$parametro]['error']) {
23
24
     case UPLOAD_ERR_OK:
25
26
      return $contents;
27
28
     case UPLOAD_ERR_INI_SIZE:
29
     case UPLOAD_ERR_FORM_SIZE:
30
31
      throw new ProblemDetailsException([
32
       "status" => BAD_REQUEST,
33
       "title" => "Archivo demasiado largo.",
34
       "type" => "/errors/archivodemasiadolargo.html",
35
       "detail" => "El archivo " - $parametro .
36
        " excede el tamaño máximo que el servidor puede recibir."
37
      ]);
38
39
     case UPLOAD_ERR_PARTIAL:
40
      throw new ProblemDetailsException([
41
       "status" => INTERNAL_SERVER_ERROR,
42
       "title" => "Carga incompleta de archivo.",
43
       "type" => "/errors/archivocargaincompleta.html",
44
       "detail" => "Por una razón desconocida, el archivo " - $parametro .
45
        " no se cargó completamente."
46
      ]);
47
48
     case UPLOAD_ERR_NO_FILE:
49
50
      throw creaArchivoNoRecibido($parametro);
51
52
     case UPLOAD_ERR_NO_TMP_DIR:
53
54
      throw new ProblemDetailsException([
55
       "status" => INTERNAL_SERVER_ERROR,
56
       "title" => "Falta la carpeta temporal.",
57
       "type" => "/errors/faltacarpetatemporal.html",
58
       "detail" => "Por una razón desconocida, falta la carpeta temporal " .
59
        "para cargar el archivo $parametro."
60
      ]);
61
62
     case UPLOAD_ERR_CANT_WRITE:
63
64
      throw new ProblemDetailsException([
65
       "status" => INTERNAL_SERVER_ERROR,
66
       "title" => "El archivo no se guardó.",
67
       "type" => "/errors/archivonoguardado.html",
68
       "detail" => "Por una razón desconocida, el archivo " - $parametro .
69
        " no se pudo guardar en disco."
70
      ]);
71
72
     case UPLOAD_ERR_EXTENSION:
73
74
      throw new ProblemDetailsException([
75
       "status" => BAD_REQUEST,
76
       "title" => "Extensión no permitida.",
77
       "type" => "/errors/extensionprohibida.html",
78
       "detail" => "La extensión del archivo " - $parametro .
79
        " no está permitida en el servidor."
80
      ]);
81
82
     default:
83
84
      throw new ProblemDetailsException([
85
       "status" => INTERNAL_SERVER_ERROR,
86
       "title" => "Error no identificado recuperando el archivo.",
87
       "type" => "/errors/errorrecuperandoarchivo.html",
88
       "detail" => "Por una razón desconocida, el archivo " - $parametro .
89
        " no se pudo recuperar."
90
      ]);
91
    }
92
   } else {
93
94
    return $contents;
95
   }
96
  } else {
97
98
   throw creaArchivoNoRecibido($parametro);
99
  }
100
 } else {
101
  return false;
102
 }
103
}
104
105
function creaArchivoNoRecibido(string $parametro)
106
{
107
 return new ProblemDetailsException([
108
  "status" => BAD_REQUEST,
109
  "title" => "Archivo no recibido.",
110
  "type" => "/errors/archivonorecibido.html",
111
  "detail" => "El archivo $parametro no fué recibido por el servidor."
112
 ]);
113
}
114

11. php / lib / recibeBytesObligatorios.php

1
<?php
2
3
require_once __DIR__ . "/BAD_REQUEST.php";
4
require_once __DIR__ . "/recibeBytes.php";
5
require_once __DIR__ . "/ProblemDetailsException.php";
6
7
function recibeBytesObligatorios(string $parametro)
8
{
9
 $bytes = recibeBytes($parametro);
10
11
 if ($bytes === false)
12
  throw new ProblemDetailsException([
13
   "status" => BAD_REQUEST,
14
   "title" => "Falta el valor $parametro.",
15
   "type" => "/errors/faltavalor.html",
16
   "detail" => "La solicitud no tiene el valor de $parametro."
17
  ]);
18
19
 if ($bytes === "")
20
  throw new ProblemDetailsException([
21
   "status" => BAD_REQUEST,
22
   "title" => "Archivo no seleccionado o vacío para el campo $parametro.",
23
   "type" => "/errors/archivovacio.html",
24
   "detail" => "Selecciona un archivo que no esté vacío en el campo $parametro."
25
  ]);
26
27
 return $bytes;
28
}
29

12. php / lib / recibeBytesOpcionales.php

1
<?php
2
3
require_once __DIR__ . "/recibeBytes.php";
4
5
function recibeBytesOpcionales(string $parametro)
6
{
7
 $enteroOpcional = recibeBytes($parametro);
8
 return $enteroOpcional === false ? "" : $enteroOpcional;
9
}
10

13. php / lib / recibeEntero.php

1
<?php
2
3
require_once __DIR__ . "/recibeTexto.php";
4
5
/**
6
 * Devuelve el valor entero de un parámetro recibido en el
7
 * servidor por medio de GET, POST o cookie.
8
 * 
9
 * Si el parámetro no se recibe, devuelve false
10
 *
11
 * Si se recibe una cadena vacía, se devuelve null.
12
 * 
13
 * Si parámetro no se puede convertir a entero, se genera
14
 * un error.
15
 */
16
function recibeEntero(string $parametro): false|null|int
17
{
18
 $valor = recibeTexto($parametro);
19
 if ($valor === false) {
20
  return false;
21
 } else {
22
  $valor = trim($valor);
23
  if ($valor === "") {
24
   return null;
25
  } else {
26
   return (int) $valor;
27
  }
28
 }
29
}
30

14. php / lib / recibeEnteroObligatorio.php

1
<?php
2
3
require_once __DIR__ . "/BAD_REQUEST.php";
4
require_once __DIR__ . "/recibeEntero.php";
5
require_once __DIR__ . "/ProblemDetailsException.php";
6
7
function recibeEnteroObligatorio(string $parametro)
8
{
9
 $entero = recibeEntero($parametro);
10
11
 if ($entero === false)
12
  throw new ProblemDetailsException([
13
   "status" => BAD_REQUEST,
14
   "title" => "Falta el valor $parametro.",
15
   "type" => "/errors/faltavalor.html",
16
   "detail" => "La solicitud no tiene el valor de $parametro."
17
  ]);
18
19
 if ($entero === null)
20
  throw new ProblemDetailsException([
21
   "status" => BAD_REQUEST,
22
   "title" => "Campo $parametro en blanco.",
23
   "type" => "/errors/campoenteroenblanco.html",
24
   "detail" => "Pon un número entero en el campo $parametro."
25
  ]);
26
27
 return $entero;
28
}
29

15. php / lib / recibeEnteroOpcional.php

1
<?php
2
3
require_once __DIR__ . "/recibeEntero.php";
4
5
function recibeEnteroOpcional(string $parametro)
6
{
7
 $enteroOpcional = recibeEntero($parametro);
8
 return $enteroOpcional === false ? null : $enteroOpcional;
9
}
10

16. php / lib / recibeTexto.php

1
<?php
2
3
/**
4
 * Devuelve el texto de un parámetro enviado al
5
 * servidor por medio de GET, POST o cookie.
6
 * 
7
 * Si el parámetro no se recibe, devuelve false.
8
 */
9
function recibeTexto(string $parametro): false|string
10
{
11
 /* Si el parámetro está asignado en $_REQUEST,
12
  * devuelve su valor; de lo contrario, devuelve false.
13
  */
14
 $valor = isset($_REQUEST[$parametro])
15
  ? $_REQUEST[$parametro]
16
  : false;
17
 return $valor;
18
}
19

17. php / lib / recibeTextoObligatorio.php

1
<?php
2
3
require_once __DIR__ . "/BAD_REQUEST.php";
4
require_once __DIR__ . "/recibeTexto.php";
5
require_once __DIR__ . "/ProblemDetailsException.php";
6
7
function recibeTextoObligatorio(string $parametro)
8
{
9
 $texto = recibeTexto($parametro);
10
11
 if ($texto === false)
12
  throw new ProblemDetailsException([
13
   "status" => BAD_REQUEST,
14
   "title" => "Falta el valor $parametro.",
15
   "type" => "/errors/faltavalor.html",
16
   "detail" => "La solicitud no tiene el valor de $parametro."
17
  ]);
18
19
 $trimTexto = trim($texto);
20
21
 if ($trimTexto === "")
22
  throw new ProblemDetailsException([
23
   "status" => BAD_REQUEST,
24
   "title" => "Campo $parametro en blanco.",
25
   "type" => "/errors/campoenblanco.html",
26
   "detail" => "Pon texto en el campo $parametro."
27
  ]);
28
29
 return $trimTexto;
30
}
31

18. php / lib / validaEntidadObligatoria.php

1
<?php
2
3
require_once __DIR__ . "/NOT_FOUND.php";
4
require_once __DIR__ . "/ProblemDetailsException.php";
5
6
function validaEntidadObligatoria(string $nombre,  $entidad)
7
{
8
9
 if ($entidad === false)
10
  throw new ProblemDetailsException([
11
  "status" => NOT_FOUND,
12
  "title" => "Registro de $nombre no encontrado.",
13
  "type" => "/errors/entidadnoencontrada.html",
14
  "detail" => "No se encontró ningún registro de $nombre con el id solicitado.",
15
  ]);
16
17
 return $entidad;
18
}
19