HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhost/disk-apps/comfama.sports-crowd.com/app/Http/Controllers/ZapSignController.php
<?php

namespace App\Http\Controllers;

use App\Services\AcademyDocumentService;
use App\Services\AcademyService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;

class ZapSignController extends Controller
{

    private $academyDocumentService;
    private $academyService;

    public function __construct()
    {
        $this->academyDocumentService = new AcademyDocumentService;
        $this->academyService = new AcademyService;
    }

    public function autocomplete(Request $request)
    {
        $data = $this->mapDataDocument($request);
        return $this->createDocument($data);
    }

    public function webhooksListener(Request $request)
    {
        header('Content-Type: application/json');
        $utilController = new UtilController;
        $utilController->logFile($request, 'zapsign');

        $content = json_decode($request->getContent(), true);
        if (!$content) {
            return array('r' => false, 'm' => __('messages.error_updating'));
        }

        $answers = $this->findValueByKey($content, 'answers');
        $webhook = $this->findValueByValueKey($answers, 'webhook');
        if ($webhook) {
            $webhook = Crypt::decrypt($webhook);
            if (!str_contains($webhook, $request->getSchemeAndHttpHost())) {
                $this->resendWebhook($webhook, $request);
                return;
            }
        }

        $user = $this->findValueByValueKey($answers, 'id');
        if ($user) {
            $user = Crypt::decrypt($user);
        }

        $document = $this->findValueByValueKey($answers, 'document');
        if ($document) {
            $document = Crypt::decrypt($document);
        }

        $signed_file = $this->findValueByKey($content, 'signed_file');

        if (!$user || !$document || !$signed_file) {
            return array('r' => false, 'm' => __('messages.error_updating'));
        }

        $parameters                     = new \stdClass();
        $parameters->user               = $user;
        $parameters->document           = $document;
        $parameters->file               = $this->convertUrltoBase64($signed_file);
        $parameters->extension          = $this->convertUrltoExtension($signed_file);
        return $this->academyDocumentService->uploadUserAcademyDocumentExternal($parameters);
    }

    private function resendWebhook($webhook, $request)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $webhook);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getContent());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);
        curl_close($ch);
    }

    private function mapDataDocument($request)
    {
        $templateId = $this->academyDocumentService->getExternalFormId($request->get('documentId'));
        $params = $this->encryptParamsData($request);

        $user = $request->user() ?? Auth::user();
        $signer = $user ? $user->first_name . ' ' . $user->last_name : 'ZapSign';
        $data = [
            "template_id"               => $templateId,
            "signer_name"               => $signer,
            "send_automatic_email"      => false,
            "send_automatic_whatsapp"   => false,
            "lang"                      => "en-us",
            "external_id"               => null,
            "data"                      => $params
        ];
        return $data;
    }

    private function encryptParamsData($request)
    {
        $data = [];
        $data[] = [
            'de'    => 'webhook',
            'para'  => Crypt::encrypt($request->getSchemeAndHttpHost() . '/api/zapsign/webhooksListener')
        ];
        $data[] = [
            'de'    => 'id',
            'para'  => Crypt::encrypt($request->get('academyUserId'))
        ];
        $data[] = [
            'de'    => 'document',
            'para'  => Crypt::encrypt($request->get('documentId'))
        ];

        $academyUser = $this->academyService->find($request->get('academyUserId'));
        $data[] = [
            'de'    => 'estudiante',
            'para'  => $academyUser->student_name . ' ' . $academyUser->student_last_name
        ];
        $data[] = [
            'de'    => 'identificacion_estudiante',
            'para'  => $academyUser->identification
        ];
        $data[] = [
            'de'    => 'responsable',
            'para'  => $academyUser->advisor_name . ' ' . $academyUser->advisor_last_name
        ];
        $data[] = [
            'de'    => 'identificacion_responsable',
            'para'  => $academyUser->advisor_identification
        ];
        $data[] = [
            'de'    => 'correo_responsable',
            'para'  => $academyUser->mail
        ];
        $data[] = [
            'de'    => 'telefono_responsable',
            'para'  => $academyUser->phone
        ];
        return $data;
    }

    private function createDocument($data)
    {
        try {
            $client = new \GuzzleHttp\Client();
            $response = $client->post(config('zapsign.api') . "/api/v1/models/create-doc/", [
                'headers' => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . config('zapsign.token')
                ],
                'body'              => json_encode($data),
            ]);

            $body = $response->getBody()->getContents();
            $body = json_decode($body, true);
            return $this->mapResponse($body);
        } catch (\Exception $e) {
            return response(array("r" => false, "m" => $e->getMessage()));
        }
    }

    private function mapResponse($body)
    {
        $link = $this->findValueByKey($body, 'sign_url');
        if ($link) {
            return response(array("r" => true, "d" => $link, "m" => 'Sign url found successfully'));
        } else {
            return response(array("r" => false, "m" => 'Sign url not found'));
        }
    }

    private function findValueByKey($jsonObject, $searchKey)
    {
        // Check if the key exists at the top level
        if (array_key_exists($searchKey, $jsonObject)) {
            return $jsonObject[$searchKey];
        }

        // Iterate through the object/array and search recursively
        foreach ($jsonObject as $key => $value) {
            if (is_array($value)) {
                $result = $this->findValueByKey($value, $searchKey);
                if ($result !== null) {
                    return $result;
                }
            }
        }

        return null; // Return null if the key is not found
    }

    private function findValueByValueKey($data, $key)
    {
        $value;
        foreach ($data as $item) {
            if ($item['variable'] == $key) {
                $value = $item['value'];
            }
        }
        return $value;
    }

    private function convertUrltoBase64($url)
    {
        return chunk_split(base64_encode(file_get_contents($url)));
    }

    private function convertUrltoExtension($url)
    {
        return pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
    }
}