Grav\Plugin\Admin\AdminBaseController::taskFilesUpload PHP Method

taskFilesUpload() public method

Stores in a flash object the temporary file and deals with potential file errors.
public taskFilesUpload ( ) : boolean
return boolean True if the action was performed.
    public function taskFilesUpload()
    {
        if (!$this->authorizeTask('save', $this->dataPermissions()) || !isset($_FILES)) {
            return false;
        }
        /** @var Config $config */
        $config = $this->grav['config'];
        $data = $this->view == 'pages' ? $this->admin->page(true) : $this->prepareData([]);
        $settings = $data->blueprints()->schema()->getProperty($this->post['name']);
        $settings = (object) array_merge(['avoid_overwriting' => false, 'random_name' => false, 'accept' => ['image/*'], 'limit' => 10, 'filesize' => $config->get('system.media.upload_limit', 5242880)], (array) $settings, ['name' => $this->post['name']]);
        $upload = $this->normalizeFiles($_FILES['data'], $settings->name);
        if (!isset($settings->destination)) {
            $this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.DESTINATION_NOT_SPECIFIED', null)];
            return false;
        }
        // Do not use self@ outside of pages
        if ($this->view != 'pages' && in_array($settings->destination, ['@self', 'self@'])) {
            $this->admin->json_response = ['status' => 'error', 'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_PREVENT_SELF', null), $settings->destination)];
            return false;
        }
        // Handle errors and breaks without proceeding further
        if ($upload->file->error != UPLOAD_ERR_OK) {
            $this->admin->json_response = ['status' => 'error', 'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_UPLOAD', null), $upload->file->name, $this->upload_errors[$upload->file->error])];
            return false;
        } else {
            // Remove the error object to avoid storing it
            unset($upload->file->error);
            // we need to move the file at this stage or else
            // it won't be available upon save later on
            // since php removes it from the upload location
            $tmp_dir = Admin::getTempDir();
            $tmp_file = $upload->file->tmp_name;
            $tmp = $tmp_dir . '/uploaded-files/' . basename($tmp_file);
            Folder::create(dirname($tmp));
            if (!move_uploaded_file($tmp_file, $tmp)) {
                $this->admin->json_response = ['status' => 'error', 'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_MOVE', null), '', $tmp)];
                return false;
            }
            $upload->file->tmp_name = $tmp;
        }
        // Handle file size limits
        $settings->filesize *= 1048576;
        // 2^20 [MB in Bytes]
        if ($settings->filesize > 0 && $upload->file->size > $settings->filesize) {
            $this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT')];
            return false;
        }
        // Handle Accepted file types
        // Accept can only be mime types (image/png | image/*) or file extensions (.pdf|.jpg)
        $accepted = false;
        $errors = [];
        foreach ((array) $settings->accept as $type) {
            // Force acceptance of any file when star notation
            if ($type == '*') {
                $accepted = true;
                break;
            }
            $isMime = strstr($type, '/');
            $find = str_replace('*', '.*', $type);
            $match = preg_match('#' . $find . '$#', $isMime ? $upload->file->type : $upload->file->name);
            if (!$match) {
                $message = $isMime ? 'The MIME type "' . $upload->file->type . '"' : 'The File Extension';
                $errors[] = $message . ' for the file "' . $upload->file->name . '" is not an accepted.';
                $accepted |= false;
            } else {
                $accepted |= true;
            }
        }
        if (!$accepted) {
            $this->admin->json_response = ['status' => 'error', 'message' => implode('<br />', $errors)];
            return false;
        }
        // Retrieve the current session of the uploaded files for the field
        // and initialize it if it doesn't exist
        $sessionField = base64_encode($this->grav['uri']->url());
        $flash = $this->admin->session()->getFlashObject('files-upload');
        if (!$flash) {
            $flash = [];
        }
        if (!isset($flash[$sessionField])) {
            $flash[$sessionField] = [];
        }
        if (!isset($flash[$sessionField][$upload->field])) {
            $flash[$sessionField][$upload->field] = [];
        }
        // Set destination
        $destination = Folder::getRelativePath(rtrim($settings->destination, '/'));
        $destination = $this->admin->getPagePathFromToken($destination);
        // Create destination if needed
        if (!is_dir($destination)) {
            Folder::mkdir($destination);
        }
        // Generate random name if required
        if ($settings->random_name) {
            // TODO: document
            $extension = pathinfo($upload->file->name)['extension'];
            $upload->file->name = Utils::generateRandomString(15) . '.' . $extension;
        }
        // Handle conflicting name if needed
        if ($settings->avoid_overwriting) {
            // TODO: document
            if (file_exists($destination . '/' . $upload->file->name)) {
                $upload->file->name = date('YmdHis') . '-' . $upload->file->name;
            }
        }
        // Prepare object for later save
        $path = $destination . '/' . $upload->file->name;
        $upload->file->path = $path;
        // $upload->file->route = $page ? $path : null;
        // Prepare data to be saved later
        $flash[$sessionField][$upload->field][$path] = (array) $upload->file;
        // Finally store the new uploaded file in the field session
        $this->admin->session()->setFlashObject('files-upload', $flash);
        $this->admin->json_response = ['status' => 'success', 'session' => \json_encode(['sessionField' => base64_encode($this->grav['uri']->url()), 'path' => $upload->file->path, 'field' => $settings->name])];
        return true;
    }