public function archive_to_pathname(array $files, $archivefile,
            $ignoreinvalidfiles=true, file_progress $progress = null) {
        $ziparch = new zip_archive();
        if (!$ziparch->open($archivefile, file_archive::OVERWRITE)) {
            return false;
        }

        $abort = false;
        foreach ($files as $archivepath => $file) {
            $archivepath = trim($archivepath, '/');

            // Record progress each time around this loop.
            if ($progress) {
                $progress->progress();
            }

            if (is_null($file)) {
                // Directories have null as content.
                if (!$ziparch->add_directory($archivepath.'/')) {
                    debugging("Can not zip '$archivepath' directory", DEBUG_DEVELOPER);
                    if (!$ignoreinvalidfiles) {
                        $abort = true;
                        break;
                    }
                }

            } else if (is_string($file)) {
                if (!$this->archive_pathname($ziparch, $archivepath, $file, $progress)) {
                    debugging("Can not zip '$archivepath' file", DEBUG_DEVELOPER);
                    if (!$ignoreinvalidfiles) {
                        $abort = true;
                        break;
                    }
                }

            } else if (is_array($file)) {
                $content = reset($file);
                if (!$ziparch->add_file_from_string($archivepath, $content)) {
                    debugging("Can not zip '$archivepath' file", DEBUG_DEVELOPER);
                    if (!$ignoreinvalidfiles) {
                        $abort = true;
                        break;
                    }
                }

            } else {
                if (!$this->archive_stored($ziparch, $archivepath, $file, $progress)) {
                    debugging("Can not zip '$archivepath' file", DEBUG_DEVELOPER);
                    if (!$ignoreinvalidfiles) {
                        $abort = true;
                        break;
                    }
                }
            }
        }

        if (!$ziparch->close()) {
            @unlink($archivefile);
            return false;
        }

        if ($abort) {
            @unlink($archivefile);
            return false;
        }

        return true;
    }