mirror of
https://github.com/foomo/contentful.git
synced 2025-10-16 12:25:37 +00:00
401 lines
10 KiB
Go
401 lines
10 KiB
Go
package contentful
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
// ContentTypesService service
|
|
type ContentTypesService service
|
|
|
|
// ContentType model
|
|
type ContentType struct {
|
|
Sys *Sys `json:"sys"`
|
|
Name string `json:"name,omitempty"`
|
|
Description string `json:"description,omitempty"`
|
|
Fields []*Field `json:"fields,omitempty"`
|
|
DisplayField string `json:"displayField,omitempty"`
|
|
}
|
|
|
|
const (
|
|
// FieldTypeSymbol content type field type for short textual data
|
|
FieldTypeSymbol = "Symbol"
|
|
|
|
// FieldTypeText content type field type for text data
|
|
FieldTypeText = "Text"
|
|
|
|
// FieldTypeArray content type field type for array data
|
|
FieldTypeArray = "Array"
|
|
|
|
// FieldTypeLink content type field type for link data
|
|
FieldTypeLink = "Link"
|
|
|
|
// FieldTypeInteger content type field type for integer data
|
|
FieldTypeInteger = "Integer"
|
|
|
|
// FieldTypeLocation content type field type for location data
|
|
FieldTypeLocation = "Location"
|
|
|
|
// FieldTypeBoolean content type field type for boolean data
|
|
FieldTypeBoolean = "Boolean"
|
|
|
|
// FieldTypeDate content type field type for date data
|
|
FieldTypeDate = "Date"
|
|
|
|
// FieldTypeObject content type field type for object data
|
|
FieldTypeObject = "Object"
|
|
)
|
|
|
|
// Field model
|
|
type Field struct {
|
|
ID string `json:"id,omitempty"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
LinkType string `json:"linkType,omitempty"`
|
|
Items *FieldTypeArrayItem `json:"items,omitempty"`
|
|
Required bool `json:"required,omitempty"`
|
|
Localized bool `json:"localized,omitempty"`
|
|
Disabled bool `json:"disabled,omitempty"`
|
|
Omitted bool `json:"omitted,omitempty"`
|
|
Validations []FieldValidation `json:"validations,omitempty"`
|
|
}
|
|
|
|
// UnmarshalJSON for custom json unmarshaling
|
|
func (field *Field) UnmarshalJSON(data []byte) error {
|
|
payload := map[string]interface{}{}
|
|
if err := json.Unmarshal(data, &payload); err != nil {
|
|
return err
|
|
}
|
|
|
|
if val, ok := payload["id"]; ok {
|
|
field.ID = val.(string)
|
|
}
|
|
|
|
if val, ok := payload["name"]; ok {
|
|
field.Name = val.(string)
|
|
}
|
|
|
|
if val, ok := payload["type"]; ok {
|
|
field.Type = val.(string)
|
|
}
|
|
|
|
if val, ok := payload["linkType"]; ok {
|
|
field.LinkType = val.(string)
|
|
}
|
|
|
|
if val, ok := payload["items"]; ok {
|
|
byteArray, err := json.Marshal(val)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var fieldTypeArrayItem FieldTypeArrayItem
|
|
if err := json.Unmarshal(byteArray, &fieldTypeArrayItem); err != nil {
|
|
return err
|
|
}
|
|
|
|
field.Items = &fieldTypeArrayItem
|
|
}
|
|
|
|
if val, ok := payload["required"]; ok {
|
|
field.Required = val.(bool)
|
|
}
|
|
|
|
if val, ok := payload["localized"]; ok {
|
|
field.Localized = val.(bool)
|
|
}
|
|
|
|
if val, ok := payload["disabled"]; ok {
|
|
field.Disabled = val.(bool)
|
|
}
|
|
|
|
if val, ok := payload["omitted"]; ok {
|
|
field.Omitted = val.(bool)
|
|
}
|
|
|
|
if val, ok := payload["validations"]; ok {
|
|
validations, err := ParseValidations(val.([]interface{}))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
field.Validations = validations
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ParseValidations converts json representation to go struct
|
|
func ParseValidations(data []interface{}) (validations []FieldValidation, err error) {
|
|
for _, value := range data {
|
|
var validation map[string]interface{}
|
|
var byteArray []byte
|
|
|
|
if validationStr, ok := value.(string); ok {
|
|
if err := json.Unmarshal([]byte(validationStr), &validation); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
byteArray = []byte(validationStr)
|
|
}
|
|
|
|
if validationMap, ok := value.(map[string]interface{}); ok {
|
|
byteArray, err = json.Marshal(validationMap)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validation = validationMap
|
|
}
|
|
|
|
if _, ok := validation["linkContentType"]; ok {
|
|
var fieldValidationLink FieldValidationLink
|
|
if err := json.Unmarshal(byteArray, &fieldValidationLink); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationLink)
|
|
}
|
|
|
|
if _, ok := validation["linkMimetypeGroup"]; ok {
|
|
var fieldValidationMimeType FieldValidationMimeType
|
|
if err := json.Unmarshal(byteArray, &fieldValidationMimeType); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationMimeType)
|
|
}
|
|
|
|
if _, ok := validation["assetImageDimensions"]; ok {
|
|
var fieldValidationDimension FieldValidationDimension
|
|
if err := json.Unmarshal(byteArray, &fieldValidationDimension); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationDimension)
|
|
}
|
|
|
|
if _, ok := validation["assetFileSize"]; ok {
|
|
var fieldValidationFileSize FieldValidationFileSize
|
|
if err := json.Unmarshal(byteArray, &fieldValidationFileSize); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationFileSize)
|
|
}
|
|
|
|
if _, ok := validation["unique"]; ok {
|
|
var fieldValidationUnique FieldValidationUnique
|
|
if err := json.Unmarshal(byteArray, &fieldValidationUnique); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationUnique)
|
|
}
|
|
|
|
if _, ok := validation["in"]; ok {
|
|
var fieldValidationPredefinedValues FieldValidationPredefinedValues
|
|
if err := json.Unmarshal(byteArray, &fieldValidationPredefinedValues); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationPredefinedValues)
|
|
}
|
|
|
|
if _, ok := validation["range"]; ok {
|
|
var fieldValidationRange FieldValidationRange
|
|
if err := json.Unmarshal(byteArray, &fieldValidationRange); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationRange)
|
|
}
|
|
|
|
if _, ok := validation["dateRange"]; ok {
|
|
var fieldValidationDate FieldValidationDate
|
|
if err := json.Unmarshal(byteArray, &fieldValidationDate); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationDate)
|
|
}
|
|
|
|
if _, ok := validation["size"]; ok {
|
|
var fieldValidationSize FieldValidationSize
|
|
if err := json.Unmarshal(byteArray, &fieldValidationSize); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationSize)
|
|
}
|
|
|
|
if _, ok := validation["regexp"]; ok {
|
|
var fieldValidationRegex FieldValidationRegex
|
|
if err := json.Unmarshal(byteArray, &fieldValidationRegex); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
validations = append(validations, fieldValidationRegex)
|
|
}
|
|
}
|
|
|
|
return validations, nil
|
|
}
|
|
|
|
// FieldTypeArrayItem model
|
|
type FieldTypeArrayItem struct {
|
|
Type string `json:"type,omitempty"`
|
|
Validations []FieldValidation `json:"validations,omitempty"`
|
|
LinkType string `json:"linkType,omitempty"`
|
|
}
|
|
|
|
// UnmarshalJSON for custom json unmarshaling
|
|
func (item *FieldTypeArrayItem) UnmarshalJSON(data []byte) error {
|
|
payload := map[string]interface{}{}
|
|
if err := json.Unmarshal(data, &payload); err != nil {
|
|
return err
|
|
}
|
|
|
|
if val, ok := payload["type"]; ok {
|
|
item.Type = val.(string)
|
|
}
|
|
|
|
if val, ok := payload["validations"]; ok {
|
|
validations, err := ParseValidations(val.([]interface{}))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
item.Validations = validations
|
|
}
|
|
|
|
if val, ok := payload["linktype"]; ok {
|
|
item.LinkType = val.(string)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetVersion returns entity version
|
|
func (ct *ContentType) GetVersion() int {
|
|
version := 1
|
|
if ct.Sys != nil {
|
|
version = ct.Sys.Version
|
|
}
|
|
|
|
return version
|
|
}
|
|
|
|
// List return a content type collection
|
|
func (service *ContentTypesService) List(spaceID string) *Collection {
|
|
path := fmt.Sprintf("/spaces/%s/content_types", spaceID)
|
|
method := "GET"
|
|
|
|
req, err := service.c.newRequest(method, path, nil, nil)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
col := NewCollection(&CollectionOptions{})
|
|
col.c = service.c
|
|
col.req = req
|
|
|
|
return col
|
|
}
|
|
|
|
// Get fetched a content type specified by `contentTypeID`
|
|
func (service *ContentTypesService) Get(spaceID, contentTypeID string) (*ContentType, error) {
|
|
path := fmt.Sprintf("/spaces/%s/content_types/%s", spaceID, contentTypeID)
|
|
method := "GET"
|
|
|
|
req, err := service.c.newRequest(method, path, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var ct ContentType
|
|
if err = service.c.do(req, &ct); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ct, nil
|
|
}
|
|
|
|
// Upsert updates or creates a new content type
|
|
func (service *ContentTypesService) Upsert(spaceID string, ct *ContentType) error {
|
|
bytesArray, err := json.Marshal(ct)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var path string
|
|
var method string
|
|
|
|
if ct.Sys != nil && ct.Sys.ID != "" {
|
|
path = fmt.Sprintf("/spaces/%s/content_types/%s", spaceID, ct.Sys.ID)
|
|
method = "PUT"
|
|
} else {
|
|
path = fmt.Sprintf("/spaces/%s/content_types", spaceID)
|
|
method = "POST"
|
|
}
|
|
|
|
req, err := service.c.newRequest(method, path, nil, bytes.NewReader(bytesArray))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req.Header.Set("X-Contentful-Version", strconv.Itoa(ct.GetVersion()))
|
|
|
|
return service.c.do(req, ct)
|
|
}
|
|
|
|
// Delete the content_type
|
|
func (service *ContentTypesService) Delete(spaceID string, ct *ContentType) error {
|
|
path := fmt.Sprintf("/spaces/%s/content_types/%s", spaceID, ct.Sys.ID)
|
|
method := "DELETE"
|
|
|
|
req, err := service.c.newRequest(method, path, nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
version := strconv.Itoa(ct.Sys.Version)
|
|
req.Header.Set("X-Contentful-Version", version)
|
|
|
|
return service.c.do(req, nil)
|
|
}
|
|
|
|
// Activate the contenttype, a.k.a publish
|
|
func (service *ContentTypesService) Activate(spaceID string, ct *ContentType) error {
|
|
path := fmt.Sprintf("/spaces/%s/content_types/%s/published", spaceID, ct.Sys.ID)
|
|
method := "PUT"
|
|
|
|
req, err := service.c.newRequest(method, path, nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
version := strconv.Itoa(ct.Sys.Version)
|
|
req.Header.Set("X-Contentful-Version", version)
|
|
|
|
return service.c.do(req, ct)
|
|
}
|
|
|
|
// Deactivate the contenttype, a.k.a unpublish
|
|
func (service *ContentTypesService) Deactivate(spaceID string, ct *ContentType) error {
|
|
path := fmt.Sprintf("/spaces/%s/content_types/%s/published", spaceID, ct.Sys.ID)
|
|
method := "DELETE"
|
|
|
|
req, err := service.c.newRequest(method, path, nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
version := strconv.Itoa(ct.Sys.Version)
|
|
req.Header.Set("X-Contentful-Version", version)
|
|
|
|
return service.c.do(req, ct)
|
|
}
|