<?php

defined('C5_EXECUTE') or die("Access Denied.");

use \Concrete\Core\File\EditResponse as FileEditResponse;
use Concrete\Core\Support\Facade\Application;

$app = Application::getFacadeApplication();

$u = new User();

$cf = $app->make('helper/file');
$fp = FilePermissions::getGlobal();
if (!$fp->canAddFiles()) {
    die(t("Unable to add files."));
}

$error = $app->make('helper/validation/error');

if (isset($_REQUEST['fID'])) {
    // we are replacing a file
    $fr = File::getByID($_REQUEST['fID']);
    $frp = new Permissions($fr);
    if (!$frp->canEditFileContents()) {
        $error->add(t('You do not have permission to modify this file.'));
    }
} else {
    $fr = false;
}

$r = new FileEditResponse();

$valt = $app->make('helper/validation/token');
$file = $app->make('helper/file');
$app->make('helper/mime');

// load all the incoming fields into an array
$incoming_urls = array();

if (!function_exists('iconv_get_encoding')) {
    $error->add(t('Remote URL import requires the iconv extension enabled on your server.'));
}

if (!$error->has()) {
    for ($i = 1; $i < 6; ++$i) {
        $this_url = trim($_REQUEST['url_upload_' .$i]);

        // did we get anything?
        if (!strlen($this_url)) {
            continue;
        }

        // validate URL
        try {
            $url = \Concrete\Core\Url\Url::createFromUrl($this_url);
            if (!$url->getHost() || in_array($url->getHost(), ['localhost', '127.0.0.1'])) {
                throw new \InvalidArgumentException(t('Invalid URL: %s', $this_url));
            }

            $client = $app->make('http/client');
            $request = $client->getRequest();
            $request->setUri((string) $url);
            $response = $client->send();
            $incoming_urls[] = $this_url;
        } catch (\Exception $e) {
            $error->add(t('Failed to access "%s"', h($this_url)));
        }
    }

    if (!$valt->validate('import_remote')) {
        $$error->add($valt->getErrorMessage());
    }

    if (count($incoming_urls) < 1) {
        $error->add(t('You must specify at least one valid URL.'));
    }
}

$import_responses = array();
$files = array();

// if we haven't gotten any errors yet then try to process the form
if (!$error->has()) {
    // itterate over each incoming URL adding if relevant
    foreach ($incoming_urls as $this_url) {
        // try to D/L the provided file
        $client = $app->make('http/client');
        $request = $client->getRequest();
        $request->setUri($this_url);
        $response = $client->send();
        if ($response->isSuccess()) {
            $headers = $response->getHeaders();
            $contentType = $headers->get('ContentType')->getFieldValue();

            $fpath = $file->getTemporaryDirectory();

            // figure out a filename based on filename, mimetype, ???
            if (preg_match('/^.+?[\\/]([-\w%]+\.[-\w%]+)$/', $request->getUri(), $matches)) {
                // got a filename (with extension)... use it
                $fname = $matches[1];
            } elseif ($contentType) {
                // use mimetype from http response
                $fextension = $app->make('helper/mime')->mimeToExtension($contentType);
                if ($fextension === false) {
                    $error->add(t('Unknown mime-type: %s', h($contentType)));
                } else {
                    // make sure we're coming up with a unique filename
                    do {
                        // make up a filename based on the current date/time, a random int, and the extension from the mime-type
                        $fname = date('Y-m-d_H-i_') . mt_rand(100, 999) . '.' . $fextension;
                    } while (file_exists($fpath.'/'.$fname));
                }
            } //else {
                // if we can't get the filename from the file itself OR from the mime-type I'm not sure there's much else we can do
            //}

            if (strlen($fname)) {
                // write the downloaded file to a temporary location on disk
                $handle = fopen($fpath.'/'.$fname, "w");
                fwrite($handle, $response->getBody());
                fclose($handle);

                // import the file into concrete
                if ($fp->canAddFileType($cf->getExtension($fname))) {

                    $folder = null;
                    if (isset($_POST['currentFolder'])) {
                        $node = \Concrete\Core\Tree\Node\Node::getByID($_POST['currentFolder']);
                        if ($node instanceof \Concrete\Core\Tree\Node\Type\FileFolder) {
                            $folder = $node;
                        }
                    }

                    if (!$fr && $folder) {
                        $fr = $folder;
                    }

                    $fi = new FileImporter();
                    $resp = $fi->import($fpath.'/'.$fname, $fname, $fr);
                    $r->setMessage(t('File uploaded successfully.'));
                    if (is_object($fr)) {
                        $r->setMessage(t('File replaced successfully.'));
                    }
                } else {
                    $resp = FileImporter::E_FILE_INVALID_EXTENSION;
                }
                if (!($resp instanceof \Concrete\Core\Entity\File\Version)) {
                    $error->add($fname . ': ' . FileImporter::getErrorMessage($resp));
                } else {
                    $import_responses[] = $resp;

                    if (!($fr instanceof \Concrete\Core\Entity\File\Version)) {
                        // we check $fr because we don't want to set it if we are replacing an existing file
                        $respf = $resp->getFile();
                        $respf->setOriginalPage($_POST['ocID']);
                        $files[] = $respf;
                    } else {
                        $respf = $fr;
                    }
                }

                // clean up the file
                unlink($fpath.'/'.$fname);
            } else {
                // could not figure out a file name
                $error->add(t(/*i18n: %s is an URL*/'Could not determine the name of the file at %s', h($this_url)));
            }
        } else {
            // warn that we couldn't download the file
            $error->add(t(/*i18n: %s is an URL*/'There was an error downloading %s', h($this_url)));
        }
    }
}

$r->setError($error);
$r->setFiles($files);
$r->outputJSON();
