lib/scrivito/workspace.rb in scrivito_sdk-0.66.0 vs lib/scrivito/workspace.rb in scrivito_sdk-0.70.0.rc1
- old
+ new
@@ -1,41 +1,45 @@
require 'active_model/naming'
module Scrivito
-# This class represents a CMS workspace
# @api public
+# This class represents a CMS workspace, called "working copy" in the UI. A working copy lets
+# editors create and modify content independently of the published content or other working copies.
+# On creation, a working copy is based on the currently published content.
+# @see http://scrivito.com/about-working-copies About working copies
+
class Workspace
extend ActiveModel::Naming
include ModelIdentity
PublishPreventedDueToContentChange = Class.new(ScrivitoError)
- # Set the currently used workspace
+ # Set the workspace to use for subsequent workspace operations.
# @api public
# @param [Scrivito::Workspace] workspace
def self.current=(workspace)
@current = workspace
end
def self.current_using_proc=(workspace_proc)
@current = workspace_proc
end
- # Returns the currently used workspace
+ # Returns the currently used workspace.
# @api public
# @return [Scrivito::Workspace]
def self.current
if @current.respond_to? :call
@current = @current.call
else
@current ||= published
end
end
- # Returns all the workspaces
+ # Returns all workspaces.
# @api public
# @return [Array<Scrivito::Workspace>]
def self.all
result_json = CmsRestApi.get('/workspaces')
@@ -46,30 +50,43 @@
def self.published
find("published")
end
- # Find a workspace by its id
+ def self.published_with_fallback
+ cached_workspace_data = CmsBackend.instance.find_workspace_data_from_cache('published')
+
+ if cached_workspace_data
+ workspace_data = begin
+ CmsBackend.instance.find_workspace_data_by_id('published', 0.5)
+ rescue => e
+ warn_backend_not_available(e.message)
+ cached_workspace_data
+ end
+
+ from_workspace_data('published', workspace_data)
+ else
+ published
+ end
+ end
+
+ # Find a workspace by its id.
# @api public
# @param [String] id
# @return [Scrivito::Workspace]
# @raise [Scrivito::ResourceNotFound]
def self.find(id)
cache.fetch(id) do
workspace_data = CmsBackend.instance.find_workspace_data_by_id(id)
- unless workspace_data
- raise ResourceNotFound, "Could not find #{self} with id #{id}"
- end
-
- cache[id] = Workspace.new(workspace_data)
+ from_workspace_data(id, workspace_data)
end
end
# Find a workspace by its title.
# If multiple workspaces share the same title, one of them is returned.
- # If no workspace with the given title can be found, nil is returned.
+ # If no workspace with the given title can be found, +nil+ is returned.
# @api public
# @param [String] title
# @return [Scrivito::Workspace]
def self.find_by_title(title)
all.detect { |workspace| workspace.title == title }
@@ -106,45 +123,47 @@
end
delegate :content_state_id, :base_content_state_id, :content_state,
:base_revision_id, :base_content_state, to: :data
- # Create a new workspace
+ # Create a new workspace.
+ # @example Create a workspace, providing its title:
+ # Scrivito::Workspace.create(title: "Jane")
# @api public
# @param [Hash] attributes
# @return [Scrivito::Workspace]
def self.create(attributes)
workspace_json = CmsRestApi.post("/workspaces", workspace: attributes)
self.find(workspace_json["id"])
end
- # reloads the current workspace to reflect any changes to it that may have happened concurrently
- # since it was loaded
+ # Reloads the current workspace to reflect the changes that were made to it concurrently
+ # since it was loaded.
# @api public
def self.reload
current.reload
end
def self.cache
@cache ||= {}
end
def initialize(workspace_data)
- @workspace_data = workspace_data
+ update_data(workspace_data)
+ @id = data.id
end
- # Reloads this workspace to reflect any changes to it that may have happened concurrently since
- # it was loaded
+ # Reloads this workspace to reflect the changes that were made to it concurrently since
+ # it was loaded.
# @api public
def reload
- @workspace_data = CmsBackend.instance.find_workspace_data_by_id(self.id)
+ update_data(method(:fetch_workspace_data))
+ end
- # Clear all cached instance variables.
- @base_revision = nil
- @memberships = nil
- @revision = nil
+ def eager_reload
+ update_data(fetch_workspace_data)
end
def api_request(verb, path, payload = nil)
response = CmsRestApi.public_send(verb, "#{backend_url}#{path}", payload)
reload if [:post, :put, :delete].include?(verb)
@@ -153,73 +172,78 @@
def task_unaware_api_request(verb, path, payload = nil)
CmsRestApi.task_unaware_request(verb, "#{backend_url}#{path}", payload)
end
- # Updates this workspace's attributes
+ # Updates the attributes of this workspace.
# @api public
# @param [Hash] attributes
# @return [Scrivito::Workspace]
def update(attributes)
raise ScrivitoError, 'published workspace is not modifiable' if published?
CmsRestApi.put(backend_url, workspace: attributes)
reload
end
- # Destroy this workspace
+ # Destroy this workspace.
# @api public
def destroy
reset_workspace_if_current
CmsRestApi.delete(backend_url)
end
- # Publish the changes of this workspace
+ # Publish the changes that were made to this workspace.
# @api public
def publish
CmsRestApi.put("#{backend_url}/publish", {})
Workspace.published.reload
reset_workspace_if_current
end
- # Rebases the current workspace on the published content
+ # Rebases the current workspace from the published content in order to integrate the changes
+ # that were published in the meantime.
# @api public
def rebase
CmsRestApi.put("#{backend_url}/rebase", {})
reload
end
- # Returns the id of the workspace
+ # Returns the id of the workspace.
# @api public
# @return [String]
def id
- @workspace_data.id
+ @id
end
def revision_id
- @workspace_data.revision_id
+ data.revision_id
end
- # Returns the title of the workspace or an empty +String+
+ # Returns the title of the workspace if present. Otherwise, and for the published content,
+ # an empty +String+ is returned.
# @api public
# @return [String]
def title
return '' if published?
- @workspace_data.title || ''
+ data.title || ''
end
# @api public
- # Returns the members of this workspace and their roles
- #
+ # Returns the memberships (users and their roles) of this workspace.
# @return [MembershipCollection]
def memberships
@memberships ||= MembershipCollection.new(self)
end
def data
- @workspace_data
+ if @workspace_data.respond_to?(:call)
+ @workspace_data = @workspace_data.call
+ else
+ @workspace_data
+ end
end
def published?
self.id == 'published'
end
@@ -263,11 +287,11 @@
def assert_revertable
raise ScrivitoError, 'published workspace is not modifiable' if published?
end
- # {ObjCollection} for this working copy
+ # Returns an {ObjCollection} of this working copy for accessing its CMS objects.
# @api public
# @return {ObjCollection}
def objs
@objs ||= ObjCollection.new(self)
end
@@ -292,18 +316,52 @@
self.class.all_with_modification_for(obj_id) - [self]
end
private
+ def update_data(new_data)
+ @workspace_data = new_data
+
+ # Clear all cached instance variables.
+ @base_revision = nil
+ @memberships = nil
+ @revision = nil
+ end
+
+ def fetch_workspace_data
+ CmsBackend.instance.find_workspace_data_by_id(id)
+ end
+
def backend_url
"/workspaces/#{id}"
end
def reset_workspace_if_current
Workspace.cache.delete(id)
if Workspace.current == self
Workspace.current = Workspace.published
+ end
+ end
+
+ class << self
+ private
+
+ def from_workspace_data(id, data)
+ unless data
+ raise ResourceNotFound, "Could not find #{self} with id #{id}"
+ end
+
+ cache[id] = Workspace.new(data)
+ end
+
+ def warn_backend_not_available(error_message)
+ message = <<-EOS
+ Couldn't connect to backend to fetch published workspace.
+ #{error_message}
+ Serving from cache.
+ EOS
+ Rails.logger.warn(message)
end
end
end
end