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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user