@param string      $contentType
@param string|null $error

@return self
768494
public static function createNotParsable(string $contentType, string $error = null): self
    {
        $message = sprintf('Data is not parsable with content-type: "%s"', $contentType);
        if (null !== $error) {
            $message .= sprintf(', error: "%s"', $error);
        }

        return new self($message);
    }
51126
public function loadFromContentType(ContentType $contentType): self
    {
        $languages = [];
        foreach ($contentType->languageCodes as $languageCode) {
            $languages[] = $this->languageService->loadLanguage($languageCode);
        }

        $this->data = array_map(
            function (Language $language) use ($contentType) {
                return $this->valueFactory->createLanguageFromContentType($language, $contentType);
            },
            $languages
        );

        return $this;
    }
225818
public static function createFromFile(string $filename, string $contentType = null): self
    {
        $instance = new static();
        $instance->content = \file_get_contents($filename);
        $instance->name = \basename($filename);

        if (null !== $contentType) {
            $instance->contentType = $contentType;
        }

        return $instance;
    }
653602
public function setContentType(ContentType $contentType)
    {
        $this->contentTypeName = $contentType->getName();
        $this->contentTypeId = null;

        return parent::setContentType($contentType);
    }
1262229
protected function add_error($name = null, $error = null)
	{
		if($name !== null and $error !== null)
		{
			$this->errors[$name] = $error;
		}

		return $this;
	}
604424
public function createNewFields(Content $content, Type $contentType)
    {
        $fieldsToCopy = array();
        $languageCodes = array();
        $fields = $this->getFieldMap($content->fields, $languageCodes);
        $languageCodes[$content->versionInfo->contentInfo->mainLanguageCode] = true;

        foreach ($contentType->fieldDefinitions as $fieldDefinition) {
            foreach (array_keys($languageCodes) as $languageCode) {
                // Create fields passed from struct
                if (isset($fields[$fieldDefinition->id][$languageCode])) {
                    $field = $fields[$fieldDefinition->id][$languageCode];
                    $this->createNewField($field, $content);
                } elseif (
                    !$fieldDefinition->isTranslatable
                    && isset($fields[$fieldDefinition->id][$content->versionInfo->contentInfo->mainLanguageCode])
                ) {
                    // Copy only for untranslatable field and when field in main language exists
                    // Only register here, process later as field copied should be already stored
                    $fieldsToCopy[$fieldDefinition->id][$languageCode] =
                        $fields[$fieldDefinition->id][$content->versionInfo->contentInfo->mainLanguageCode];
                } else { // In all other cases create empty field
                    $field = $this->getEmptyField($fieldDefinition, $languageCode);
                    $content->fields[] = $field;
                    $this->createNewField($field, $content);
                }
            }
        }

        $this->copyFields($fieldsToCopy, $content);
    }
1355941
public function withContentType($contentType)
    {
        $contentType = $this->normalizeContentType($contentType);

        $contentType = explode(';', $contentType, 2);

        $this->type = $contentType[0];

        $contentType[0] .= ';' . (isset($contentType[1]) ? $contentType[1] : ' charset=utf-8');

        return $this->withHeader('Content-Type', $contentType[0]);
    }
125399
public function setContentType(string $contentType): void
    {
        $this->contentType = $contentType;
        // TODO: This can be removed after the full changes are done for next major.
        $this->headers->set('Content-Type', $contentType, true);
    }
1121568
public function setContentType($contentType, $charset = null)
    {
        if ($charset === null) {
            $this->setHeader('Content-Type', $contentType);
        } else {
            $this->setHeader('Content-Type', $contentType . '; charset=' . $charset);
        }

        return $this;
    }
594932
public function addParser(string $contentType, callable $parser): self
	{
		$this->parsers[$contentType] = \Closure::fromCallable($parser);

		return $this;
	}
1234871
public function withContentType($contentType, $charset = null)
    {
        if (is_null($charset)) {
            return $this->withHeader('Content-Type', $contentType);
        }

        return $this->withHeader('Content-Type', $contentType . '; charset=' . $charset);
    }
134911
public function setContentType(string $contentType, string $charset = null)
    {
        $this->setHeader('Content-Type', $contentType . ($charset ? "; charset=$charset" : ''));

        return $this;
    }
