<?php
/**
*
* @About: API Interface
* @File: index.php
* @Date: $Date:$ Agosot0 -2022
* @Version: $Rev:$ 1.0
* @Developer: Federico Guzman || Modificado por Fernando Humanes para PHP 8.1
**/
/* Los headers permiten acceso desde otro dominio (CORS) a nuestro REST API o desde un cliente remoto via HTTP
* Removiendo las lineas header() limitamos el acceso a nuestro RESTfull API a el mismo dominio
* Nótese los métodos permitidos en Access-Control-Allow-Methods. Esto nos permite limitar los métodos de consulta a nuestro RESTfull API
* Mas información: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
**/
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS');
header("Access-Control-Allow-Headers: X-Requested-With");
header('Content-Type: text/html; charset=utf-8');
header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"');
include_once '../include/Config.php';
require_once("../../include/dbcommon.php"); // DataBase PHPRunner
$debugCode = true; // for Debug
custom_error(1,"Se inicia el Proceso de Conversión"); // To debug
$post = $_POST;
unset($post['file']); // Quitamos este dato porque es muy grande
custom_error(2,"Variable $_POST: ".json_encode($post)); // To debug
// use App\Models\Db; // Utilizamos la conexión de PHPRunner
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Selective\BasePath\BasePathMiddleware;
use Slim\Factory\AppFactory;
require_once __DIR__ . '/../include/slim_4.11.0/autoload.php';
$app = AppFactory::create();
$app->addRoutingMiddleware();
// $app->add(new BasePathMiddleware($app)); // No usar si se ejecuta en subdirectorio
$app->addErrorMiddleware(true, true, true);
$app->addBodyParsingMiddleware();
$app->setBasePath(SCRIPTS_DIR);
// --------------------------------------------------------------------------------------
/* Usando POST para convertir fichero */
$app->post('/document', function(Request $request, Response $response) {
$startConvert = date("Y-m-d H:i:s");; // marcar fecha de inicio
// Verify Token Security
$verify = authenticate($request, $response);
if (is_array($verify)) { // Si es una array, es que hay error
$response->getBody()->write(json_encode($verify));
return $response
->withHeader('content-type', 'application/json')
->withStatus(400);
}
// check for required params
$verify = verifyRequiredParams(array('name', 'file','option'), $request, $response);
if (is_array($verify)) { // Si es una array, es que hay error
$response->getBody()->write(json_encode($verify));
return $response
->withHeader('content-type', 'application/json')
->withStatus(400);
}
$data = $request->getParsedBody();
$BlobInput=base64_decode($data['file']); // Convert Base64
$part_file = explode(".", $data['name']); // name file
$ExtensionFile = $part_file[(count($part_file)-1)]; // Tipo file
$new_file = substr($data['name'],0,(strlen($data['name'])-strlen($ExtensionFile)-1)).".pdf";
$option = $data['option']; // Option convert Opffice_to_PDF
// -------------------- for create temporaly file --------------------------
$temp_file = tempnam(sys_get_temp_dir(), 'temp');
$part_path = pathinfo($temp_file);
$temp_file1 = $part_path['dirname'].'/'.$part_path['filename'].'.'.$ExtensionFile;
$phpLog = $part_path['dirname'].'/phplog.txt'; // Trace of Debug code
$fp = fopen($temp_file1, 'w');
$fwrite = fwrite($fp, $BlobInput);
fclose($fp);
$sizeFile = filesize($temp_file1);
$temp_file2 = $part_path['dirname'].'/'.$part_path['filename'].'.pdf';
do { // Para dotar de mútiples bloqueos
$action = false; // Indica que falta la conversión
$limint_block = 5;
for ($i=0;$i< $limint_block ; $i++) { // El Límite fija el número de procesos concurrentes
$fileLock = $part_path['dirname'].'/lockConvert_'.$i.'.txt';
if (!file_exists($fileLock)) { // Si no existe, se crea
$fpLock = fopen("$fileLock", "w");
fclose($fpLock);
}
custom_error(3,"Fichero de bloque: ".$fileLock); // To debug
$fp = fopen($fileLock, "r+"); // Fichero de bloqueos para que sólo haya una única ejecución
// do { // Bucle de conversión copn control de que sólo un proceso puede estar en ejecución
if (flock($fp, LOCK_EX)) { // adquirir un bloqueo exclusivo
// Convert to PDF
custom_error(4,"Iniciamos conversión de : ".$temp_file1." con bloqueo. ".$fileLock); // To debug
// $result = shell_exec("..\\Office_to_PDF\\OfficeToPDF.exe $temp_file1 $temp_file2");
$status = exec("..\\Office_to_PDF\\OfficeToPDF.exe $option $temp_file1 $temp_file2", $outputCommand, $result);
if ($result <> 0) {
// LOG
$a = "Resultado de conversion: ".$result."\n".var_export($outputCommand, true)." \n";
file_put_contents($phpLog, $a, FILE_APPEND | LOCK_EX);
}
flock($fp, LOCK_UN); // libera el bloqueo
custom_error(5,"Termina conversión de : ".$temp_file1." con bloqueo. ".$fileLock); // To debug
$action = true; // Se ha hecho la conersión
break;
}
// } while (true);
fclose($fp);
}
if ($action) { break; } // Se termina. Se ha hecho conversión
custom_error(6,"Espera en cola fichero: ".$temp_file1); // To debug
sleep(1);
} while (true);
// ------------------ Operation with file result -------------------------------------------
$document = file_get_contents($temp_file2);
unlink($temp_file); // delete file tmp
unlink($temp_file1); // delete file tmp
unlink($temp_file2); // delete file tmp
$responseBody = array();
//capturamos los parametros recibidos y los almacxenamos como un nuevo array
$param['name'] = $new_file;
$param['file'] = base64_encode($document);
// Write LOG
$data = array();
$data["nameFile"] = $new_file;
$data["sizeFile"] = $sizeFile;
$data["startConvert"] = $startConvert;
$data["endConvert"] = date("Y-m-d H:i:s");
DB::Insert("server_pdf_log", $data );
if ( is_array($param) ) {
$responseBody["error"] = false;
$responseBody["message"] = "Documento convertido satisfactoriamente!";
$responseBody["document"] = $param;
$response->getBody()->write(json_encode($responseBody));
return $response
->withHeader('content-type', 'application/json')
->withStatus(200);
} else {
$responseBody["error"] = true;
$responseBody["message"] = "Error al crear auto. Por favor intenta nuevamente.";
$response->getBody()->write(json_encode($responseBody));
return $response
->withHeader('content-type', 'application/json')
->withStatus(400);
}
});
/* corremos la aplicación */
$app->run();
/*********************** USEFULL FUNCTIONS **************************************/
/**
* Verificando los parametros requeridos en el metodo
*/
function verifyRequiredParams($required_fields, Request $request, Response $response)
{
$error = false;
$error_fields = "";
$request_params = $request->getParsedBody();
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields .= $field . ', ';
}
}
if ($error) {
// Required field(s) are missing or empty
// echo error json and stop the app
$responseBody = array();
$responseBody["error"] = true;
$responseBody["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
return $responseBody;
}
return true;
}
/**
* Validando parametro email si necesario; un Extra ;)
*/
function validateEmailRest($email, Request $request, Response $response)
{
$responseBody = array();
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$responseBody["error"] = true;
$responseBody["message"] = 'Email address is not valid';
return $responseBody;
}
return true;
}
/**
* Revisa si la consulta contiene un Header "Authorization" para validar
*/
function authenticate(Request $request, Response $response)
{
// Getting request headers
$headers = $request->getHeaders();
// Verifying Authorization Header
if (isset($headers['Authorization'])) {
// get the api key
$token = $headers['Authorization'];
// validating api key
if (!($token[0] == API_KEY)) { //API_KEY declarada en Config.php
// api key is not present in users table
$responseBody["error"] = true;
$responseBody["message"] = "Acceso denegado. Token inválido";
// Error 401
return $responseBody;
} else {
//procede utilizar el recurso o metodo del llamado
return true;
}
} else {
// api key is missing in header
$responseBody["error"] = true;
$responseBody["message"] = "Falta token de autorización";
// error 400
return $responseBody;
}
}
?>