public function add_file_from_string($localname, $contents) {
        if ($this->emptyziphack) {
            $this->close();
            $this->open($this->archivepathname, file_archive::OVERWRITE, $this->encoding);
        }

        if (!isset($this->za)) {
            return false;
        }

        $localname = trim($localname, '/'); // No leading slashes in archives!
        $localname = $this->mangle_pathname($localname);

        if ($localname === '') {
            // Sorry - conversion failed badly.
            return false;
        }

        if ($this->usedmem > 2097151) {
            // This prevents running out of memory when adding many large files using strings.
            $this->close();
            $res = $this->open($this->archivepathname, file_archive::OPEN, $this->encoding);
            if ($res !== true) {
                print_error('cannotopenzip');
            }
        }
        $this->usedmem += strlen($contents);

        if (!$this->za->addFromString($localname, $contents)) {
            return false;
        }
        $this->modified = true;
        return true;
    }