Improved taxonomy by supporting tags, multiple terms allowed, and required kind of vocabulary for specific content type.
Updated node web form, to support taxonomy editing if allowed (specific support for CMS_VOCABULARY.is_tags: BOOLEAN). Added notion of required or optional module dependencies.
This commit is contained in:
@@ -12,3 +12,4 @@ set ROC_CMS_DIR=%~dp0
|
||||
%ROC_CMD% install --module ..\..\modules\recent_changes --dir %ROC_CMS_DIR%
|
||||
%ROC_CMD% install --module ..\..\modules\feed_aggregator --dir %ROC_CMS_DIR%
|
||||
%ROC_CMD% install --module ..\..\modules\google_search --dir %ROC_CMS_DIR%
|
||||
%ROC_CMD% install --module ..\..\modules\taxonomy --dir %ROC_CMS_DIR%
|
||||
|
||||
21
examples/demo/site/modules/taxonomy/files/css/taxonomy.css
Normal file
21
examples/demo/site/modules/taxonomy/files/css/taxonomy.css
Normal file
@@ -0,0 +1,21 @@
|
||||
ul.taxonomy {
|
||||
font-size: 80%;
|
||||
list-style-type: none;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
ul.taxonomy li {
|
||||
padding: 2px;
|
||||
margin-right: 3px;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
}
|
||||
ul.taxonomy li a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
ul.taxonomy li:hover {
|
||||
padding: 1px;
|
||||
border-top: solid 1px #66f;
|
||||
border-bottom: solid 1px #66f;
|
||||
background-color: #ddf;
|
||||
}
|
||||
21
examples/demo/site/modules/taxonomy/files/scss/taxonomy.scss
Normal file
21
examples/demo/site/modules/taxonomy/files/scss/taxonomy.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
ul.taxonomy {
|
||||
font-size: 80%;
|
||||
list-style-type: none;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
li {
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
padding: 2px;
|
||||
margin-right: 3px;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
&:hover {
|
||||
padding: 1px;
|
||||
border-top: solid 1px #66f;
|
||||
border-bottom: solid 1px #66f;
|
||||
background-color: #ddf;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
examples/demo/site/modules/taxonomy/scripts/install.sql
Normal file
24
examples/demo/site/modules/taxonomy/scripts/install.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
CREATE TABLE taxonomy_term (
|
||||
`tid` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
|
||||
`text` VARCHAR(255) NOT NULL,
|
||||
`weight` INTEGER,
|
||||
`description` TEXT,
|
||||
`langcode` VARCHAR(12)
|
||||
);
|
||||
|
||||
CREATE TABLE taxonomy_hierarchy (
|
||||
`tid` INTEGER NOT NULL,
|
||||
`parent` INTEGER,
|
||||
CONSTRAINT PK_tid_parent PRIMARY KEY (tid,parent)
|
||||
);
|
||||
|
||||
/* Associate tid with unique (type,entity)
|
||||
* for instance: "page" + "$nid" -> "tid"
|
||||
*/
|
||||
CREATE TABLE taxonomy_index (
|
||||
`tid` INTEGER NOT NULL,
|
||||
`entity` VARCHAR(255),
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
CONSTRAINT PK_tid_entity_type PRIMARY KEY (tid,entity,type)
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
DROP TABLE IF EXISTS taxonomy_term;
|
||||
DROP TABLE IF EXISTS taxonomy_hierarchy;
|
||||
DROP TABLE IF EXISTS taxonomy_index;
|
||||
@@ -41,6 +41,9 @@ feature {NONE} -- Initialization
|
||||
description := "Service to manage content based on 'node'"
|
||||
package := "core"
|
||||
config := a_setup
|
||||
-- Optional dependencies, mainly for information.
|
||||
put_dependency ({CMS_RECENT_CHANGES_MODULE}, False)
|
||||
put_dependency ({CMS_TAXONOMY_MODULE}, False)
|
||||
end
|
||||
|
||||
config: CMS_SETUP
|
||||
|
||||
@@ -48,8 +48,8 @@ feature -- Forms ...
|
||||
if a_node /= Void then
|
||||
ta.set_text_value (a_node.content)
|
||||
end
|
||||
ta.set_label ("Content")
|
||||
ta.set_description ("This is the main content")
|
||||
ta.set_label (response.translation ("Content", Void))
|
||||
ta.set_description (response.translation ("This is the main content", Void))
|
||||
ta.set_is_required (False)
|
||||
|
||||
-- Summary
|
||||
@@ -61,8 +61,8 @@ feature -- Forms ...
|
||||
if a_node /= Void then
|
||||
sum.set_text_value (a_node.summary)
|
||||
end
|
||||
sum.set_label ("Summary")
|
||||
sum.set_description ("Text displayed in short view.")
|
||||
sum.set_label (response.translation ("Summary", Void))
|
||||
sum.set_description (response.translation ("Text displayed in short view.", Void))
|
||||
sum.set_is_required (False)
|
||||
|
||||
create fset.make
|
||||
@@ -93,9 +93,230 @@ feature -- Forms ...
|
||||
f.extend (fset)
|
||||
|
||||
-- Path alias
|
||||
populate_form_with_taxonomy (response, f, a_node)
|
||||
populate_form_with_path_alias (response, f, a_node)
|
||||
end
|
||||
|
||||
populate_form_with_taxonomy (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
|
||||
local
|
||||
ti: detachable WSF_FORM_TEXT_INPUT
|
||||
w_set: WSF_FORM_FIELD_SET
|
||||
w_select: WSF_FORM_SELECT
|
||||
w_opt: WSF_FORM_SELECT_OPTION
|
||||
w_cb: WSF_FORM_CHECKBOX_INPUT
|
||||
w_voc_set: WSF_FORM_FIELD_SET
|
||||
s: STRING_32
|
||||
voc: CMS_VOCABULARY
|
||||
t: detachable CMS_TERM
|
||||
l_terms: detachable CMS_TERM_COLLECTION
|
||||
l_has_edit_permission: BOOLEAN
|
||||
do
|
||||
if
|
||||
attached {CMS_TAXONOMY_API} response.api.module_api ({CMS_TAXONOMY_MODULE}) as l_taxonomy_api and then
|
||||
attached l_taxonomy_api.vocabularies_for_type (content_type.name) as l_vocs and then not l_vocs.is_empty
|
||||
then
|
||||
|
||||
l_has_edit_permission := response.has_permissions (<<"update any taxonomy", "update " + content_type.name + " taxonomy">>)
|
||||
|
||||
-- Handle Taxonomy fields, if any associated with `content_type'.
|
||||
create w_set.make
|
||||
w_set.add_css_class ("taxonomy")
|
||||
l_vocs.sort
|
||||
across
|
||||
l_vocs as vocs_ic
|
||||
loop
|
||||
voc := vocs_ic.item
|
||||
l_terms := Void
|
||||
if a_node /= Void and then a_node.has_id then
|
||||
l_terms := l_taxonomy_api.terms_of_entity (a_node.content_type, a_node.id.out, voc)
|
||||
if l_terms /= Void then
|
||||
l_terms.sort
|
||||
end
|
||||
end
|
||||
create w_voc_set.make
|
||||
w_set.extend (w_voc_set)
|
||||
|
||||
if voc.is_tags then
|
||||
w_voc_set.set_legend (response.translation (voc.name, Void))
|
||||
|
||||
create ti.make ({STRING_32} "taxonomy_terms[" + voc.name + "]")
|
||||
w_voc_set.extend (ti)
|
||||
if voc.is_term_required then
|
||||
ti.enable_required
|
||||
end
|
||||
if attached voc.description as l_desc then
|
||||
ti.set_description (response.html_encoded (response.translation (l_desc, Void)))
|
||||
else
|
||||
ti.set_description (response.html_encoded (response.translation (voc.name, Void)))
|
||||
end
|
||||
ti.set_size (70)
|
||||
if l_terms /= Void then
|
||||
create s.make_empty
|
||||
across
|
||||
l_terms as ic
|
||||
loop
|
||||
t := ic.item
|
||||
if not s.is_empty then
|
||||
s.append_character (',')
|
||||
s.append_character (' ')
|
||||
end
|
||||
if ic.item.text.has (' ') then
|
||||
s.append_character ('"')
|
||||
s.append (t.text)
|
||||
s.append_character ('"')
|
||||
else
|
||||
s.append (t.text)
|
||||
end
|
||||
end
|
||||
ti.set_text_value (s)
|
||||
end
|
||||
if not l_has_edit_permission then
|
||||
ti.set_is_readonly (True)
|
||||
end
|
||||
else
|
||||
l_taxonomy_api.fill_vocabularies_with_terms (voc)
|
||||
if not voc.terms.is_empty then
|
||||
if voc.multiple_terms_allowed then
|
||||
if attached voc.description as l_desc then
|
||||
w_voc_set.set_legend (response.html_encoded (l_desc))
|
||||
else
|
||||
w_voc_set.set_legend (response.html_encoded (voc.name))
|
||||
end
|
||||
across
|
||||
voc as voc_terms_ic
|
||||
loop
|
||||
t := voc_terms_ic.item
|
||||
create w_cb.make_with_value ({STRING_32} "taxonomy_terms[" + voc.name + "]", t.text)
|
||||
w_voc_set.extend (w_cb)
|
||||
if l_terms /= Void and then across l_terms as ic some ic.item.text.same_string (t.text) end then
|
||||
w_cb.set_checked (True)
|
||||
end
|
||||
if not l_has_edit_permission then
|
||||
w_cb.set_is_readonly (True)
|
||||
end
|
||||
end
|
||||
else
|
||||
create w_select.make ({STRING_32} "taxonomy_terms[" + voc.name + "]")
|
||||
w_voc_set.extend (w_select)
|
||||
|
||||
if attached voc.description as l_desc then
|
||||
w_select.set_description (response.html_encoded (l_desc))
|
||||
else
|
||||
w_select.set_description (response.html_encoded (voc.name))
|
||||
end
|
||||
w_voc_set.set_legend (response.html_encoded (voc.name))
|
||||
|
||||
across
|
||||
voc as voc_terms_ic
|
||||
loop
|
||||
t := voc_terms_ic.item
|
||||
create w_opt.make (response.html_encoded (t.text), response.html_encoded (t.text))
|
||||
w_select.add_option (w_opt)
|
||||
|
||||
if l_terms /= Void and then across l_terms as ic some ic.item.text.same_string (t.text) end then
|
||||
w_opt.set_is_selected (True)
|
||||
end
|
||||
end
|
||||
if not l_has_edit_permission then
|
||||
w_select.set_is_readonly (True)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
f.submit_actions.extend (agent taxonomy_submit_action (response, l_taxonomy_api, l_vocs, a_node, ?))
|
||||
|
||||
if
|
||||
attached f.fields_by_name ("title") as l_title_fields and then
|
||||
attached l_title_fields.first as l_title_field
|
||||
then
|
||||
f.insert_after (w_set, l_title_field)
|
||||
else
|
||||
f.extend (w_set)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
taxonomy_submit_action (a_response: CMS_RESPONSE; a_taxonomy_api: CMS_TAXONOMY_API; a_vocs: CMS_VOCABULARY_COLLECTION; a_node: detachable CMS_NODE fd: WSF_FORM_DATA)
|
||||
require
|
||||
vocs_not_empty: not a_vocs.is_empty
|
||||
local
|
||||
l_voc_name: READABLE_STRING_32
|
||||
l_terms_to_remove: ARRAYED_LIST [CMS_TERM]
|
||||
l_new_terms: LIST [READABLE_STRING_32]
|
||||
l_text: READABLE_STRING_GENERAL
|
||||
l_found: BOOLEAN
|
||||
t: detachable CMS_TERM
|
||||
do
|
||||
if
|
||||
a_node /= Void and then a_node.has_id and then
|
||||
attached fd.table_item ("taxonomy_terms") as fd_terms
|
||||
then
|
||||
across
|
||||
fd_terms.values as ic
|
||||
loop
|
||||
if attached {WSF_STRING} ic.item as l_string then
|
||||
l_voc_name := ic.key
|
||||
l_new_terms := a_taxonomy_api.splitted_string (l_string.value, ',')
|
||||
if attached a_vocs.item_by_name (l_voc_name) as voc then
|
||||
if a_response.has_permissions (<<{STRING_32} "update any taxonomy", {STRING_32} "update " + content_type.name + " taxonomy">>) then
|
||||
create l_terms_to_remove.make (0)
|
||||
if attached a_taxonomy_api.terms_of_entity (content_type.name, a_node.id.out, voc) as l_existing_terms then
|
||||
across
|
||||
l_existing_terms as t_ic
|
||||
loop
|
||||
l_text := t_ic.item.text
|
||||
from
|
||||
l_found := False
|
||||
l_new_terms.start
|
||||
until
|
||||
l_new_terms.after
|
||||
loop
|
||||
if l_new_terms.item.same_string_general (l_text) then
|
||||
-- Already associated with term `t_ic.text'.
|
||||
l_found := True
|
||||
l_new_terms.remove
|
||||
else
|
||||
l_new_terms.forth
|
||||
end
|
||||
end
|
||||
if not l_found then
|
||||
-- Remove term
|
||||
l_terms_to_remove.force (t_ic.item)
|
||||
end
|
||||
end
|
||||
across
|
||||
l_terms_to_remove as t_ic
|
||||
loop
|
||||
a_taxonomy_api.unassociate_term_from_entity (t_ic.item, content_type.name, a_node.id.out)
|
||||
end
|
||||
end
|
||||
across
|
||||
l_new_terms as t_ic
|
||||
loop
|
||||
t := a_taxonomy_api.term_by_text (t_ic.item, voc)
|
||||
if
|
||||
t = Void and voc.is_tags
|
||||
then
|
||||
-- Create new term!
|
||||
create t.make (t_ic.item)
|
||||
a_taxonomy_api.save_term (t, voc)
|
||||
if a_taxonomy_api.has_error then
|
||||
t := Void
|
||||
end
|
||||
end
|
||||
if t /= Void then
|
||||
a_taxonomy_api.associate_term_with_entity (t, content_type.name, a_node.id.out)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
populate_form_with_path_alias (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
@@ -316,6 +537,33 @@ feature -- Output
|
||||
s.append ("</div>")
|
||||
|
||||
|
||||
if
|
||||
attached {CMS_TAXONOMY_API} a_response.api.module_api ({CMS_TAXONOMY_MODULE}) as l_taxonomy_api and then
|
||||
attached l_taxonomy_api.vocabularies_for_type (content_type.name) as vocs and then not vocs.is_empty
|
||||
then
|
||||
vocs.sort
|
||||
across
|
||||
vocs as ic
|
||||
loop
|
||||
if
|
||||
attached l_taxonomy_api.terms_of_entity (content_type.name, a_node.id.out, ic.item) as l_terms and then
|
||||
not l_terms.is_empty
|
||||
then
|
||||
s.append ("<ul class=%"taxonomy term-" + ic.item.id.out + "%">")
|
||||
s.append (a_response.html_encoded (ic.item.name))
|
||||
s.append (": ")
|
||||
across
|
||||
l_terms as t_ic
|
||||
loop
|
||||
s.append ("<li>")
|
||||
a_response.append_link_to_html (t_ic.item.text, "taxonomy/term/" + t_ic.item.id.out, Void, s)
|
||||
s.append ("</li>")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- We don't show the summary on the detail page, since its just a short view of the full content. Otherwise we would write the same thing twice.
|
||||
-- The usage of the summary is to give a short overview in the list of nodes or for the meta tag "description"
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ feature {NONE} -- Create a new node
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit (?, l_node, a_type, b))
|
||||
f.submit_actions.put_front (agent edit_form_submit (?, l_node, a_type, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
@@ -147,7 +147,7 @@ feature {NONE} -- Create a new node
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit (?, a_node, a_type, b))
|
||||
f.submit_actions.put_front (agent edit_form_submit (?, a_node, a_type, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<library name="cms" location="..\..\cms-safe.ecf"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes-safe.ecf" readonly="false"/>
|
||||
<library name="cms_taxonomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\web\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<library name="cms" location="..\..\cms.ecf"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes.ecf" readonly="false"/>
|
||||
<library name="cms_taxonomy_module" location="..\..\modules\taxonomy\taxonomy.ecf" readonly="false"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
|
||||
|
||||
@@ -46,7 +46,7 @@ feature -- Access node
|
||||
Result := taxonomy_storage.vocabulary_count
|
||||
end
|
||||
|
||||
vocabularies (a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_VOCABULARY]
|
||||
vocabularies (a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_VOCABULARY_COLLECTION
|
||||
-- List of vocabularies ordered by weight and limited by limit and offset.
|
||||
do
|
||||
Result := taxonomy_storage.vocabularies (a_limit, a_offset)
|
||||
@@ -60,6 +60,26 @@ feature -- Access node
|
||||
Result := taxonomy_storage.vocabulary (a_id)
|
||||
end
|
||||
|
||||
vocabularies_for_type (a_type_name: READABLE_STRING_GENERAL): detachable CMS_VOCABULARY_COLLECTION
|
||||
-- Vocabularies associated with content type `a_type_name'.
|
||||
do
|
||||
Result := taxonomy_storage.vocabularies_for_type (a_type_name)
|
||||
end
|
||||
|
||||
fill_vocabularies_with_terms (a_vocab: CMS_VOCABULARY)
|
||||
-- Fill `a_vocab' with associated terms.
|
||||
do
|
||||
reset_error
|
||||
a_vocab.terms.wipe_out
|
||||
if attached terms (a_vocab, 0, 0) as lst then
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
a_vocab.extend (ic.item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
term_count_from_vocabulary (a_vocab: CMS_VOCABULARY): INTEGER_64
|
||||
-- Number of terms from vocabulary `a_vocab'.
|
||||
require
|
||||
@@ -68,7 +88,14 @@ feature -- Access node
|
||||
Result := taxonomy_storage.term_count_from_vocabulary (a_vocab)
|
||||
end
|
||||
|
||||
terms (a_vocab: CMS_VOCABULARY; a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_TERM]
|
||||
terms_of_entity (a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM_COLLECTION
|
||||
-- Terms related to `(a_type_name,a_entity)', and if `a_vocabulary' is set
|
||||
-- constrain to be part of `a_vocabulary'.
|
||||
do
|
||||
Result := taxonomy_storage.terms_of_entity (a_type_name, a_entity, a_vocabulary)
|
||||
end
|
||||
|
||||
terms (a_vocab: CMS_VOCABULARY; a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_TERM_COLLECTION
|
||||
-- List of terms ordered by weight and limited by limit and offset.
|
||||
require
|
||||
has_id: a_vocab.has_id
|
||||
@@ -81,4 +108,111 @@ feature -- Access node
|
||||
Result := taxonomy_storage.term_by_id (a_tid)
|
||||
end
|
||||
|
||||
term_by_text (a_term_text: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM
|
||||
-- Term with text `a_term_text', included in vocabulary `a_vocabulary' if provided.
|
||||
do
|
||||
Result := taxonomy_storage.term_by_text (a_term_text, a_vocabulary)
|
||||
end
|
||||
|
||||
feature -- Write
|
||||
|
||||
save_vocabulary (a_voc: CMS_VOCABULARY)
|
||||
do
|
||||
reset_error
|
||||
taxonomy_storage.save_vocabulary (a_voc)
|
||||
error_handler.append (taxonomy_storage.error_handler)
|
||||
end
|
||||
|
||||
save_term (a_term: CMS_TERM; voc: CMS_VOCABULARY)
|
||||
do
|
||||
reset_error
|
||||
taxonomy_storage.save_term (a_term, voc)
|
||||
error_handler.append (taxonomy_storage.error_handler)
|
||||
end
|
||||
|
||||
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
-- Associate term `a_term' with `(a_type_name, a_entity)'.
|
||||
do
|
||||
reset_error
|
||||
taxonomy_storage.associate_term_with_entity (a_term, a_type_name, a_entity)
|
||||
error_handler.append (taxonomy_storage.error_handler)
|
||||
end
|
||||
|
||||
unassociate_term_from_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
-- Unassociate term `a_term' from `(a_type_name, a_entity)'.
|
||||
do
|
||||
reset_error
|
||||
taxonomy_storage.unassociate_term_from_entity (a_term, a_type_name, a_entity)
|
||||
error_handler.append (taxonomy_storage.error_handler)
|
||||
end
|
||||
|
||||
associate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- Associate vocabulary `a_voc' with type `a_type_name'.
|
||||
require
|
||||
existing_term: a_voc.has_id
|
||||
do
|
||||
reset_error
|
||||
taxonomy_storage.associate_vocabulary_with_type (a_voc, a_type_name)
|
||||
error_handler.append (taxonomy_storage.error_handler)
|
||||
end
|
||||
|
||||
unassociate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- Un-associate vocabulary `a_voc' from type `a_type_name'.
|
||||
require
|
||||
existing_term: a_voc.has_id
|
||||
do
|
||||
reset_error
|
||||
taxonomy_storage.unassociate_vocabulary_with_type (a_voc, a_type_name)
|
||||
error_handler.append (taxonomy_storage.error_handler)
|
||||
end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
splitted_string (s: READABLE_STRING_32; sep: CHARACTER): LIST [READABLE_STRING_32]
|
||||
-- Splitted string from `s' with separator `sep', and support '"..."' wrapping.
|
||||
local
|
||||
i,j,n,b: INTEGER
|
||||
t: STRING_32
|
||||
do
|
||||
create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (1)
|
||||
Result.compare_objects
|
||||
from
|
||||
i := 1
|
||||
b := 1
|
||||
n := s.count
|
||||
create t.make_empty
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
if s[i].is_space then
|
||||
if not t.is_empty then
|
||||
t.append_character (s[i])
|
||||
end
|
||||
elseif s[i] = sep then
|
||||
t.left_adjust
|
||||
t.right_adjust
|
||||
if t.count > 2 and t.starts_with_general ("%"") and t.ends_with_general ("%"") then
|
||||
t.remove_head (1)
|
||||
t.remove_tail (1)
|
||||
end
|
||||
Result.force (t)
|
||||
create t.make_empty
|
||||
elseif s[i] = '"' then
|
||||
j := s.index_of ('"', i + 1)
|
||||
if j > 0 then
|
||||
t.append (s.substring (i, j))
|
||||
end
|
||||
i := j
|
||||
else
|
||||
t.append_character (s[i])
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
if not t.is_empty then
|
||||
t.left_adjust
|
||||
t.right_adjust
|
||||
Result.force (t)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -17,7 +17,8 @@ inherit
|
||||
initialize,
|
||||
install,
|
||||
uninstall,
|
||||
taxonomy_api
|
||||
taxonomy_api,
|
||||
permissions
|
||||
end
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
@@ -41,6 +42,16 @@ feature -- Access
|
||||
|
||||
name: STRING = "taxonomy"
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.force ("admin taxonomy")
|
||||
Result.force ("update any taxonomy")
|
||||
Result.force ("update page taxonomy") -- related to node module
|
||||
Result.force ("update blog taxonomy") -- related to blog module
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (api: CMS_API)
|
||||
@@ -53,6 +64,9 @@ feature {CMS_API} -- Module Initialization
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
install (api: CMS_API)
|
||||
local
|
||||
voc: CMS_VOCABULARY
|
||||
l_taxonomy_api: like taxonomy_api
|
||||
do
|
||||
-- Schema
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
@@ -61,6 +75,13 @@ feature {CMS_API} -- Module management
|
||||
api.logger.put_error ("Could not install database for taxonomy module", generating_type)
|
||||
end
|
||||
Precursor (api)
|
||||
|
||||
create l_taxonomy_api.make (api)
|
||||
create voc.make ("Tags")
|
||||
voc.set_description ("Enter comma separated tags.")
|
||||
l_taxonomy_api.save_vocabulary (voc)
|
||||
voc.set_is_tags (True)
|
||||
l_taxonomy_api.associate_vocabulary_with_type (voc, "page")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -11,14 +11,25 @@ class
|
||||
inherit
|
||||
COMPARABLE
|
||||
|
||||
DEBUG_OUTPUT
|
||||
undefine
|
||||
is_equal
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
make,
|
||||
make_with_id
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_id: INTEGER_64; a_text: READABLE_STRING_GENERAL)
|
||||
make_with_id (a_id: INTEGER_64; a_text: READABLE_STRING_GENERAL)
|
||||
do
|
||||
id := a_id
|
||||
make (a_text)
|
||||
end
|
||||
|
||||
make (a_text: READABLE_STRING_GENERAL)
|
||||
do
|
||||
set_text (a_text)
|
||||
end
|
||||
|
||||
@@ -44,6 +55,19 @@ feature -- Status report
|
||||
Result := id > 0
|
||||
end
|
||||
|
||||
debug_output: STRING_32
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
create Result.make_empty
|
||||
Result.append_character ('#')
|
||||
Result.append (id.out)
|
||||
Result.append_character (' ')
|
||||
Result.append (text)
|
||||
Result.append_character (' ')
|
||||
Result.append ("weight=")
|
||||
Result.append_integer (weight)
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
|
||||
92
modules/taxonomy/cms_term_collection.e
Normal file
92
modules/taxonomy/cms_term_collection.e
Normal file
@@ -0,0 +1,92 @@
|
||||
note
|
||||
description: "[
|
||||
Collection of CMS terms (see Taxonomy).
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_TERM_COLLECTION
|
||||
|
||||
inherit
|
||||
ITERABLE [CMS_TERM]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (nb: INTEGER)
|
||||
do
|
||||
create items.make (nb)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
new_cursor: INDEXABLE_ITERATION_CURSOR [CMS_TERM]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := items.new_cursor
|
||||
end
|
||||
|
||||
count: INTEGER
|
||||
-- Number of terms.
|
||||
do
|
||||
Result := items.count
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_empty: BOOLEAN
|
||||
do
|
||||
Result := count = 0
|
||||
end
|
||||
|
||||
has (a_term: CMS_TERM): BOOLEAN
|
||||
-- Has `a_term'?
|
||||
do
|
||||
Result := items.has (a_term)
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
wipe_out
|
||||
-- Remove all items.
|
||||
do
|
||||
items.wipe_out
|
||||
ensure
|
||||
empty: count = 0
|
||||
end
|
||||
|
||||
force, extend (a_term: CMS_TERM)
|
||||
-- Add term `a_term';
|
||||
do
|
||||
if not has (a_term) then
|
||||
items.force (a_term)
|
||||
end
|
||||
end
|
||||
|
||||
remove (a_term: CMS_TERM)
|
||||
-- Remove term `a_term'.
|
||||
do
|
||||
items.prune_all (a_term)
|
||||
end
|
||||
|
||||
sort
|
||||
-- Sort `items'
|
||||
local
|
||||
l_sorter: QUICK_SORTER [CMS_TERM]
|
||||
do
|
||||
create l_sorter.make (create {COMPARABLE_COMPARATOR [CMS_TERM]})
|
||||
l_sorter.sort (items)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
items: ARRAYED_LIST [CMS_TERM]
|
||||
-- List of terms.
|
||||
|
||||
;note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
@@ -8,55 +8,120 @@ note
|
||||
class
|
||||
CMS_VOCABULARY
|
||||
|
||||
inherit
|
||||
CMS_TERM
|
||||
rename
|
||||
text as name,
|
||||
set_text as set_name
|
||||
redefine
|
||||
make
|
||||
end
|
||||
|
||||
ITERABLE [CMS_TERM]
|
||||
undefine
|
||||
is_equal
|
||||
end
|
||||
|
||||
create
|
||||
make,
|
||||
make_from_term
|
||||
make_with_id,
|
||||
make_from_term,
|
||||
make_none
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_tid: INTEGER_64; a_name: READABLE_STRING_GENERAL)
|
||||
make_none
|
||||
do
|
||||
id := a_tid
|
||||
set_name (a_name)
|
||||
create {ARRAYED_LIST [CMS_TERM]} items.make (0)
|
||||
make ("")
|
||||
end
|
||||
|
||||
make (a_name: READABLE_STRING_GENERAL)
|
||||
do
|
||||
Precursor (a_name)
|
||||
create terms.make (0)
|
||||
end
|
||||
|
||||
make_from_term (a_term: CMS_TERM)
|
||||
do
|
||||
make (a_term.id, a_term.text)
|
||||
make_with_id (a_term.id, a_term.text)
|
||||
description := a_term.description
|
||||
set_weight (a_term.weight)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
id: INTEGER_64
|
||||
|
||||
name: IMMUTABLE_STRING_32
|
||||
|
||||
description: detachable READABLE_STRING_32
|
||||
|
||||
items: LIST [CMS_TERM]
|
||||
terms: CMS_TERM_COLLECTION
|
||||
-- Collection of terms.
|
||||
|
||||
has_id: BOOLEAN
|
||||
new_cursor: INDEXABLE_ITERATION_CURSOR [CMS_TERM]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := id > 0
|
||||
Result := terms.new_cursor
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
associated_content_type: detachable READABLE_STRING_GENERAL
|
||||
-- Associated content type, if any.
|
||||
|
||||
is_tags: BOOLEAN
|
||||
-- New terms accepted (as tags), in the context of `associated_content_type'?
|
||||
|
||||
multiple_terms_allowed: BOOLEAN
|
||||
-- Accepts multiple terms, in the context of `associated_content_type'?
|
||||
|
||||
is_term_required: BOOLEAN
|
||||
-- At least one term is required, in the context of `associated_content_type'?
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_is_tags (b: BOOLEAN)
|
||||
-- Set `is_tags' to `b'.
|
||||
do
|
||||
is_tags := b
|
||||
end
|
||||
|
||||
allow_multiple_term (b: BOOLEAN)
|
||||
-- Set `multiple_terms_allowed' to `b'.
|
||||
do
|
||||
multiple_terms_allowed := b
|
||||
end
|
||||
|
||||
set_is_term_required (b: BOOLEAN)
|
||||
-- Set `is_term_required' to `b'.
|
||||
do
|
||||
is_term_required := b
|
||||
end
|
||||
|
||||
set_associated_content_type (a_type: detachable READABLE_STRING_GENERAL; a_is_tags, a_multiple, a_is_required: BOOLEAN)
|
||||
-- If `a_type' is set, define `associated_content_type' and related options,
|
||||
-- otherwise reset `associated_content_type'.
|
||||
do
|
||||
if a_type = Void then
|
||||
associated_content_type := Void
|
||||
set_is_tags (False)
|
||||
allow_multiple_term (False)
|
||||
set_is_term_required (False)
|
||||
else
|
||||
associated_content_type := a_type
|
||||
set_is_tags (a_is_tags)
|
||||
allow_multiple_term (a_multiple)
|
||||
set_is_term_required (a_is_required)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_name (a_name: READABLE_STRING_GENERAL)
|
||||
force, extend (a_term: CMS_TERM)
|
||||
-- Add `a_term' to the vocabulary terms `terms'.
|
||||
do
|
||||
create name.make_from_string_general (a_name)
|
||||
terms.force (a_term)
|
||||
end
|
||||
|
||||
sort
|
||||
-- Sort `items'
|
||||
local
|
||||
l_sorter: QUICK_SORTER [CMS_TERM]
|
||||
do
|
||||
create l_sorter.make (create {COMPARABLE_COMPARATOR [CMS_TERM]})
|
||||
l_sorter.sort (items)
|
||||
terms.sort
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
98
modules/taxonomy/cms_vocabulary_collection.e
Normal file
98
modules/taxonomy/cms_vocabulary_collection.e
Normal file
@@ -0,0 +1,98 @@
|
||||
note
|
||||
description: "[
|
||||
Collection of CMS vocabularies (see Taxonomy).
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_VOCABULARY_COLLECTION
|
||||
|
||||
inherit
|
||||
ITERABLE [CMS_VOCABULARY]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (nb: INTEGER)
|
||||
do
|
||||
create items.make (nb)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
item_by_name (a_voc_name: READABLE_STRING_GENERAL): detachable CMS_VOCABULARY
|
||||
-- Vocabulary from current collection associated with name `a_voc_name', if any.
|
||||
do
|
||||
across
|
||||
items as ic
|
||||
until
|
||||
Result /= Void
|
||||
loop
|
||||
if ic.item.name.is_case_insensitive_equal_general (a_voc_name) then
|
||||
Result := ic.item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_cursor: INDEXABLE_ITERATION_CURSOR [CMS_VOCABULARY]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := items.new_cursor
|
||||
end
|
||||
|
||||
count: INTEGER
|
||||
-- Number of vocabularies.
|
||||
do
|
||||
Result := items.count
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_empty: BOOLEAN
|
||||
do
|
||||
Result := count = 0
|
||||
end
|
||||
|
||||
has (a_vocabulary: CMS_VOCABULARY): BOOLEAN
|
||||
-- Has `a_vocabulary'?
|
||||
do
|
||||
Result := items.has (a_vocabulary)
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
force, extend (a_vocabulary: CMS_VOCABULARY)
|
||||
-- Add vocabulary `a_vocabulary';
|
||||
do
|
||||
if not has (a_vocabulary) then
|
||||
items.force (a_vocabulary)
|
||||
end
|
||||
end
|
||||
|
||||
remove (a_vocabulary: CMS_VOCABULARY)
|
||||
-- Remove vocabulary `a_vocabulary'.
|
||||
do
|
||||
items.prune_all (a_vocabulary)
|
||||
end
|
||||
|
||||
sort
|
||||
-- Sort `items'
|
||||
local
|
||||
l_sorter: QUICK_SORTER [CMS_VOCABULARY]
|
||||
do
|
||||
create l_sorter.make (create {COMPARABLE_COMPARATOR [CMS_VOCABULARY]})
|
||||
l_sorter.sort (items)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
items: ARRAYED_LIST [CMS_VOCABULARY]
|
||||
-- List of vocabularies.
|
||||
|
||||
;note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
@@ -22,8 +22,8 @@ feature -- Access
|
||||
deferred
|
||||
end
|
||||
|
||||
vocabularies (limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_VOCABULARY]
|
||||
-- List of vocabularies ordered by weight from offset to offset + limit.
|
||||
vocabularies (a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_VOCABULARY_COLLECTION
|
||||
-- List of vocabularies ordered by weight from `a_offset' to `a_offset + a_limit'.
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -34,6 +34,13 @@ feature -- Access
|
||||
deferred
|
||||
end
|
||||
|
||||
vocabularies_for_type (a_type_name: READABLE_STRING_GENERAL): detachable CMS_VOCABULARY_COLLECTION
|
||||
-- Vocabularies associated with content type `a_type_name'.
|
||||
require
|
||||
valid_type_name: not a_type_name.is_whitespace
|
||||
deferred
|
||||
end
|
||||
|
||||
terms_count: INTEGER_64
|
||||
-- Number of terms.
|
||||
deferred
|
||||
@@ -46,6 +53,13 @@ feature -- Access
|
||||
Result /= Void implies Result.id = tid
|
||||
end
|
||||
|
||||
term_by_text (a_term_text: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM
|
||||
-- Term with text `a_term_text', included in vocabulary `a_vocabulary' if provided.
|
||||
deferred
|
||||
ensure
|
||||
Result /= Void implies a_term_text.same_string (Result.text)
|
||||
end
|
||||
|
||||
term_count_from_vocabulary (a_vocab: CMS_VOCABULARY): INTEGER_64
|
||||
-- Number of terms from vocabulary `a_vocab'.
|
||||
require
|
||||
@@ -53,20 +67,61 @@ feature -- Access
|
||||
deferred
|
||||
end
|
||||
|
||||
terms (a_vocab: CMS_VOCABULARY; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_TERM]
|
||||
-- List of terms from vocabulary `a_vocab' ordered by weight from offset to offset + limit.
|
||||
terms (a_vocab: CMS_VOCABULARY; a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_TERM_COLLECTION
|
||||
-- List of terms from vocabulary `a_vocab' ordered by weight from `a_offset' to `a_offset + a_limit'.
|
||||
require
|
||||
has_id: a_vocab.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
terms_of_entity (a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM_COLLECTION
|
||||
-- Terms related to `(a_type_name,a_entity)', and if `a_vocabulary' is set
|
||||
-- constrain to be part of `a_vocabulary'.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Store
|
||||
|
||||
save_term (t: CMS_TERM)
|
||||
-- Insert or update term `t'.
|
||||
save_vocabulary (a_voc: CMS_VOCABULARY)
|
||||
-- Insert or update vocabulary `a_voc'.
|
||||
deferred
|
||||
ensure
|
||||
not error_handler.has_error implies a_voc.has_id and then vocabulary (a_voc.id) /= Void
|
||||
end
|
||||
|
||||
save_term (t: CMS_TERM; voc: CMS_VOCABULARY)
|
||||
-- Insert or update term `t' as part of vocabulary `voc'.
|
||||
deferred
|
||||
ensure
|
||||
not error_handler.has_error implies t.has_id and then term_by_id (t.id) /= Void
|
||||
end
|
||||
|
||||
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
-- Associate term `a_term' with `(a_type_name, a_entity)'.
|
||||
require
|
||||
existing_term: a_term.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
unassociate_term_from_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
-- Unassociate term `a_term' from `(a_type_name, a_entity)'.
|
||||
require
|
||||
existing_term: a_term.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
associate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- Associate vocabulary `a_voc' with type `a_type_name'.
|
||||
require
|
||||
existing_term: a_voc.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
unassociate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- Un-associate vocabulary `a_voc' from type `a_type_name'.
|
||||
require
|
||||
existing_term: a_voc.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -37,10 +37,10 @@ feature -- Access
|
||||
do
|
||||
end
|
||||
|
||||
vocabularies (limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_VOCABULARY]
|
||||
-- List of vocabularies ordered by weight from offset to offset + limit.
|
||||
vocabularies (a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_VOCABULARY_COLLECTION
|
||||
-- List of vocabularies ordered by weight from `a_offset' to `a_offset + a_limit'.
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_VOCABULARY]} Result.make (0)
|
||||
create Result.make (0)
|
||||
end
|
||||
|
||||
vocabulary (a_id: INTEGER_64): detachable CMS_VOCABULARY
|
||||
@@ -48,6 +48,11 @@ feature -- Access
|
||||
do
|
||||
end
|
||||
|
||||
vocabularies_for_type (a_type_name: READABLE_STRING_GENERAL): detachable CMS_VOCABULARY_COLLECTION
|
||||
-- <Precursor>
|
||||
do
|
||||
end
|
||||
|
||||
terms_count: INTEGER_64
|
||||
-- Number of terms.
|
||||
do
|
||||
@@ -58,18 +63,55 @@ feature -- Access
|
||||
do
|
||||
end
|
||||
|
||||
terms (a_vocab: CMS_VOCABULARY; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_TERM]
|
||||
-- List of terms from vocabulary `a_vocab' ordered by weight from offset to offset + limit.
|
||||
term_by_text (a_term_text: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM
|
||||
do
|
||||
end
|
||||
|
||||
terms (a_vocab: CMS_VOCABULARY; a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_TERM_COLLECTION
|
||||
-- List of terms from vocabulary `a_vocab' ordered by weight from `a_offset' to `a_offset + a_limit'.
|
||||
do
|
||||
create Result.make (0)
|
||||
end
|
||||
|
||||
terms_of_entity (a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM_COLLECTION
|
||||
-- Terms related to `(a_type_name,a_entity)'.
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_TERM]} Result.make (0)
|
||||
end
|
||||
|
||||
feature -- Store
|
||||
|
||||
save_term (t: CMS_TERM)
|
||||
-- Insert or update term `t'.
|
||||
save_vocabulary (a_voc: CMS_VOCABULARY)
|
||||
-- Insert or update vocabulary `a_voc'.
|
||||
do
|
||||
error_handler.add_custom_error (-1, "not implemented", "")
|
||||
error_handler.add_custom_error (-1, "not implemented", "save_vocabulary")
|
||||
end
|
||||
|
||||
save_term (t: CMS_TERM; voc: CMS_VOCABULARY)
|
||||
-- <Precursor>
|
||||
do
|
||||
error_handler.add_custom_error (-1, "not implemented", "save_term")
|
||||
end
|
||||
|
||||
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
do
|
||||
error_handler.add_custom_error (-1, "not implemented", "associate_term_with_entity")
|
||||
end
|
||||
|
||||
unassociate_term_from_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
do
|
||||
error_handler.add_custom_error (-1, "not implemented", "unassociate_term_from_entity")
|
||||
end
|
||||
|
||||
associate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- Associate vocabulary `a_voc' with type `a_type_name'.
|
||||
do
|
||||
error_handler.add_custom_error (-1, "not implemented", "associate_vocabulary_with_type")
|
||||
end
|
||||
|
||||
unassociate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- Un-associate vocabulary `a_voc' from type `a_type_name'.
|
||||
do
|
||||
error_handler.add_custom_error (-1, "not implemented", "unassociate_vocabulary_with_type")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -29,10 +29,28 @@ feature -- Access
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
vocabularies (limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_VOCABULARY]
|
||||
-- List of vocabularies ordered by weight from offset to offset + limit.
|
||||
vocabularies (a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_VOCABULARY_COLLECTION
|
||||
-- List of vocabularies ordered by weight from `a_offset' to `a_offset + a_limit'.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_VOCABULARY]} Result.make (0)
|
||||
create Result.make (0)
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (0, "parent_tid")
|
||||
from
|
||||
sql_query (sql_select_terms, l_parameters)
|
||||
sql_start
|
||||
until
|
||||
sql_after
|
||||
loop
|
||||
if attached fetch_term as l_term then
|
||||
Result.force (create {CMS_VOCABULARY}.make_from_term (l_term))
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
vocabulary (a_tid: INTEGER_64): detachable CMS_VOCABULARY
|
||||
@@ -58,18 +76,21 @@ feature -- Access
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
terms (a_vocab: CMS_VOCABULARY; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_TERM]
|
||||
-- List of terms from vocabulary `a_vocab' ordered by weight from offset to offset + limit.
|
||||
terms (a_vocab: CMS_VOCABULARY; a_limit: NATURAL_32; a_offset: NATURAL_32): CMS_TERM_COLLECTION
|
||||
-- List of terms from vocabulary `a_vocab' ordered by weight from `a_offset' to `a_offset + a_limit'.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_TERM]} Result.make (0)
|
||||
create Result.make (0)
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (1)
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (a_vocab.id, "parent_tid")
|
||||
-- l_parameters.put (a_limit, "limit")
|
||||
-- l_parameters.put (a_offset, "offset")
|
||||
from
|
||||
sql_query (sql_select_terms, l_parameters)
|
||||
-- sql_query (sql_select_terms_with_range, l_parameters)
|
||||
sql_start
|
||||
until
|
||||
sql_after
|
||||
@@ -109,9 +130,89 @@ feature -- Access
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
term_by_text (a_term_text: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_term_text, "text")
|
||||
if a_vocabulary /= Void then
|
||||
l_parameters.put (a_vocabulary.id, "parent_tid")
|
||||
sql_query (sql_select_vocabulary_term_by_text, l_parameters)
|
||||
else
|
||||
sql_query (sql_select_term_by_text, l_parameters)
|
||||
end
|
||||
sql_start
|
||||
if not has_error and not sql_after then
|
||||
Result := fetch_term
|
||||
end
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
terms_of_entity (a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL; a_vocabulary: detachable CMS_VOCABULARY): detachable CMS_TERM_COLLECTION
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_tids: ARRAYED_LIST [INTEGER_64]
|
||||
tid: INTEGER_64
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (a_type_name, "type")
|
||||
l_parameters.put (a_entity , "entity")
|
||||
if a_vocabulary /= Void then
|
||||
l_parameters.put (a_vocabulary.id , "parent_tid")
|
||||
sql_query (sql_select_vocabulary_terms_of_entity, l_parameters)
|
||||
else
|
||||
sql_query (sql_select_terms_of_entity, l_parameters)
|
||||
end
|
||||
|
||||
create l_tids.make (0)
|
||||
from
|
||||
sql_start
|
||||
until
|
||||
sql_after or has_error
|
||||
loop
|
||||
tid := sql_read_integer_64 (1)
|
||||
if tid > 0 then
|
||||
l_tids.force (tid)
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
sql_finalize
|
||||
if not l_tids.is_empty then
|
||||
create Result.make (l_tids.count)
|
||||
across
|
||||
l_tids as ic
|
||||
loop
|
||||
if
|
||||
ic.item > 0 and then
|
||||
attached term_by_id (ic.item) as t
|
||||
then
|
||||
Result.force (t)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Store
|
||||
|
||||
save_term (t: CMS_TERM)
|
||||
save_vocabulary (voc: CMS_VOCABULARY)
|
||||
do
|
||||
save_term (voc, create {CMS_VOCABULARY}.make_none)
|
||||
across
|
||||
voc.terms as ic
|
||||
until
|
||||
has_error
|
||||
loop
|
||||
save_term (ic.item, voc)
|
||||
end
|
||||
end
|
||||
|
||||
save_term (t: CMS_TERM; voc: CMS_VOCABULARY)
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
@@ -130,6 +231,11 @@ feature -- Store
|
||||
sql_insert (sql_insert_term, l_parameters)
|
||||
t.set_id (last_inserted_term_id)
|
||||
end
|
||||
if not has_error then
|
||||
l_parameters.put (t.id, "tid")
|
||||
l_parameters.put (voc.id, "parent_tid")
|
||||
sql_insert (sql_insert_term_in_vocabulary, l_parameters)
|
||||
end
|
||||
if has_error then
|
||||
sql_rollback_transaction
|
||||
else
|
||||
@@ -138,6 +244,148 @@ feature -- Store
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
-- Associate term `a_term' with `(a_type_name, a_entity)'.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (a_term.id, "tid")
|
||||
l_parameters.put (a_entity, "entity")
|
||||
l_parameters.put (a_type_name, "type")
|
||||
|
||||
sql_insert (sql_insert_term_index, l_parameters)
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
unassociate_term_from_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
|
||||
-- Unassociate term `a_term' from `(a_type_name, a_entity)'.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (a_term.id, "tid")
|
||||
l_parameters.put (a_entity, "entity")
|
||||
l_parameters.put (a_type_name, "type")
|
||||
|
||||
sql_modify (sql_delete_term_index, l_parameters)
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
feature -- Vocabulary and types
|
||||
|
||||
mask_is_tags: INTEGER = 0b0001 -- 1
|
||||
mask_multiple_terms: INTEGER = 0b0010 -- 2
|
||||
mask_is_required: INTEGER = 0b0100 -- 4
|
||||
|
||||
vocabularies_for_type (a_type_name: READABLE_STRING_GENERAL): detachable CMS_VOCABULARY_COLLECTION
|
||||
-- <Precursor>
|
||||
-- note: vocabularies are not filled with associated terms.
|
||||
local
|
||||
voc: detachable CMS_VOCABULARY
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_data: ARRAYED_LIST [TUPLE [tid: INTEGER_64; entity: INTEGER_64]]
|
||||
tid, ent: INTEGER_64
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (a_type_name, "type")
|
||||
sql_query (sql_select_vocabularies_for_type, l_parameters)
|
||||
|
||||
create l_data.make (0)
|
||||
from
|
||||
sql_start
|
||||
until
|
||||
sql_after or has_error
|
||||
loop
|
||||
tid := sql_read_integer_64 (1)
|
||||
if attached sql_read_string_32 (2) as s and then s.is_integer_64 then
|
||||
ent := s.to_integer_64
|
||||
else
|
||||
ent := 0
|
||||
end
|
||||
if ent > 0 then
|
||||
-- Vocabulary index should have 0 or negative value for `entity'!
|
||||
check zero_or_negative_entity_value: False end
|
||||
else
|
||||
ent := - ent
|
||||
if tid > 0 then
|
||||
l_data.force ([tid, ent])
|
||||
end
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
sql_finalize
|
||||
if not l_data.is_empty then
|
||||
create Result.make (l_data.count)
|
||||
across
|
||||
l_data as ic
|
||||
loop
|
||||
tid := ic.item.tid
|
||||
ent := ic.item.entity
|
||||
check ic.item.tid > 0 end
|
||||
|
||||
if
|
||||
attached term_by_id (tid) as t
|
||||
then
|
||||
create voc.make_from_term (t)
|
||||
--| 1: mask 0001: New terms allowed (i.e tags)
|
||||
--| 2: mask 0010: Allow multiple tags
|
||||
--| 4: mask 0100: At least one tag is required
|
||||
voc.set_associated_content_type (a_type_name, ent & mask_is_tags = mask_is_tags, ent & mask_multiple_terms = mask_multiple_terms, ent & mask_is_required = mask_is_required)
|
||||
Result.force (voc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
associate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
i: INTEGER
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (3)
|
||||
l_parameters.put (a_voc.id, "tid")
|
||||
if a_voc.is_tags then
|
||||
i := i | mask_is_tags
|
||||
end
|
||||
if a_voc.is_term_required then
|
||||
i := i | mask_multiple_terms
|
||||
end
|
||||
if a_voc.multiple_terms_allowed then
|
||||
i := i | mask_is_required
|
||||
end
|
||||
l_parameters.put ((- i).out, "entity")
|
||||
|
||||
l_parameters.put (a_type_name, "type")
|
||||
|
||||
sql_insert (sql_insert_term_index, l_parameters)
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
unassociate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_voc.id, "tid")
|
||||
l_parameters.put (a_type_name, "type")
|
||||
|
||||
sql_insert (sql_delete_vocabulary_index, l_parameters)
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
feature {NONE} -- Queries
|
||||
|
||||
last_inserted_term_id: INTEGER_64
|
||||
@@ -159,7 +407,7 @@ feature {NONE} -- Queries
|
||||
tid := sql_read_integer_64 (1)
|
||||
l_text := sql_read_string_32 (2)
|
||||
if tid > 0 and l_text /= Void then
|
||||
create Result.make (tid, l_text)
|
||||
create Result.make_with_id (tid, l_text)
|
||||
Result.set_weight (sql_read_integer_32 (3))
|
||||
if attached sql_read_string_32 (4) as l_desc then
|
||||
Result.set_description (l_desc)
|
||||
@@ -176,27 +424,85 @@ feature {NONE} -- Queries
|
||||
sql_select_vocabulary_terms_count: STRING = "SELECT count(*) FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid WHERE taxonomy_hierarchy.parent = :parent_tid;"
|
||||
-- Number of terms under :parent_tid.
|
||||
|
||||
sql_select_vocabularies: STRING = "SELECT taxonomy_term.tid, taxonomy_term.text, taxonomy_term.weight, taxonomy_term.description FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid WHERE taxonomy_hierarchy.parent = 0;"
|
||||
-- Terms without parent.
|
||||
|
||||
sql_select_terms: STRING = "SELECT taxonomy_term.tid, taxonomy_term.text, taxonomy_term.weight, taxonomy_term.description FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid WHERE taxonomy_hierarchy.parent = :parent_tid;"
|
||||
sql_select_terms: STRING = "[
|
||||
SELECT taxonomy_term.tid, taxonomy_term.text, taxonomy_term.weight, taxonomy_term.description
|
||||
FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid
|
||||
WHERE taxonomy_hierarchy.parent = :parent_tid
|
||||
ORDER BY taxonomy_term.weight ASC ;
|
||||
]"
|
||||
-- Terms under :parent_tid.
|
||||
|
||||
sql_select_term: STRING = "SELECT tid, text, weight, description FROM taxonomy_term WHERE tid = :tid;"
|
||||
sql_select_terms_with_range: STRING = "[
|
||||
SELECT taxonomy_term.tid, taxonomy_term.text, taxonomy_term.weight, taxonomy_term.description
|
||||
FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid
|
||||
WHERE taxonomy_hierarchy.parent = :parent_tid
|
||||
ORDER BY taxonomy_term.weight ASC LIMIT :limit OFFSET :offset
|
||||
;
|
||||
]"
|
||||
-- Terms under :parent_tid, and :limit, :offset
|
||||
|
||||
sql_select_term: STRING = "SELECT tid, text, weight, description FROM taxonomy_term WHERE tid=:tid;"
|
||||
-- Term with tid :tid .
|
||||
|
||||
sql_select_term_by_text: STRING = "SELECT tid, text, weight, description FROM taxonomy_term WHERE text=:text;"
|
||||
-- Term with text :text .
|
||||
|
||||
sql_select_vocabulary_term_by_text: STRING = "[
|
||||
SELECT taxonomy_term.tid, taxonomy_term.text, taxonomy_term.weight, taxonomy_term.description
|
||||
FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid
|
||||
WHERE taxonomy_hierarchy.parent=:parent_tid AND taxonomy_term.text=:text
|
||||
;
|
||||
]"
|
||||
-- Term with text :text and with parent :parent_tid
|
||||
|
||||
Sql_last_inserted_term_id: STRING = "SELECT MAX(tid) FROM taxonomy_term;"
|
||||
|
||||
sql_insert_term: STRING = "[
|
||||
INSERT INTO taxonomy_terms (tid, text, weight, description, langcode)
|
||||
VALUES (:tid, :text, :weight, :description, null);
|
||||
INSERT INTO taxonomy_term (text, weight, description, langcode)
|
||||
VALUES (:text, :weight, :description, null);
|
||||
]"
|
||||
|
||||
sql_update_term: STRING = "[
|
||||
UPDATE taxonomy_terms
|
||||
UPDATE taxonomy_term
|
||||
SET tid=:tid, text=:text, weight=:weight, description=:description, langcode=null
|
||||
WHERE tid=:tid;
|
||||
]"
|
||||
|
||||
|
||||
sql_insert_term_in_vocabulary: STRING = "[
|
||||
INSERT INTO taxonomy_hierarchy (tid, parent)
|
||||
VALUES (:tid, :parent_tid);
|
||||
]"
|
||||
|
||||
sql_select_terms_of_entity: STRING = "[
|
||||
SELECT tid FROM taxonomy_index WHERE type=:type AND entity=:entity;
|
||||
]"
|
||||
|
||||
sql_select_vocabulary_terms_of_entity: STRING = "[
|
||||
SELECT taxonomy_index.tid
|
||||
FROM taxonomy_index INNER JOIN taxonomy_hierarchy ON taxonomy_index.tid=taxonomy_hierarchy.tid
|
||||
WHERE taxonomy_hierarchy.parent=:parent_tid AND taxonomy_index.type=:type AND taxonomy_index.entity=:entity;
|
||||
]"
|
||||
|
||||
sql_select_vocabularies_for_type: STRING = "[
|
||||
SELECT tid, entity
|
||||
FROM taxonomy_index
|
||||
WHERE type=:type AND entity <= 0;
|
||||
]"
|
||||
|
||||
sql_insert_term_index: STRING = "[
|
||||
INSERT INTO taxonomy_index (tid, entity, type)
|
||||
VALUES (:tid, :entity, :type);
|
||||
]"
|
||||
|
||||
sql_delete_term_index: STRING = "[
|
||||
DELETE FROM taxonomy_index WHERE tid=:tid AND entity=:entity AND type=:type
|
||||
;
|
||||
]"
|
||||
|
||||
sql_delete_vocabulary_index: STRING = "[
|
||||
DELETE FROM taxonomy_index WHERE tid=:tid AND type=:type
|
||||
;
|
||||
]"
|
||||
|
||||
|
||||
end
|
||||
|
||||
21
modules/taxonomy/site/files/css/taxonomy.css
Normal file
21
modules/taxonomy/site/files/css/taxonomy.css
Normal file
@@ -0,0 +1,21 @@
|
||||
ul.taxonomy {
|
||||
font-size: 80%;
|
||||
list-style-type: none;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
ul.taxonomy li {
|
||||
padding: 2px;
|
||||
margin-right: 3px;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
}
|
||||
ul.taxonomy li a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
ul.taxonomy li:hover {
|
||||
padding: 1px;
|
||||
border-top: solid 1px #66f;
|
||||
border-bottom: solid 1px #66f;
|
||||
background-color: #ddf;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
ul.taxonomy {
|
||||
font-size: 80%;
|
||||
list-style-type: none;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
li {
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
padding: 2px;
|
||||
margin-right: 3px;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
&:hover {
|
||||
padding: 1px;
|
||||
border-top: solid 1px #66f;
|
||||
border-bottom: solid 1px #66f;
|
||||
background-color: #ddf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
CREATE TABLE taxonomy_term (
|
||||
`tid` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
|
||||
`text` VARCHAR(255) NOT NULL,
|
||||
@@ -11,3 +12,13 @@ CREATE TABLE taxonomy_hierarchy (
|
||||
`parent` INTEGER,
|
||||
CONSTRAINT PK_tid_parent PRIMARY KEY (tid,parent)
|
||||
);
|
||||
|
||||
/* Associate tid with unique (type,entity)
|
||||
* for instance: "page" + "$nid" -> "tid"
|
||||
*/
|
||||
CREATE TABLE taxonomy_index (
|
||||
`tid` INTEGER NOT NULL,
|
||||
`entity` VARCHAR(255),
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
CONSTRAINT PK_tid_entity_type PRIMARY KEY (tid,entity,type)
|
||||
);
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
DROP TABLE IF EXISTS taxonomy_term;
|
||||
DROP TABLE IF EXISTS taxonomy_hierarchy;
|
||||
DROP TABLE IF EXISTS taxonomy_index;
|
||||
|
||||
26
modules/taxonomy/taxonomy.ecf
Normal file
26
modules/taxonomy/taxonomy.ecf
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_taxonomy_module" uuid="6FD848D1-5B07-46EE-B7F5-CFE2BB01479D" library_target="cms_taxonomy_module">
|
||||
<target name="cms_taxonomy_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
|
||||
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
|
||||
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -132,14 +132,16 @@ feature {NONE} -- Implementation: update
|
||||
until
|
||||
not a_module.is_enabled
|
||||
loop
|
||||
if
|
||||
attached a_collection.item (ic.item) as mod and then
|
||||
mod.is_enabled
|
||||
then
|
||||
update_module_status_within (mod, a_collection)
|
||||
else
|
||||
--| dependency not found or disabled
|
||||
a_module.disable
|
||||
if ic.item.is_required then
|
||||
if
|
||||
attached a_collection.item (ic.item.module_type) as mod and then
|
||||
mod.is_enabled
|
||||
then
|
||||
update_module_status_within (mod, a_collection)
|
||||
else
|
||||
--| dependency not found or disabled
|
||||
a_module.disable
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -236,16 +236,22 @@ feature -- Access
|
||||
|
||||
sql_start
|
||||
-- Set the cursor on first element.
|
||||
require
|
||||
no_error: not has_error
|
||||
deferred
|
||||
end
|
||||
|
||||
sql_after: BOOLEAN
|
||||
-- Are there no more items to iterate over?
|
||||
require
|
||||
no_error: not has_error
|
||||
deferred
|
||||
end
|
||||
|
||||
sql_forth
|
||||
-- Fetch next row from last sql execution, if any.
|
||||
require
|
||||
no_error: not has_error
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -255,6 +261,7 @@ feature -- Access
|
||||
|
||||
sql_item (a_index: INTEGER): detachable ANY
|
||||
require
|
||||
no_error: not has_error
|
||||
valid_index: sql_valid_item_index (a_index)
|
||||
deferred
|
||||
end
|
||||
@@ -446,7 +453,7 @@ feature {NONE} -- Implementation
|
||||
across
|
||||
l_removals as ic
|
||||
loop
|
||||
Result.remove_substring (ic.item.start_index - j, ic.item.end_index - j)
|
||||
Result.remove_substring (ic.item.start_index - j - a_start_index + 1, ic.item.end_index - j - a_start_index + 1)
|
||||
j := j + ic.item.end_index - ic.item.start_index + 1
|
||||
end
|
||||
-- a_offset.replace (a_offset.item j)
|
||||
|
||||
@@ -29,8 +29,8 @@ feature -- Access
|
||||
version: STRING
|
||||
-- Version of the module?
|
||||
|
||||
dependencies: detachable LIST [TYPE [CMS_MODULE]]
|
||||
-- Optional dependencies.
|
||||
dependencies: detachable LIST [TUPLE [module_type: TYPE [CMS_MODULE]; is_required: BOOLEAN]]
|
||||
-- Optional declaration for dependencies.
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
@@ -55,16 +55,22 @@ feature {CMS_API} -- Module Initialization
|
||||
end
|
||||
|
||||
add_dependency (a_type: TYPE [CMS_MODULE])
|
||||
-- Add dependency using type of module `a_type'.
|
||||
local
|
||||
deps: like dependencies
|
||||
-- Add required dependency using type of module `a_type'.
|
||||
do
|
||||
deps := dependencies
|
||||
if deps = Void then
|
||||
create {ARRAYED_LIST [TYPE [CMS_MODULE]]} deps.make (1)
|
||||
dependencies := deps
|
||||
put_dependency (a_type, True)
|
||||
end
|
||||
|
||||
put_dependency (a_type: TYPE [CMS_MODULE]; is_required: BOOLEAN)
|
||||
-- Add required or optional dependency using type of module `a_type', based on `is_required' value.
|
||||
local
|
||||
lst: like dependencies
|
||||
do
|
||||
lst := dependencies
|
||||
if lst = Void then
|
||||
create {ARRAYED_LIST [TUPLE [module_type: TYPE [CMS_MODULE]; is_required: BOOLEAN]]} lst.make (1)
|
||||
dependencies := lst
|
||||
end
|
||||
deps.force (a_type)
|
||||
lst.force ([a_type, is_required])
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
Reference in New Issue
Block a user