982294
public function setBody($body, string $contentType = null, string $contentCharset = null): self
    {
        if ($body != null) {
            if ($body instanceof ReturnResponse) {
                $this->setStatus($body->getStatusCode())
                     ->setHeaders($body->getHeaders())
                     ->setCookies($body->getCookies());

                $body = new Body(
                    $body->getContent(),
                    $body->getContentType() ?? $this->body->getContentType(),
                    $body->getContentCharset() ?? $this->body->getContentCharset()
                );

                // override, no need to all stuff below
                if ($body->isImage()) {
                    $this->body = $body;

                    return $this;
                }
            }

            // no elseif, could be a Body already
            if ($body instanceof Body) {
                $body = $this->body
                    ->setContent($body->getContent())
                    ->setContentType($body->getContentType())
                    ->setContentCharset($body->getContentCharset())
                    ->getContent();
            }
        }

        if ($body !== null) {
            // json stuff (array/object returns could be encoded if content type is json)
            $bodyType = gettype($body);
            if ($bodyType != 'string') {
                switch ($bodyType) {
                    case 'array': case 'object':
                        $jsonOptions = $this->app->configValue('response.json');
                        if ($jsonOptions != null // could be emptied by developer to disable json
                            && ($bodyContentType = $this->body->getContentType())
                            && (strpos($bodyContentType, '/json') || strpos($bodyContentType, '+json'))
                        ) {
                            [$body, $error] = Encoder::jsonEncode($body, $jsonOptions);
                            if ($error) {
                                throw new EncoderException($error);
                            }
                        }
                        break;
                    case 'integer': case 'double':
                        $body = (string) $body;
                        break;
                }
            }

            // not encoded/converted
            if (!is_string($body)) {
                throw new HttpException("Body content must be string, number, array or object".
                    " (or encoded in invoked service method if froq\\http\\response\\JsonResponse".
                    " not used, or content type set as application/json or text/json),".
                    " '{$bodyType}' given");
            }

            // gzip stuff
            $bodyLength = strlen($body);
            if ($bodyLength > 0) { // prevent gzip corruption for 0 byte data
                $gzipOptions = $this->app->configValue('response.gzip');
                $acceptEncoding = (string) $this->app->request()->getHeader('Accept-Encoding');

                $canGzip = $gzipOptions != null // could be emptied by developer to disable gzip
                    && strpos($acceptEncoding, 'gzip') !== false
                    && $bodyLength >= ($gzipOptions['minlen'] ?? 1);

                if ($canGzip) {
                    [$body, $error] = Encoder::gzipEncode($body, $gzipOptions);
                    if ($error) {
                        throw new EncoderException($error);
                    }

                    // cancel php's compression & add required headers
                    if (!headers_sent()) {
                        ini_set('zlib.output_compression', 'Off');
                    }
                    $this->setHeader('Content-Encoding', 'gzip');
                    $this->setHeader('Vary', 'Accept-Encoding');
                }
            }

            // finally..
            $this->body->setContent($body)
                       ->setContentLength(strlen($body));
        }

        // '' accepted for 'none' responses
        if ($contentType !== null) {
            $this->body->setContentType($contentType);
        }
        if ($contentCharset !== null) {
            $this->body->setContentCharset($contentCharset);
        }

        return $this;
    }
432428
public function decode($content, $contentType)
    {
        $converter = $this->getConverter($contentType);

        return $converter->decode($content);
    }
392286
public function addAttachment(string $file, string $content = null, string $contentType = null): self
	{
		$this->message->addAttachment($file, $content, $contentType);
		return $this;
	}
615420
private function isValidContentType(string $contentType): void
    {
        $allowedContentType = $this->getAllowedContentType();
        if (!\in_array($contentType, $allowedContentType, true)) {
            throw new InvalidTypeException('Invalid content type.');
        }
    }
200677
public static function toNumeric($contentType)
    {
        if (!is_string($contentType)) {
            throw new \InvalidArgumentException('The content type "' . $contentType . '" is not a string.');
        }

        return static::defines(strtoupper($contentType), true);
    }