naranya_ecm-sdk 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/dev/create_cvm.rb +31 -0
- data/dev/init.rb +2 -0
- data/dev/load_cvm.rb +12 -0
- data/dev/search.rb +3 -0
- data/lib/naranya_ecm/behaviors/localizable.rb +41 -0
- data/lib/naranya_ecm/behaviors/timestampable.rb +22 -0
- data/lib/naranya_ecm/behaviors.rb +9 -0
- data/lib/naranya_ecm/cache/key.rb +73 -0
- data/lib/naranya_ecm/cache/methods.rb +78 -0
- data/lib/naranya_ecm/cache.rb +9 -0
- data/lib/naranya_ecm/has_many_patch.rb +105 -0
- data/lib/naranya_ecm/lifecycles/content_lifecycle.rb +36 -0
- data/lib/naranya_ecm/lifecycles/lifecycleable.rb +43 -0
- data/lib/naranya_ecm/lifecycles/version_lifecycle.rb +75 -0
- data/lib/naranya_ecm/lifecycles.rb +10 -0
- data/lib/naranya_ecm/models/category.rb +42 -0
- data/lib/naranya_ecm/models/content.rb +102 -0
- data/lib/naranya_ecm/models/content_version.rb +38 -0
- data/lib/naranya_ecm/models/download_authorization.rb +55 -0
- data/lib/naranya_ecm/models/lifecycle.rb +36 -0
- data/lib/naranya_ecm/models/media_resource.rb +33 -0
- data/lib/naranya_ecm/models.rb +13 -0
- data/lib/naranya_ecm/search/hit.rb +17 -0
- data/lib/naranya_ecm/search/methods.rb +26 -0
- data/lib/naranya_ecm/search/query.rb +296 -0
- data/lib/naranya_ecm/search/results.rb +161 -0
- data/lib/naranya_ecm/search.rb +14 -0
- data/lib/naranya_ecm/site_from_configuration.rb +15 -0
- data/lib/naranya_ecm-sdk/version.rb +3 -0
- data/lib/naranya_ecm-sdk.rb +84 -0
- data/naranya_ecm-sdk.gemspec +33 -0
- data/spec/models/category_spec.rb +11 -0
- data/spec/models/content_spec.rb +11 -0
- data/spec/models/content_version_spec.rb +7 -0
- data/spec/models/download_authorization.rb +7 -0
- data/spec/models/media_spec.rb +7 -0
- data/spec/models/module_spec.rb +18 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/support/naranya_ecms_shared_specs.rb +33 -0
- metadata +236 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ea93a84c6487716b367c31b4e0c416de8cdd281
|
4
|
+
data.tar.gz: dff98318c7c4d3997dc0dc9fec891fcdf4ce8ac2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4ee9589ea02b1d9491d55354942ba58989d9e01e9f018c360e0e48b20c2fe1bde4ce6cba5de6b0aa4d3cd5b90bbcc68b1651ceed878a0c2f0083d27025afcaa1
|
7
|
+
data.tar.gz: 7850ded288a43ff49690f3c3813e1bac47639df640143b4107689dde841944ea7c2683714b628ccc704bb8cd12e2aa003266fd3c091b8a98f817aab3c7691874
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Roberto Quintanilla
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# NaranyaEcm
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'naranya_ecm'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install naranya_ecm
|
18
|
+
|
19
|
+
## Development: Running on console:
|
20
|
+
|
21
|
+
$ bundle console
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it ( http://github.com/<my-github-username>/naranya_ecm/fork )
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/dev/create_cvm.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
content = NaranyaEcm::Content.create(
|
3
|
+
state: "draft",
|
4
|
+
author: "Vovi",
|
5
|
+
title_translations: { "es" => "FlappyBird"},
|
6
|
+
main_url: "http://www.naranyamarket.com/1"
|
7
|
+
)
|
8
|
+
|
9
|
+
content_version = NaranyaEcm::ContentVersion.create(
|
10
|
+
content_id: content.id,
|
11
|
+
state: "draft",
|
12
|
+
description_translations: { "es" => "FlappyBird"},
|
13
|
+
code: 1,
|
14
|
+
name: "0.0.1"
|
15
|
+
)
|
16
|
+
|
17
|
+
public_media_resource = NaranyaEcm::MediaResource.create(
|
18
|
+
content_version_id: content_version.id,
|
19
|
+
type: "image/png",
|
20
|
+
role: "banner",
|
21
|
+
downloadable_url: "https://cms-ejemplo-1.s3.amazonaws.com/flappybirdbanner.png",
|
22
|
+
access_type: 'public'
|
23
|
+
)
|
24
|
+
|
25
|
+
private_media_resource = NaranyaEcm::MediaResource.create(
|
26
|
+
content_version_id: content_version.id,
|
27
|
+
type: "application/apk",
|
28
|
+
role: "main_downloadable",
|
29
|
+
downloadable_url: "https://cms-ejemplo-1.s3.amazonaws.com/flappybird.apk",
|
30
|
+
access_type: 'private'
|
31
|
+
)
|
data/dev/init.rb
ADDED
data/dev/load_cvm.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
content = Content.last
|
3
|
+
|
4
|
+
version = content.versions.last
|
5
|
+
|
6
|
+
media_resource = version.media_resources.last
|
7
|
+
|
8
|
+
=begin
|
9
|
+
download_authorization = DownloadAuthorization.create media_resource: media_resource, expires_at: 10.minutes.from_now
|
10
|
+
|
11
|
+
download_authorization = DownloadAuthorization.find("530e5e2265636d027b000000")
|
12
|
+
=end
|
data/dev/search.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module NaranyaEcm
|
4
|
+
|
5
|
+
module Behaviors
|
6
|
+
module Localizable
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
# Delegar el acceso tipo "Enumerable":
|
12
|
+
delegate :any?, to: :@attributes
|
13
|
+
|
14
|
+
# Re-establece el acceso tipo Hash:
|
15
|
+
delegate :[], to: :@attributes
|
16
|
+
delegate :[]=, to: :@attributes
|
17
|
+
self.site = "http://www.example.com"
|
18
|
+
|
19
|
+
attribute_name = self.name.demodulize.underscore[0..-("_translations".length+1)]
|
20
|
+
alias_method attribute_name.to_sym, :lookup
|
21
|
+
end
|
22
|
+
|
23
|
+
def locales
|
24
|
+
@attributes.keys
|
25
|
+
end
|
26
|
+
alias_method :available_locales, :locales
|
27
|
+
|
28
|
+
def lookup
|
29
|
+
locale = ::I18n.locale
|
30
|
+
if ::I18n.respond_to?(:fallbacks)
|
31
|
+
lookup_result = @attributes[::I18n.fallbacks[locale].map(&:to_s).find{ |loc| @attributes.has_key?(loc) }]
|
32
|
+
else
|
33
|
+
lookup_result = @attributes[locale.to_s]
|
34
|
+
end
|
35
|
+
lookup_result || @attributes.present? ? @attributes.first[1] : nil
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
module NaranyaEcm
|
3
|
+
module Behaviors
|
4
|
+
module Timestampable
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
%w(created_at updated_at).map(&:to_sym).each do |attr_sym|
|
10
|
+
# getter:
|
11
|
+
define_method(attr_sym) { @attributes[attr_sym].present? ? @attributes[attr_sym].to_datetime : nil }
|
12
|
+
# setter:
|
13
|
+
# define_method("#{attr_sym}=".to_sym) do |value|
|
14
|
+
# self.send "#{attr_sym}_will_change!".to_sym unless value == @attributes[attr_sym]
|
15
|
+
# @attributes[attr_sym] = value
|
16
|
+
# end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'active_support/hash_with_indifferent_access'
|
2
|
+
|
3
|
+
module NaranyaEcm
|
4
|
+
module Cache
|
5
|
+
class Key < String
|
6
|
+
|
7
|
+
TIMESTAMP_FORMAT = '%Y%m%d%H%M%S%L%3N'.freeze
|
8
|
+
|
9
|
+
def initialize(segments={})
|
10
|
+
|
11
|
+
@segments = ActiveSupport::HashWithIndifferentAccess.new
|
12
|
+
|
13
|
+
resource = segments.delete :resource
|
14
|
+
|
15
|
+
@segments[:class_name] = case
|
16
|
+
when resource.present? then resource.class.name
|
17
|
+
when segments.has_key?(:class_name) then segments.delete(:class_name)
|
18
|
+
when segments.has_key?(:resource_class) then segments.delete(:resource_class).name
|
19
|
+
else nil
|
20
|
+
end
|
21
|
+
|
22
|
+
@segments[:id] = case
|
23
|
+
when resource.present? then resource.id
|
24
|
+
when segments.has_key?(:id) then segments.delete(:id)
|
25
|
+
else nil
|
26
|
+
end
|
27
|
+
|
28
|
+
@segments[:timestamp] = case
|
29
|
+
when resource.present? then resource.respond_to?(:updated_at) ? resource.updated_at : nil
|
30
|
+
when segments.has_key?(:timestamp) then segments.delete(:timestamp)
|
31
|
+
else nil
|
32
|
+
end
|
33
|
+
|
34
|
+
@segments.freeze
|
35
|
+
|
36
|
+
super self.class.join_segments(@segments).freeze
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def class_name; @segments[:class_name]; end
|
41
|
+
def id; @segments[:id]; end
|
42
|
+
def timestamp; @segments[:timestamp]; end
|
43
|
+
|
44
|
+
def timestamped?
|
45
|
+
resource_timestamp.present?
|
46
|
+
end
|
47
|
+
|
48
|
+
def any_timestamp
|
49
|
+
self.class.join_segments(@segments.except(:timestamp)) + '-*'
|
50
|
+
end
|
51
|
+
|
52
|
+
def with_timestamp(datetime)
|
53
|
+
raise "Not a valid timestamp" unless datetime.respond_to? :strftime
|
54
|
+
self.class.new class_name: class_name, id: id, timestamp: datetime
|
55
|
+
end
|
56
|
+
|
57
|
+
class << self
|
58
|
+
def join_segments(segments)
|
59
|
+
segments = segments.with_indifferent_access
|
60
|
+
str = segments[:class_name].underscore
|
61
|
+
if segments[:id].present?
|
62
|
+
str += "/#{segments[:id]}"
|
63
|
+
if segments[:timestamp].present? and segments[:timestamp].respond_to?(:strftime)
|
64
|
+
str += "-#{segments[:timestamp].strftime(TIMESTAMP_FORMAT)}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
str
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
module NaranyaEcm
|
3
|
+
module Cache
|
4
|
+
module Methods
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
alias_method_chain :load, :caching
|
10
|
+
|
11
|
+
class << self
|
12
|
+
alias_method_chain :find_single, :caching
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_key
|
17
|
+
@cache_key ||= NaranyaEcm.cache_key_for resource: self
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_with_caching(attributes, remove_root = false, persisted = false)
|
21
|
+
res = load_without_caching(attributes, remove_root = false, persisted = false)
|
22
|
+
|
23
|
+
cache_options = {}
|
24
|
+
cache_options[:expires_in] = 10.minutes unless self.updated_at.present? and self.updated_at.is_a? DateTime
|
25
|
+
|
26
|
+
NaranyaEcm.cache.write cache_key, @attributes, cache_options
|
27
|
+
|
28
|
+
res
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
|
33
|
+
def cache
|
34
|
+
NaranyaEcm.cache
|
35
|
+
end
|
36
|
+
|
37
|
+
def cache_key_for(attributes)
|
38
|
+
NaranyaEcm.cache_key_for attributes.merge(resource_class: self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_cached(cache_key)
|
42
|
+
cached_attributes = cache.read(cache_key)
|
43
|
+
cached_attributes.present? ? instantiate_record(cached_attributes) : nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_cached!(cache_key)
|
47
|
+
found = find_cached(cache_key)
|
48
|
+
raise "No record matched given attribute in cache" unless found
|
49
|
+
found
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Find a single resource from the default URL
|
55
|
+
def find_single_with_caching(scope, options)
|
56
|
+
|
57
|
+
# Try to load the record from cache:
|
58
|
+
cache_key = cache_key_for id: scope, timestamp: options.delete(:timestamp)
|
59
|
+
|
60
|
+
record = find_cached cache_key
|
61
|
+
|
62
|
+
unless record.present?
|
63
|
+
|
64
|
+
# Load the record from the ECM server:
|
65
|
+
record = find_single_without_caching(scope, options)
|
66
|
+
|
67
|
+
# Cache the record by writing the record's attributes to the cache store,
|
68
|
+
# IF the attributes have not been written before:
|
69
|
+
cache.write(record.cache_key, record.attributes) unless cache.exist? record.cache_key
|
70
|
+
end
|
71
|
+
|
72
|
+
record
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module NaranyaEcm
|
4
|
+
|
5
|
+
# Aplica de manera dinámica el patch visto en:
|
6
|
+
# https://github.com/kenips/activeresource/commit/720c06a5a4a2d1cfd7319accb649b7aececa1ca2
|
7
|
+
module HasManyPatch
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
class << self
|
13
|
+
alias_method_chain :element_path, :has_many_patch
|
14
|
+
|
15
|
+
unless method_defined? :element_base_path
|
16
|
+
alias_method :element_base_path, :element_base_path_with_has_many_patch
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method_chain :defines_has_many_finder_method, :has_many_patch
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def element_base_path(options = nil)
|
24
|
+
self.class.element_base_path(to_param, options || prefix_options)
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
|
29
|
+
# Gets the element path for the given ID in +id+. If the +query_options+ parameter is omitted, Rails
|
30
|
+
# will split from the \prefix options.
|
31
|
+
#
|
32
|
+
# ==== Options
|
33
|
+
# +prefix_options+ - A \hash to add a \prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
|
34
|
+
# would yield a URL like <tt>/accounts/19/purchases.json</tt>).
|
35
|
+
#
|
36
|
+
# +query_options+ - A \hash to add items to the query string for the request.
|
37
|
+
#
|
38
|
+
# ==== Examples
|
39
|
+
# Post.element_path(1)
|
40
|
+
# # => /posts/1.json
|
41
|
+
#
|
42
|
+
# class Comment < ActiveResource::Base
|
43
|
+
# self.site = "https://37s.sunrise.com/posts/:post_id"
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# Comment.element_path(1, :post_id => 5)
|
47
|
+
# # => /posts/5/comments/1.json
|
48
|
+
#
|
49
|
+
# Comment.element_path(1, :post_id => 5, :active => 1)
|
50
|
+
# # => /posts/5/comments/1.json?active=1
|
51
|
+
#
|
52
|
+
# Comment.element_path(1, {:post_id => 5}, {:active => 1})
|
53
|
+
# # => /posts/5/comments/1.json?active=1
|
54
|
+
#
|
55
|
+
def element_path_with_has_many_patch(id, prefix_options = {}, query_options = nil)
|
56
|
+
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
57
|
+
"#{element_base_path(id, prefix_options)}#{format_extension}#{query_string(query_options)}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Gets the element base path for the given ID in +id+. This will never return a format extension or params,
|
61
|
+
# it is useful for building prefix paths. See <tt>element_path</tt> if you need format extensions and params.
|
62
|
+
#
|
63
|
+
# ==== Options
|
64
|
+
# +prefix_options+ - A \hash to add a \prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
|
65
|
+
# would yield a URL like <tt>/accounts/19</tt>).
|
66
|
+
#
|
67
|
+
# ==== Examples
|
68
|
+
# Class Post < ActiveResource::Base
|
69
|
+
# self.site = "https://37s.sunrise.com/api"
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# Post.element_base_path(1)
|
73
|
+
# # => /api/posts/1
|
74
|
+
#
|
75
|
+
# class Comment < ActiveResource::Base
|
76
|
+
# self.site = "https://37s.sunrise.com/api/posts/:post_id"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# Comment.element_base_path(1, :post_id => 5)
|
80
|
+
# # => /api/posts/5/comments/1
|
81
|
+
#
|
82
|
+
def element_base_path_with_has_many_patch(id, prefix_options = {})
|
83
|
+
check_prefix_options(prefix_options)
|
84
|
+
"#{prefix(prefix_options)}#{collection_name}/#{URI.parser.escape id.to_s}"
|
85
|
+
end
|
86
|
+
|
87
|
+
# Patches the definition of the has_many finder method
|
88
|
+
def defines_has_many_finder_method_with_has_many_patch(method_name, association_model)
|
89
|
+
ivar_name = :"@#{method_name}"
|
90
|
+
|
91
|
+
define_method(method_name) do
|
92
|
+
if instance_variable_defined?(ivar_name)
|
93
|
+
instance_variable_get(ivar_name)
|
94
|
+
elsif attributes.include?(method_name)
|
95
|
+
attributes[method_name]
|
96
|
+
else
|
97
|
+
instance_variable_set(ivar_name, association_model.find(:all, :from => "#{element_base_path}/#{method_name}.#{association_model.format.extension}"))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'state_machine'
|
3
|
+
|
4
|
+
module NaranyaEcm
|
5
|
+
module Lifecycles
|
6
|
+
|
7
|
+
module ContentLifecycle
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
|
12
|
+
include NaranyaEcm::Lifecycles::Lifecycleable
|
13
|
+
|
14
|
+
##################################################################
|
15
|
+
# StateMachine:
|
16
|
+
state_machine :lifecycle_state, initial: :draft do
|
17
|
+
|
18
|
+
state :draft
|
19
|
+
|
20
|
+
state :awaiting_validation
|
21
|
+
|
22
|
+
state :rejected
|
23
|
+
|
24
|
+
state :validated
|
25
|
+
|
26
|
+
state :published
|
27
|
+
|
28
|
+
state :deactivated
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module NaranyaEcm
|
4
|
+
module Lifecycles
|
5
|
+
|
6
|
+
module Lifecycleable
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
attr_accessor :lifecycle_name, :lifecycle_state
|
11
|
+
end
|
12
|
+
|
13
|
+
def lifecycle_name
|
14
|
+
@attributes['lifecycle_name'] ||= NaranyaEcm::Lifecycle.new(@attributes['lifecycle_name'])
|
15
|
+
end
|
16
|
+
|
17
|
+
def lifecycle_name=(given_lifecycle_name)
|
18
|
+
@attributes['lifecycle_name'] = NaranyaEcm::Lifecycle.new(given_lifecycle_name)
|
19
|
+
@lifecycle_name = @attributes['lifecycle_name']
|
20
|
+
end
|
21
|
+
|
22
|
+
def lifecycle_state
|
23
|
+
@attributes['lifecycle_state']
|
24
|
+
end
|
25
|
+
|
26
|
+
def lifecycle_state=(given_lifecycle_state)
|
27
|
+
@attributes['lifecycle_state']= given_lifecycle_state.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(method_name, *args, &block)
|
31
|
+
if method_name.to_s =~ /^(\w+)_lifecycle\?$/
|
32
|
+
self.lifecycle_name.is_lifecycle?($1)
|
33
|
+
else
|
34
|
+
super # You *must* call super if you don't handle the
|
35
|
+
# method, otherwise you'll mess up Ruby's method
|
36
|
+
# lookup.
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'state_machine'
|
3
|
+
|
4
|
+
module NaranyaEcm
|
5
|
+
module Lifecycles
|
6
|
+
|
7
|
+
module VersionLifecycle
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
|
12
|
+
include NaranyaEcm::Lifecycles::Lifecycleable
|
13
|
+
|
14
|
+
##################################################################
|
15
|
+
# StateMachine:
|
16
|
+
state_machine :lifecycle_state, initial: :draft do
|
17
|
+
|
18
|
+
# # Not working...
|
19
|
+
# #after_transition :on => :publish, :do => :supercede_the_content_current_version_if_published
|
20
|
+
|
21
|
+
# #########################################
|
22
|
+
# # Eventos:
|
23
|
+
|
24
|
+
# event :request_validation do
|
25
|
+
# # Iniciar la transición de :draft a :awaiting_validation,
|
26
|
+
# # si el lifecycle es sencillo:
|
27
|
+
# transition :draft => :awaiting_validation, :unless => :simple_lifecycle?
|
28
|
+
# end
|
29
|
+
|
30
|
+
# event :validate do
|
31
|
+
# # Iniciar la transición de :awaiting_validation a :validated:
|
32
|
+
# transition :awaiting_validation => :validated
|
33
|
+
# end
|
34
|
+
|
35
|
+
# event :reject do
|
36
|
+
# # Iniciar la transición de :awaiting_validation a :rejected:
|
37
|
+
# transition :awaiting_validation => :rejected
|
38
|
+
# end
|
39
|
+
|
40
|
+
# event :publish do
|
41
|
+
# # Iniciar la transición de :draft a :published,
|
42
|
+
# # si el lifecycle es sencillo:
|
43
|
+
# transition :draft => :published, :if => :simple_lifecycle?
|
44
|
+
# transition :validated => :published
|
45
|
+
# end
|
46
|
+
|
47
|
+
# event :supersede do
|
48
|
+
# # Iniciar la transición de :published a :superseded:
|
49
|
+
# transition :published => :superseded
|
50
|
+
# end
|
51
|
+
|
52
|
+
# event :deactivate do
|
53
|
+
# # Iniciar la transición de :published a :deactivated:
|
54
|
+
# transition :published => :deactivated
|
55
|
+
# end
|
56
|
+
|
57
|
+
state :awaiting_validation
|
58
|
+
|
59
|
+
state :rejected
|
60
|
+
|
61
|
+
state :validated
|
62
|
+
|
63
|
+
state :published
|
64
|
+
|
65
|
+
state :superseded
|
66
|
+
|
67
|
+
state :deactivated
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|