note description: "Summary description for {BAD_REQUEST_ERROR_CMS_RESPONSE}." date: "$Date: 2017-09-06 20:40:40 +0000 (Wed, 06 Sep 2017) $" revision: "$Revision: 100739 $" class BAD_REQUEST_ERROR_CMS_RESPONSE create make feature {NONE} -- Initialization default_create -- Process instances of classes with no creation clause. -- (Default: do nothing.) -- (from ANY) do end initialize -- (from CMS_RESPONSE) do Precursor get_theme create menu_system.make initialize_block_region_settings end make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api) -- (from CMS_RESPONSE) do create values.make (3) Precursor (req, res, a_api) end feature -- Access generating_type: TYPE [detachable BAD_REQUEST_ERROR_CMS_RESPONSE] -- Type of current object -- (type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generating_type_not_void: Result /= Void end generator: STRING_8 -- Name of current object's generating class -- (base class of the type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generator_not_void: Result /= Void generator_not_empty: not Result.is_empty end header: WSF_HEADER -- (from CMS_RESPONSE_I) main_content: detachable STRING_8 -- (from CMS_RESPONSE) request: WSF_REQUEST -- (from CMS_RESPONSE_I) response: WSF_RESPONSE -- (from CMS_RESPONSE_I) status_code: INTEGER_32 -- (from CMS_RESPONSE_I) feature -- Comparison frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void -- or attached to isomorphic object structures? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_deep_equal (b) end ensure -- from ANY instance_free: class shallow_implies_deep: standard_equal (a, b) implies Result both_or_none_void: (a = Void) implies (Result = (b = Void)) same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b)) symmetric: Result implies deep_equal (b, a) end frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached -- to objects considered equal? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b)) end frozen is_deep_equal (other: BAD_REQUEST_ERROR_CMS_RESPONSE): BOOLEAN -- Are Current and other attached to isomorphic object structures? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY shallow_implies_deep: standard_is_equal (other) implies Result same_type: Result implies same_type (other) symmetric: Result implies other.is_deep_equal (Current) end is_equal (other: BAD_REQUEST_ERROR_CMS_RESPONSE): BOOLEAN -- Is other attached to an object considered -- equal to current object? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result end frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached to -- field-by-field identical objects of the same type? -- Always uses default object comparison criterion. -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.standard_is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b)) end frozen standard_is_equal (other: BAD_REQUEST_ERROR_CMS_RESPONSE): BOOLEAN -- Is other attached to an object of the same type -- as current object, and field-by-field identical to it? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY same_type: Result implies same_type (other) symmetric: Result implies other.standard_is_equal (Current) end feature -- Status report conforms_to (other: ANY): BOOLEAN -- Does type of current object conform to type -- of other (as per Eiffel: The Language, chapter 13)? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" end same_type (other: ANY): BOOLEAN -- Is type of current object identical to type of other? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY definition: Result = (conforms_to (other) and other.conforms_to (Current)) end feature -- Duplication frozen clone (other: detachable ANY): like other obsolete "Use `twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- equal to other -- -- For non-void other, clone calls copy; -- to change copying/cloning semantics, redefine copy. -- (from ANY) do if other /= Void then Result := other.twin end ensure -- from ANY instance_free: class equal: Result ~ other end copy (other: BAD_REQUEST_ERROR_CMS_RESPONSE) -- Update current object using fields of object attached -- to other, so as to yield equal objects. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_equal: Current ~ other end frozen deep_clone (other: detachable ANY): like other obsolete "Use `deep_twin' instead. [2017-05-31]" -- Void if other is void: otherwise, new object structure -- recursively duplicated from the one attached to other -- (from ANY) do if other /= Void then Result := other.deep_twin end ensure -- from ANY instance_free: class deep_equal: deep_equal (other, Result) end frozen deep_copy (other: BAD_REQUEST_ERROR_CMS_RESPONSE) -- Effect equivalent to that of: -- copy (other . deep_twin) -- (from ANY) require -- from ANY other_not_void: other /= Void do copy (other.deep_twin) ensure -- from ANY deep_equal: deep_equal (Current, other) end frozen deep_twin: BAD_REQUEST_ERROR_CMS_RESPONSE -- New object structure recursively duplicated from Current. -- (from ANY) external "built_in" ensure -- from ANY deep_twin_not_void: Result /= Void deep_equal: deep_equal (Current, Result) end frozen standard_clone (other: detachable ANY): like other obsolete "Use `standard_twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) do if other /= Void then Result := other.standard_twin end ensure -- from ANY instance_free: class equal: standard_equal (Result, other) end frozen standard_copy (other: BAD_REQUEST_ERROR_CMS_RESPONSE) -- Copy every field of other onto corresponding field -- of current object. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_standard_equal: standard_is_equal (other) end frozen standard_twin: BAD_REQUEST_ERROR_CMS_RESPONSE -- New object field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) external "built_in" ensure -- from ANY standard_twin_not_void: Result /= Void equal: standard_equal (Result, Current) end frozen twin: BAD_REQUEST_ERROR_CMS_RESPONSE -- New object equal to Current -- twin calls copy; to change copying/twinning semantics, redefine copy. -- (from ANY) external "built_in" ensure -- from ANY twin_not_void: Result /= Void is_equal: Result ~ Current end feature -- Basic operations frozen as_attached: attached BAD_REQUEST_ERROR_CMS_RESPONSE obsolete "Remove calls to this feature. [2017-05-31]" -- Attached version of Current. -- (Can be used during transitional period to convert -- non-void-safe classes to void-safe ones.) -- (from ANY) do Result := Current end frozen default: detachable BAD_REQUEST_ERROR_CMS_RESPONSE -- Default value of object's type -- (from ANY) do end frozen default_pointer: POINTER -- Default value of type POINTER -- (Avoid the need to write p.default for -- some p of type POINTER.) -- (from ANY) do ensure -- from ANY instance_free: class end default_rescue -- Process exception for routines with no Rescue clause. -- (Default: do nothing.) -- (from ANY) do end frozen do_nothing -- Execute a null action. -- (from ANY) do ensure -- from ANY instance_free: class end feature -- API api: CMS_API -- Current CMS API. -- (from CMS_RESPONSE_I) formats: CMS_FORMATS -- Available content formats. -- (from CMS_RESPONSE) do Result := api.formats end setup: CMS_SETUP -- Current setup -- (from CMS_RESPONSE_I) do Result := api.setup end feature -- Access: CMS front_page_url: READABLE_STRING_8 -- (from CMS_RESPONSE_I) do Result := absolute_url ("/", Void) end site_name: STRING_32 -- (from CMS_RESPONSE_I) do Result := setup.site_name.as_string_32 end values: CMS_VALUE_TABLE -- Associated values indexed by string name. -- (from CMS_RESPONSE) feature -- Access: metadata add_metadata (v: READABLE_STRING_32; k: READABLE_STRING_GENERAL) -- Add v as metadata k, allows mutiple occurrences. -- (from CMS_RESPONSE_I) local md: like metadata do md := metadata if md = Void then create md.make (1) metadata := md end md.add (v, k) end additional_page_head_lines: detachable LIST [READABLE_STRING_8] -- HTML>head>...extra lines -- (from CMS_RESPONSE) description: detachable READABLE_STRING_32 -- (from CMS_RESPONSE) keywords: detachable ARRAYED_LIST [READABLE_STRING_32] -- (from CMS_RESPONSE_I) modification_date: detachable DATE_TIME -- Optional modification date. -- (from CMS_RESPONSE_I) page_title: detachable READABLE_STRING_32 -- Page title -- (from CMS_RESPONSE) publication_date: detachable DATE_TIME -- Optional publication date. -- (from CMS_RESPONSE_I) redirection: detachable READABLE_STRING_8 -- Location for eventual redirection. -- (from CMS_RESPONSE_I) redirection_delay: NATURAL_32 -- Optional redirection delay in seconds. -- (from CMS_RESPONSE_I) set_metadata (v: READABLE_STRING_32; k: READABLE_STRING_GENERAL) -- Set v as metadata k, replace any previous occurrences (if any). -- (from CMS_RESPONSE_I) local md: like metadata do md := metadata if md = Void then create md.make (1) metadata := md end md.put (v, k) end title: detachable READABLE_STRING_32 -- (from CMS_RESPONSE) feature -- Access: query location: IMMUTABLE_STRING_8 -- Associated cms local location. -- (from CMS_RESPONSE_I) request_url (opts: detachable CMS_API_OPTIONS): STRING_8 -- Current request location as a url. -- (from CMS_RESPONSE_I) do Result := url (location, opts) end feature -- Block management block_cache (a_block_id: READABLE_STRING_8): detachable TUPLE [cache_block: CMS_CACHE_BLOCK; region: READABLE_STRING_8; expired: BOOLEAN] -- Cached version of block a_block_id. -- (from CMS_RESPONSE) local l_cache: CMS_FILE_STRING_8_CACHE do if attached setup.text_item ("blocks." + a_block_id + ".expiration") as nb_secs and then nb_secs.is_integer then if attached block_region_preference (a_block_id, "none") as l_region and then not l_region.same_string_general ("none") then create l_cache.make (api.cache_location.extended ("_blocks").extended (a_block_id).appended_with_extension ("html")) if l_cache.exists and then not l_cache.expired (Void, nb_secs.to_integer) then Result := [create {CMS_CACHE_BLOCK}.make (a_block_id, l_cache), l_region, False] else Result := [create {CMS_CACHE_BLOCK}.make (a_block_id, l_cache), l_region, True] end end end end block_conditions (a_block_id: READABLE_STRING_8): detachable ARRAYED_LIST [CMS_BLOCK_EXPRESSION_CONDITION] -- Condition associated with a_block_id in configuration, if any. -- (from CMS_RESPONSE) do if attached setup.text_item ("blocks." + a_block_id + ".condition") as s then create Result.make (1) Result.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (s)) end if attached setup.text_list_item ("blocks." + a_block_id + ".conditions") as lst then if Result = Void then create Result.make (lst.count) end across lst as ic loop Result.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (ic.item)) end end end block_options (a_block_id: READABLE_STRING_8): detachable STRING_TABLE [READABLE_STRING_32] -- Options associated with a_block_id in configuration, if any. -- (from CMS_RESPONSE) do if attached setup.text_table_item ("blocks." + a_block_id + ".options") as tb then Result := tb end end clear_block_caches (a_block_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]) -- Clear cache for block a_block_id_list if set, -- otherwise clear all block caches if a_block_id_list is Void. -- (from CMS_RESPONSE) local p, pb: PATH dir: DIRECTORY l_cache: CMS_FILE_STRING_8_CACHE do p := api.cache_location.extended ("_blocks") if a_block_id_list /= Void then across a_block_id_list as ic loop pb := p.extended (ic.item).appended_with_extension ("html") create l_cache.make (pb) if l_cache.exists then l_cache.delete end end else create dir.make_with_path (p) dir.recursive_delete end add_notice_message ("Blocks cache cleared.") end is_block_included (a_block_id: READABLE_STRING_8; dft: BOOLEAN): BOOLEAN -- Is block a_block_id included in current response? -- If no preference, return dft. -- (from CMS_RESPONSE) do if attached block_conditions (a_block_id) as l_conditions then Result := across l_conditions as ic some ic.item.satisfied_for_response (Current) end else Result := dft end end update_block (a_block: CMS_BLOCK) -- Update parameters for block a_block according to configuration. -- (from CMS_RESPONSE) do if attached setup.text_item ("blocks." + a_block.name + ".weight") as w and then w.is_integer then a_block.set_weight (w.to_integer) end if attached setup.text_item ("blocks." + a_block.name + ".title") as l_title then if l_title.same_string ("<none>".as_string_32) then a_block.set_title (Void) else a_block.set_title (l_title) end end end feature {CMS_HOOK_CORE_MANAGER} -- Block management: internal block_alias_table: detachable STRING_TABLE [LIST [READABLE_STRING_8]] -- Table of included block aliases, if any. -- note: { block_id => [ alias-names ..] } -- (from CMS_RESPONSE) local k, v: READABLE_STRING_GENERAL l_block_id, l_alias_id: READABLE_STRING_8 lst: detachable LIST [READABLE_STRING_8] do Result := internal_block_alias_table if Result = Void and then attached setup.text_table_item ("blocks.&aliases") as tb then create Result.make (tb.count) across tb as ic loop k := ic.key v := ic.item if v.is_valid_as_string_8 then l_block_id := v.to_string_8 if k.is_valid_as_string_8 then l_alias_id := k.to_string_8 if is_block_included (l_alias_id, False) then lst := Result.item (l_block_id) if lst = Void then create {ARRAYED_LIST [READABLE_STRING_8]} lst.make (1) end lst.force (l_alias_id) Result.force (lst, l_block_id) end else check valid_alias_id: False end end else check valid_block_id: False end end end end end internal_block_alias_table: like block_alias_table -- Internal memory cache for block_alias_table. -- (from CMS_RESPONSE) feature {NONE} -- Blocks put_core_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8; is_block_included_by_default: BOOLEAN; a_alias_table: like block_alias_table) -- Add block b to associated region or a_default_region if provided -- and check optional associated condition. -- If no condition then use is_block_included_by_default to -- decide if block is included or not. -- (from CMS_RESPONSE) local l_region: detachable like block_region do if is_block_included (b.name, is_block_included_by_default) then l_region := block_region (b, a_default_region) l_region.extend (b) blocks.force (b, b.name) end if a_alias_table /= Void and then attached a_alias_table.item (b.name) as l_aliases then across l_aliases as ic loop add_block (create {CMS_ALIAS_BLOCK}.make_with_block (ic.item, b), a_default_region) end end end feature -- Blocks add_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8) -- Add block b to associated region or a_default_region if provided. -- WARNING: ignore any block condition! USE WITH CARE! -- (from CMS_RESPONSE) local l_region: detachable like block_region do l_region := block_region (b, a_default_region) l_region.extend (b) blocks.force (b, b.name) end content_block: CMS_CONTENT_BLOCK -- (from CMS_RESPONSE) local s: STRING_8 do if attached main_content as l_content then s := l_content else s := "" debug s := "No Content" end end create Result.make ("content", Void, s, Void) Result.set_weight (-1) Result.set_is_raw (True) end get_blocks -- Get block from CMS core, and from modules. -- (from CMS_RESPONSE) local l_region: CMS_BLOCK_REGION b: CMS_BLOCK do get_core_blocks get_module_blocks across regions as reg_ic loop l_region := reg_ic.item across l_region.blocks as ic loop update_block (ic.item) end l_region.sort end debug ("cms") create {CMS_CONTENT_BLOCK} b.make ("made_with", Void, "Made with <a href=%"https://www.eiffel.org/%">EWF</a>", Void) b.set_weight (99) put_block (b, "footer", True) end end get_core_blocks -- Get blocks provided by the CMS core. -- (from CMS_RESPONSE) local l_alias_table: like block_alias_table do l_alias_table := block_alias_table put_core_block (top_header_block, "top", True, l_alias_table) put_core_block (header_block, "header", True, l_alias_table) if attached message_block as m then put_core_block (m, "content", True, l_alias_table) end if attached primary_tabs_block as m then put_core_block (m, "content", True, l_alias_table) end add_block (content_block, "content") if attached management_menu_block as l_block then put_core_block (l_block, "sidebar_first", True, l_alias_table) end if attached navigation_menu_block as l_block then put_core_block (l_block, "sidebar_first", True, l_alias_table) end if attached user_menu_block as l_block then put_core_block (l_block, "sidebar_second", True, l_alias_table) end end get_module_blocks -- Get blocks provided by modules. -- (from CMS_RESPONSE) do api.hooks.invoke_block (Current) end header_block: CMS_CONTENT_BLOCK -- (from CMS_RESPONSE) local s: STRING_8 l_hb: STRING_8 do create s.make_from_string (theme.menu_html (primary_menu, True, Void)) create l_hb.make_empty create Result.make ("header", Void, l_hb, Void) Result.set_weight (-4) Result.set_is_raw (True) end horizontal_primary_menu_html: STRING_8 -- (from CMS_RESPONSE) do create Result.make_empty Result.append ("<div id=%"menu-bar%">") Result.append (theme.menu_html (primary_menu, True, Void)) Result.append ("</div>") end horizontal_primary_tabs_html: STRING_8 -- (from CMS_RESPONSE) do create Result.make_empty Result.append ("<div id=%"tabs-bar%">") Result.append (theme.menu_html (primary_tabs, True, Void)) Result.append ("</div>") end management_menu_block: detachable CMS_MENU_BLOCK -- (from CMS_RESPONSE) do if attached management_menu as m and then not m.is_empty then create Result.make (m) end end message_block: detachable CMS_CONTENT_BLOCK -- (from CMS_RESPONSE) do if attached message as m and then not m.is_empty then create Result.make ("message", Void, "<div id=%"message%">" + m + "</div>", Void) Result.set_is_raw (True) Result.set_weight (-3) end end message_html: detachable STRING_8 -- (from CMS_RESPONSE) do if attached message as m and then not m.is_empty then Result := "<div id=%"message%">" + m + "</div>" end end navigation_menu_block: detachable CMS_MENU_BLOCK -- (from CMS_RESPONSE) do if attached navigation_menu as m and then not m.is_empty then create Result.make (m) end end primary_menu_block: detachable CMS_MENU_BLOCK -- (from CMS_RESPONSE) do if attached primary_menu as m and then not m.is_empty then create Result.make (m) end end primary_tabs_block: detachable CMS_MENU_BLOCK -- (from CMS_RESPONSE) do if attached primary_tabs as m and then not m.is_empty then create Result.make (m) Result.is_horizontal := True Result.set_is_raw (True) Result.set_weight (-2) Result.add_css_class ("tabs") end end put_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8; is_block_included_by_default: BOOLEAN) -- Add block b to associated region or a_default_region if provided -- and check optional associated condition. -- If no condition then use is_block_included_by_default to -- decide if block is included or not. -- (from CMS_RESPONSE) do if is_block_included (b.name, is_block_included_by_default) then add_block (b, a_default_region) end end remove_block (b: CMS_BLOCK) -- Remove block b from associated region. -- (from CMS_RESPONSE) local l_region: detachable like block_region l_found: BOOLEAN do across regions as reg_ic until l_found loop l_region := reg_ic.item l_found := l_region.blocks.has (b) if l_found then l_region.remove (b) end end blocks.remove (b.name) end top_header_block: CMS_CONTENT_BLOCK -- (from CMS_RESPONSE) local s: STRING_8 do create s.make_empty create Result.make ("page_top", Void, s, Void) Result.set_weight (-5) Result.set_is_raw (True) end user_menu_block: detachable CMS_MENU_BLOCK -- (from CMS_RESPONSE) do if attached user_menu as m and then not m.is_empty then create Result.make (m) end end feature -- Blocks initialization block_region_preference (a_block_id: READABLE_STRING_8; a_default_region: READABLE_STRING_8): READABLE_STRING_8 -- Region associated with a_block_id in configuration, if any. -- (from CMS_RESPONSE) do Result := setup.string_8_item_or_default ("blocks." + a_block_id + ".region", a_default_region) end initialize_block_region_settings -- (from CMS_RESPONSE) local l_table: like block_region_settings do debug ("refactor_fixme") fixme ("CHECK:Can we use the same structure as in theme.info?") fixme ("let the user choose ...") end create regions.make_caseless (5) create blocks.make (10) create l_table.make_caseless (10) l_table ["top"] := block_region_preference ("top", "top").as_string_8 l_table ["header"] := block_region_preference ("header", "header").as_string_8 l_table ["highlighted"] := block_region_preference ("highlighted", "highlighted").as_string_8 l_table ["help"] := block_region_preference ("help", "help").as_string_8 l_table ["content"] := block_region_preference ("content", "content").as_string_8 l_table ["footer"] := block_region_preference ("footer", "footer").as_string_8 l_table ["management"] := block_region_preference ("management", "sidebar_first").as_string_8 l_table ["navigation"] := block_region_preference ("navigation", "sidebar_first").as_string_8 l_table ["user"] := block_region_preference ("user", "sidebar_first").as_string_8 l_table ["bottom"] := block_region_preference ("bottom", "page_bottom").as_string_8 block_region_settings := l_table end feature -- Blocks regions block_region (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8): CMS_BLOCK_REGION -- Region associated with block b, or else a_default_region if provided. -- (from CMS_RESPONSE) local l_region_name: detachable READABLE_STRING_8 do l_region_name := block_region_settings.item (b.name) if l_region_name = Void then if attached setup.text_item ("blocks." + b.name + ".region") as l_setup_name then l_region_name := l_setup_name.as_string_8 block_region_settings.force (l_region_name.as_string_8, b.name) elseif a_default_region /= Void then l_region_name := a_default_region else l_region_name := b.name.as_lower end end if attached regions.item (l_region_name) as res then Result := res else create Result.make (l_region_name) regions.force (Result, l_region_name) end end block_region_settings: STRING_TABLE [STRING_8] -- (from CMS_RESPONSE) blocks: STRING_TABLE [CMS_BLOCK] -- Blocks indexed by their block id. -- (from CMS_RESPONSE) regions: STRING_TABLE [CMS_BLOCK_REGION] -- Layout regions, that contains blocks. -- (from CMS_RESPONSE) feature -- Cache managment clear_cache (a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]) -- Clear caches identified by a_cache_id_list, -- or clear all caches if a_cache_id_list is Void. -- (from CMS_RESPONSE) do if has_permissions (<<"clear blocks cache", "admin core caches">>) then clear_block_caches (a_cache_id_list) end end feature -- Change: metadata metadata: detachable CMS_RESPONSE_METADATA -- Optional metadata. -- For instance: -- type or og:type: Optional public type of the response page (related to http://ogp.me/) -- (from CMS_RESPONSE_I) feature -- Core based_path (p: STRING_8): STRING_8 -- Path p in the context of the base_url -- (from CMS_URL_UTILITIES) do if attached base_url as l_base_url then create Result.make_from_string (l_base_url) if p.is_empty then else if p [1] = '/' then Result.append (p.substring (2, p.count)) else Result.append (p) end end else Result := p end end feature -- Element Change set_status_code (a_status: INTEGER_32) -- Set status_code with a_status. -- (from CMS_RESPONSE_I) do status_code := a_status ensure -- from CMS_RESPONSE_I status_code_set: status_code = a_status end feature -- Element change add_keyword (a_keyword: READABLE_STRING_GENERAL) -- Add keyword keyword to the existing list of keywords. -- (from CMS_RESPONSE_I) local lst: like keywords do lst := keywords if lst = Void then create lst.make (1) keywords := lst end lst.force (a_keyword.to_string_32) end set_description (d: like description) -- (from CMS_RESPONSE) do description := d end set_main_content (s: like main_content) -- (from CMS_RESPONSE) do main_content := s end set_modification_date (dt: like modification_date) -- (from CMS_RESPONSE_I) do modification_date := dt if dt /= Void and publication_date = Void then publication_date := dt end end set_optional_content_type (a_content_type: detachable ANY) -- (from CMS_RESPONSE) do set_value (a_content_type, "optional_content_type") end set_page_title (t: like page_title) -- (from CMS_RESPONSE) do page_title := t end set_publication_date (dt: like publication_date) -- (from CMS_RESPONSE_I) do publication_date := dt if dt /= Void and modification_date = Void then modification_date := dt end end set_redirection (a_location: READABLE_STRING_8) -- Set redirection to a_location. -- (from CMS_RESPONSE_I) do redirection := a_location end set_redirection_delay (nb_secs: NATURAL_32) -- (from CMS_RESPONSE_I) do redirection_delay := nb_secs end set_title (t: like title) -- (from CMS_RESPONSE) do title := t set_page_title (t) end set_value (v: detachable ANY; k: READABLE_STRING_GENERAL) -- Set value v associated with name k. -- (from CMS_RESPONSE) do values.force (v, k) end unset_value (k: READABLE_STRING_GENERAL) -- Unset value associated with name k. -- (from CMS_RESPONSE) do values.remove (k) end feature -- Encoder Html_encoder: HTML_ENCODER -- Shared HTML encoder. -- (from SHARED_HTML_ENCODER) once create Result end Percent_encoder: WSF_PERCENT_ENCODER -- Shared Percent encoding engine. -- (from SHARED_WSF_PERCENT_ENCODER) once create Result end feature -- Encoders html_encoded (a_string: READABLE_STRING_GENERAL): STRING_8 -- a_string encoded for html output. -- (from CMS_ENCODERS) do Result := Html_encoder.general_encoded_string (a_string) end percent_encoded (a_string: READABLE_STRING_GENERAL): STRING_8 -- a_string encoded with percent encoding, mainly used for url. -- Was declared in CMS_ENCODERS as synonym of url_encoded. -- (from CMS_ENCODERS) do Result := Percent_encoder.percent_encoded_string (a_string) end safe_html_encoded (a_string: detachable READABLE_STRING_GENERAL): STRING_8 -- a_string encoded for html output or empty string. -- (from CMS_ENCODERS) do if a_string /= Void then Result := html_encoded (a_string) else Result := "" end end url_encoded (a_string: READABLE_STRING_GENERAL): STRING_8 -- a_string encoded with percent encoding, mainly used for url. -- Was declared in CMS_ENCODERS as synonym of percent_encoded. -- (from CMS_ENCODERS) do Result := Percent_encoder.percent_encoded_string (a_string) end utf_8_encoded (a_string: READABLE_STRING_GENERAL): STRING_8 -- a_string encoded using UTF-8. -- (from CMS_ENCODERS) local utf: UTF_CONVERTER do Result := utf.utf_32_string_to_utf_8_string_8 (a_string) end feature -- Execution execute -- (from CMS_RESPONSE) do begin process terminate end process -- Computed response message. do set_title ("Bad request".as_string_32) set_page_title ("Bad request".as_string_32) set_main_content ("<em>Bad request.</em>") end feature {NONE} -- Execution begin -- (from CMS_RESPONSE) do end on_terminated -- (from CMS_RESPONSE) do end frozen terminate -- (from CMS_RESPONSE) local cms_page: CMS_HTML_PAGE page: CMS_HTML_PAGE_RESPONSE h: HTTP_HEADER l_new_location: detachable READABLE_STRING_8 l_redirection_delay: like redirection_delay do if attached redirection as l_location then if l_location.has_substring ("://") then l_new_location := l_location else l_new_location := location_absolute_url (l_location, Void) end l_redirection_delay := redirection_delay if l_redirection_delay > 0 then add_additional_head_line ("<meta http-equiv=%"refresh%" content=%"" + l_redirection_delay.out + ";url=" + l_new_location + "%" />", True) end end if attached {READABLE_STRING_GENERAL} optional_content_type as l_type then create cms_page.make_typed (api.utf_8_encoded (l_type)) else create cms_page.make end prepare (cms_page) create page.make (theme.page_html (cms_page)) page.set_status_code (status_code) h := page.header h.put_content_length (page.html.count) h.put_current_date if l_new_location /= Void and l_redirection_delay = 0 then response.redirect_now (l_new_location) else h.put_header_object (header) response.send (page) end on_terminated end feature -- Generation common_prepare (page: CMS_HTML_PAGE) -- Common preparation for page page. -- (from CMS_RESPONSE) do debug ("refactor_fixme") fixme ("Fix generation common") end page.set_title (title) debug ("cms") if title = Void then page.set_title ({STRING_32}"CMS::" + request.path_info) end end across builtin_variables as ic loop page.register_variable (ic.item, ic.key) end page.register_variable (absolute_url ("", Void), "site_url") page.register_variable (base_path, "base_path") page.register_variable (absolute_url ("", Void), "host") page.register_variable (request.is_https, "is_https") if attached title as l_title then page.register_variable (l_title, "site_title") else page.register_variable (site_name, "site_title") end page.set_is_front (is_front) page.set_is_https (request.is_https) page.register_variable (is_administration_mode, "is_administration_mode") page.register_variable (api.theme_path, "theme_path") page.register_variable (horizontal_primary_menu_html, "primary_nav") page.register_variable (horizontal_primary_tabs_html, "primary_tabs") if attached page_title as l_page_title then page.register_variable (l_page_title, "page_title") end end custom_prepare (page: CMS_HTML_PAGE) -- Common preparation for page page that can be redefined by descendants. do set_status_code ({HTTP_STATUS_CODE}.bad_request) page.register_variable (absolute_url (request.percent_encoded_path_info.as_string_8, Void), "request") page.set_status_code (status_code) page.register_variable (status_code.out, "code") end get_local_link_active_status (a_lnk: CMS_LOCAL_LINK) -- Get a_lnk.is_active value according to request data. -- (from CMS_RESPONSE) local qs: STRING_8 l_is_active: BOOLEAN do create qs.make_from_string (request.percent_encoded_path_info) if qs.starts_with ("/") then qs.remove_head (1) end l_is_active := qs.same_string (a_lnk.location) if not l_is_active then if attached request.query_string as l_query_string and then not l_query_string.is_empty then qs.append_character ('?') qs.append (l_query_string) end l_is_active := qs.same_string (a_lnk.location) end a_lnk.set_is_active (l_is_active) a_lnk.set_is_forbidden (not has_permission_on_link (a_lnk)) end prepare (page: CMS_HTML_PAGE) -- (from CMS_RESPONSE) local lnk: CMS_LINK l_region: CMS_BLOCK_REGION l_menu_list_prepared: ARRAYED_LIST [CMS_LINK_COMPOSITE] l_empty_blocks: detachable ARRAYED_LIST [CMS_BLOCK] l_block_html: STRING_8 do create {CMS_LOCAL_LINK} lnk.make ("Home", "") lnk.set_weight (-10) add_to_primary_menu (lnk) api.hooks.invoke_menu_system_alter (menu_system, Current) if api.enabled_modules.count <= 1 then lnk := api.administration_link ("Install", "install") if lnk.location.same_string (location) then else add_to_primary_menu (lnk) end end create l_menu_list_prepared.make (0) get_blocks across regions as reg_ic loop l_region := reg_ic.item across l_region.blocks as ic loop if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then l_menu_list_prepared.force (l_menu_block.menu) prepare_links (l_menu_block.menu) if l_menu_block.menu.is_empty then if l_empty_blocks = Void then create l_empty_blocks.make (1) end l_empty_blocks.force (l_menu_block) end end end if l_empty_blocks /= Void then across l_empty_blocks as ic loop l_region.remove (ic.item) end l_empty_blocks := Void end end across menu_system as ic loop if not l_menu_list_prepared.has (ic.item) then l_menu_list_prepared.force (ic.item) prepare_links (ic.item) end end l_menu_list_prepared.wipe_out across menu_system as ic loop ic.item.sort end common_prepare (page) custom_prepare (page) api.hooks.invoke_response_alter (Current) api.hooks.invoke_value_table_alter (values, Current) page.register_variable (page, "page") across values as ic loop page.register_variable (ic.item, ic.key) end across regions as reg_ic loop l_region := reg_ic.item across l_region.blocks as ic loop if attached {CMS_SMARTY_TEMPLATE_BLOCK} ic.item as l_tpl_block then across page.variables as var_ic loop if not l_tpl_block.values.has (var_ic.key) then l_tpl_block.set_value (var_ic.item, var_ic.key) end end end l_block_html := theme.block_html (ic.item) if attached {CMS_CACHE_BLOCK} ic.item then do_nothing elseif attached block_cache (ic.item.name) as l_block_cache_info then l_block_cache_info.cache_block.set_cache_content (l_block_html) end page.add_to_region (l_block_html, reg_ic.item.name) end end if attached additional_page_head_lines as l_head_lines then across l_head_lines as hl loop page.head_lines.force (hl.item.as_string_8) end end end prepare_links (a_comp: CMS_LINK_COMPOSITE) -- Update the active status recursively on a_comp. -- (from CMS_RESPONSE) local to_remove: ARRAYED_LIST [CMS_LINK] ln: CMS_LINK l_comp_link: detachable CMS_LOCAL_LINK do if attached {CMS_LOCAL_LINK} a_comp as lnk then l_comp_link := lnk get_local_link_active_status (lnk) end if attached a_comp.items as l_items then create to_remove.make (0) across l_items as ic loop ln := ic.item if attached {CMS_LOCAL_LINK} ln as l_local then get_local_link_active_status (l_local) end if ln.is_forbidden then to_remove.force (ln) else if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then prepare_links (l_comp) end if l_comp_link /= Void then if ln.is_expanded or (not ln.is_expandable and ln.is_active) then l_comp_link.set_expanded (True) end end end end across to_remove as ic loop a_comp.remove (ic.item) end end if l_comp_link /= Void and then l_comp_link.is_active then l_comp_link.set_expanded (True) end end feature -- Head customization add_additional_head_line (s: READABLE_STRING_8; a_allow_duplication: BOOLEAN) -- (from CMS_RESPONSE) local lst: like additional_page_head_lines do lst := additional_page_head_lines if lst = Void then create {ARRAYED_LIST [like additional_page_head_lines.item]} lst.make (1) additional_page_head_lines := lst end if a_allow_duplication or else across lst as c all not c.item.same_string (s) end then lst.extend (s) end end add_javascript_content (a_script: STRING_8) -- (from CMS_RESPONSE) local s: STRING_8 do create s.make_from_string ("<script type=%"text/javascript%">%N") s.append (a_script) s.append ("%N</script>") add_additional_head_line (s, True) end add_javascript_url (a_src: STRING_8) -- (from CMS_RESPONSE) local s: STRING_8 do create s.make_from_string ("<script type=%"text/javascript%" src=%"") s.append (a_src) s.append ("%"></script>") add_additional_head_line (s, False) end add_style (a_href: STRING_8; a_media: detachable STRING_8) -- (from CMS_RESPONSE) local s: STRING_8 do create s.make_from_string ("<link rel=%"stylesheet%" href=%"") s.append (a_href) s.append ("%" type=%"text/css%"") if a_media /= Void then s.append (" media=%"" + a_media + "%"") end s.append ("/>") add_additional_head_line (s, False) end add_style_content (a_style_content: STRING_8) -- Add style content a_style_content in the head, using <style> tag. -- (from CMS_RESPONSE) local s: STRING_8 do create s.make_from_string ("<style>%N") s.append (a_style_content) s.append ("%N</style>") add_additional_head_line (s, True) end feature -- Helper conversions to and from string date_time_from_string (s: READABLE_STRING_GENERAL): detachable DATE_TIME -- Date time from string s, if valid. -- (from CMS_ENCODERS) local hd: HTTP_DATE do create hd.make_from_string (s) check not hd.has_error end if not hd.has_error then Result := hd.date_time end end date_time_to_string (dt: DATE_TIME): STRING_8 -- Date time dt converted to standard output (using RFC1123) -- (from CMS_ENCODERS) local hd: HTTP_DATE do create hd.make_from_date_time (dt) Result := hd.rfc1123_string end list_from_csv_string (a_csv: READABLE_STRING_32): LIST [READABLE_STRING_32] -- List of Comma-separated-value string items. -- (from CMS_ENCODERS) local i, j, n: INTEGER_32 s: STRING_32 do from i := 1 n := a_csv.count create s.make_empty create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (1) Result.force (s) until i > n loop inspect a_csv [i] when ',' then create s.make_empty Result.force (s) when '"' then j := a_csv.index_of ('"'.to_character_32, i + 1) if j > 0 then s.append (a_csv.substring (i + 1, j - 1)) i := j else s.extend (a_csv [i]) end else s.extend (a_csv [i]) end i := i + 1 end end list_to_csv_string (a_strings: ITERABLE [READABLE_STRING_GENERAL]): STRING_32 -- a_strings as comma separated value string. -- (from CMS_ENCODERS) local s: READABLE_STRING_GENERAL do create Result.make (0) across a_strings as ic loop s := ic.item if not Result.is_empty then Result.append_character (','.to_character_32) end if s.has (','.to_character_32) then Result.append_character ('"'.to_character_32) Result.append_string_general (s) Result.append_character ('"'.to_character_32) else Result.append_string_general (s) end end end feature -- Helpers / security vulnerabilities secure_text (a_text: STRING_GENERAL) -- Clean a_text from XSS vulnerabilities. -- (from CMS_ENCODERS) do (create {SECURITY_HTML_CONTENT_FILTER}).filter (a_text) end secured_html_content (a_html_content: READABLE_STRING_8): STRING_8 -- a_html_content cleaned from XSS vulnerabilities. -- (from CMS_ENCODERS) do create Result.make_from_string (a_html_content) secure_text (Result) end secured_url_content (a_url_content: READABLE_STRING_8): STRING_8 -- a_url_content cleaned from XSS vulnerabilities. -- (from CMS_ENCODERS) do create Result.make_from_string (a_url_content) secure_text (Result) end feature -- Helpers: URLs location_absolute_url (a_location: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- Absolute URL for a_location. -- (from CMS_RESPONSE_I) do Result := api.location_absolute_url (a_location, opts) end location_url (a_location: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- URL for a_location. -- (from CMS_RESPONSE_I) do Result := api.location_url (a_location, opts) end module_resource_url (a_module: CMS_MODULE; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- Url for resource a_path associated with module a_module. -- (from CMS_RESPONSE_I) require -- from CMS_RESPONSE_I a_valid_valid: a_path.is_empty or else a_path.starts_with ("/") do Result := url ("/module/" + a_module.name + a_path, opts) end user_url (u: CMS_USER): like url -- (from CMS_RESPONSE_I) require -- from CMS_RESPONSE_I u_with_id: u.has_id do Result := api.user_url (u) end feature -- Helpers: cms link administration_link (a_title: READABLE_STRING_GENERAL; a_relative_location: detachable READABLE_STRING_8): CMS_LOCAL_LINK -- (from CMS_RESPONSE_I) require -- from CMS_RESPONSE_I no_first_slash: a_relative_location = Void or else not a_relative_location.starts_with_general ("/") do Result := api.administration_link (a_title, a_relative_location) end local_link (a_title: READABLE_STRING_GENERAL; a_location: READABLE_STRING_8): CMS_LOCAL_LINK -- (from CMS_RESPONSE_I) do Result := api.local_link (a_title, a_location) end user_local_link (u: CMS_USER; a_opt_title: detachable READABLE_STRING_GENERAL): CMS_LOCAL_LINK -- (from CMS_RESPONSE_I) do Result := api.user_local_link (u, a_opt_title) end webapi_link (a_title: READABLE_STRING_GENERAL; a_relative_location: detachable READABLE_STRING_8): CMS_LOCAL_LINK -- (from CMS_RESPONSE_I) require -- from CMS_RESPONSE_I no_first_slash: a_relative_location = Void or else not a_relative_location.starts_with_general ("/") do Result := api.webapi_link (a_title, a_relative_location) end feature -- Helpers: html links user_display_name (u: CMS_USER): READABLE_STRING_32 -- Was declared in CMS_RESPONSE_I as synonym of user_profile_name. -- (from CMS_RESPONSE_I) do Result := api.user_display_name (u) end user_html_link (u: CMS_USER): STRING_8 -- (from CMS_RESPONSE) require -- from CMS_RESPONSE u_with_name: not u.name.is_whitespace do Result := api.user_html_link (u) end user_profile_name (u: CMS_USER): READABLE_STRING_32 -- Was declared in CMS_RESPONSE_I as synonym of user_display_name. -- (from CMS_RESPONSE_I) do Result := api.user_display_name (u) end feature -- Hooks hooks: CMS_HOOK_CORE_MANAGER obsolete "Use api.hooks [2017-05-31]" -- Manager handling hook subscriptions. -- (from CMS_RESPONSE_I) do Result := api.hooks end feature -- Internationalization (i18n) formatted_string (a_text: READABLE_STRING_GENERAL; args: TUPLE): STRING_32 -- Format a_text using arguments args. -- (from CMS_RESPONSE_I) do Result := api.formatted_string (a_text, args) end translation (a_text: READABLE_STRING_GENERAL; opts: detachable CMS_API_OPTIONS): STRING_32 -- Translated text a_text according to expected context (lang, ...) -- and adapt according to options eventually set by opts. -- (from CMS_RESPONSE_I) do Result := api.translation (a_text, opts) end feature -- Link append_link_to_html (a_text: detachable READABLE_STRING_GENERAL; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS; a_html: STRING_8) -- (from CMS_URL_UTILITIES) local l_html: BOOLEAN t: READABLE_STRING_GENERAL do l_html := True if opts /= Void then l_html := opts.boolean_item ("html", l_html) end a_html.append ("<a href=%"" + checked_url (url (a_path, opts)) + "%">") if a_text = Void then t := a_path else t := a_text end if l_html then a_html.append (html_encoded (t)) else a_html.append (checked_plain (t)) end a_html.append ("</a>") end append_link_with_raw_text_to_html (a_raw_text: detachable READABLE_STRING_8; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS; a_html: STRING_8) -- (from CMS_URL_UTILITIES) local l_html: BOOLEAN t: READABLE_STRING_8 do l_html := True if opts /= Void then l_html := opts.boolean_item ("html", l_html) end a_html.append ("<a href=%"" + checked_url (url (a_path, opts)) + "%">") if a_raw_text = Void then t := a_path else t := a_raw_text end a_html.append (t) a_html.append ("</a>") end link (a_text: detachable READABLE_STRING_GENERAL; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- HTML link with title a_text and href a_path. -- opts is used for additional settings. -- (from CMS_URL_UTILITIES) do create Result.make (32) append_link_to_html (a_text, a_path, opts, Result) end link_with_raw_text (a_raw_text: detachable READABLE_STRING_8; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- HTML link with title the html code a_raw_text and href a_path. -- opts is used for additional settings. -- (from CMS_URL_UTILITIES) do create Result.make (32) append_link_with_raw_text_to_html (a_raw_text, a_path, opts, Result) end feature -- Markers fixme (comment: READABLE_STRING_8) -- Mark code that has to be "fixed" with comment. -- (from REFACTORING_HELPER) require -- from REFACTORING_HELPER comment_not_void: comment /= Void do debug ("refactor_fixme") Io.Error.put_string ("FIXME: ") Io.Error.put_string (comment) Io.Error.put_new_line end ensure -- from REFACTORING_HELPER instance_free: class end to_implement (comment: READABLE_STRING_8) -- Mark code that has to be "implemented" with comment. -- (from REFACTORING_HELPER) require -- from REFACTORING_HELPER comment_not_void: comment /= Void do debug ("refactor_fixme") Io.Error.put_string ("TO_BE_IMPLEMENTED: ") Io.Error.put_string (comment) Io.Error.put_new_line end ensure -- from REFACTORING_HELPER instance_free: class end to_implement_assertion (comment: READABLE_STRING_8): BOOLEAN -- Mark assertion that has to be "implemented" with comment. -- (from REFACTORING_HELPER) require -- from REFACTORING_HELPER comment_not_void: comment /= Void do debug ("refactor_fixme") Io.Error.put_string ("ASSERTION_TO_BE_IMPLEMENTED: ") Io.Error.put_string (comment) Io.Error.put_new_line end Result := True ensure -- from REFACTORING_HELPER instance_free: class end feature -- Menu main_menu: CMS_MENU obsolete "Use `primary_menu' [2017-05-31]" -- (from CMS_RESPONSE) do Result := primary_menu end management_menu: CMS_MENU -- (from CMS_RESPONSE) do Result := menu_system.management_menu end menu_system: CMS_MENU_SYSTEM -- (from CMS_RESPONSE) navigation_menu: CMS_MENU -- (from CMS_RESPONSE) do Result := menu_system.navigation_menu end primary_menu: CMS_MENU -- (from CMS_RESPONSE) do Result := menu_system.primary_menu end primary_tabs: CMS_MENU -- (from CMS_RESPONSE) do Result := menu_system.primary_tabs end user_menu: CMS_MENU -- (from CMS_RESPONSE) do Result := menu_system.user_menu end feature -- Menu: change add_to_main_menu (lnk: CMS_LINK) obsolete "use add_to_primary_menu [2017-05-31]" -- (from CMS_RESPONSE) do add_to_primary_menu (lnk) end add_to_menu (lnk: CMS_LINK; m: CMS_MENU) -- (from CMS_RESPONSE) do m.extend (lnk) end add_to_primary_menu (lnk: CMS_LINK) -- (from CMS_RESPONSE) do add_to_menu (lnk, primary_menu) end add_to_primary_tabs (lnk: CMS_LINK) -- (from CMS_RESPONSE) do add_to_menu (lnk, primary_tabs) end feature -- Message add_debug_message (a_msg: READABLE_STRING_8) -- (from CMS_RESPONSE) do if api.is_debug then add_message (a_msg, "debug") end end add_error_message (a_msg: READABLE_STRING_8) -- (from CMS_RESPONSE) do add_message (a_msg, "error") end add_message (a_msg: READABLE_STRING_8; a_category: detachable READABLE_STRING_8) -- (from CMS_RESPONSE) local m: like message do m := message if m = Void then create m.make (a_msg.count + 9) message := m end if a_category /= Void then m.append ("<li class=%"" + a_category + "%">") else m.append ("<li>") end m.append (a_msg + "</li>") end add_notice_message (a_msg: READABLE_STRING_8) -- (from CMS_RESPONSE) do add_message (a_msg, "notice") end add_success_message (a_msg: READABLE_STRING_8) -- (from CMS_RESPONSE) do add_message (a_msg, "success") end add_warning_message (a_msg: READABLE_STRING_8) -- (from CMS_RESPONSE) do add_message (a_msg, "warning") end message: detachable STRING_8 -- (from CMS_RESPONSE) report_form_errors (fd: WSF_FORM_DATA) -- (from CMS_RESPONSE) require -- from CMS_RESPONSE has_error: not fd.is_valid do if attached fd.errors as errs then across errs as err loop if attached err.item as e then if attached e.field as l_field then if attached e.message as e_msg then add_error_message (e_msg) else add_error_message ("Field [" + l_field.name + "] is invalid.") end elseif attached e.message as e_msg then add_error_message (e_msg) end end end end end feature -- Output Io: STD_FILES -- Handle to standard file setup -- (from ANY) once create Result Result.set_output_default ensure -- from ANY instance_free: class io_not_void: Result /= Void end out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) do Result := tagged_out ensure -- from ANY out_not_void: Result /= Void end print (o: detachable ANY) -- Write terse external representation of o -- on standard output. -- (from ANY) do if o /= Void then Io.put_string (o.out) end ensure -- from ANY instance_free: class end frozen tagged_out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) external "built_in" ensure -- from ANY tagged_out_not_void: Result /= Void end feature -- Permission has_permission (a_permission: READABLE_STRING_GENERAL): BOOLEAN -- Does current user has permission a_permission ? -- (from CMS_RESPONSE_I) do Result := user_has_permission (user, a_permission) end has_permission_on_link (a_link: CMS_LINK): BOOLEAN -- Does current user has permission to access link a_link? -- (from CMS_RESPONSE_I) do Result := True if attached {CMS_LOCAL_LINK} a_link as lnk and then attached lnk.permission_arguments as l_perms then Result := has_permissions (l_perms) end end has_permissions (a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN -- Does current user has any of the permissions a_permission_list ? -- (from CMS_RESPONSE_I) do Result := user_has_permissions (user, a_permission_list) end user_has_permission (a_user: detachable CMS_USER; a_permission: READABLE_STRING_GENERAL): BOOLEAN -- Does a_user has permission a_permission ? -- (from CMS_RESPONSE_I) do Result := api.user_has_permission (a_user, a_permission) end user_has_permissions (a_user: detachable CMS_USER; a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN -- Does a_user has any of the permissions a_permission_list ? -- (from CMS_RESPONSE_I) do Result := api.user_has_permissions (a_user, a_permission_list) end feature -- Platform Operating_environment: OPERATING_ENVIRONMENT -- Objects available from the operating system -- (from ANY) once create Result ensure -- from ANY instance_free: class operating_environment_not_void: Result /= Void end feature -- Response builtin variables builtin_variables: STRING_TABLE [detachable ANY] -- builtin variables value indexed by name. -- (from CMS_RESPONSE) do Result := api.builtin_variables Result ["site_url"] := site_url Result ["host"] := site_url Result ["is_https"] := request.is_https end feature {NONE} -- Retrieval frozen internal_correct_mismatch -- Called from runtime to perform a proper dynamic dispatch on correct_mismatch -- from MISMATCH_CORRECTOR. -- (from ANY) local l_msg: STRING_8 l_exc: EXCEPTIONS do if attached {MISMATCH_CORRECTOR} Current as l_corrector then l_corrector.correct_mismatch else create l_msg.make_from_string ("Mismatch: ") create l_exc l_msg.append (generating_type.name) l_exc.raise_retrieval_exception (l_msg) end end feature -- Settings is_administration_mode: BOOLEAN -- Is administration mode? -- (from CMS_RESPONSE_I) do Result := api.is_administration_mode end is_site_mode: BOOLEAN -- Is site mode? -- (from CMS_RESPONSE_I) do Result := api.is_site_mode end is_webapi_mode: BOOLEAN -- Is Web API mode? -- (from CMS_RESPONSE_I) do Result := api.is_webapi_mode end feature -- Specific values optional_content_type: detachable ANY -- (from CMS_RESPONSE) do Result := values.item ("optional_content_type") end feature -- Theme get_theme -- (from CMS_RESPONSE) local l_info: CMS_THEME_INFORMATION do if attached setup.theme_information_location as fn then create l_info.make (fn) else create l_info.make_default end if l_info.engine.is_case_insensitive_equal_general ("smarty") then create {SMARTY_CMS_THEME} theme.make (api, l_info, site_url) else create {MISSING_CMS_THEME} theme.make (api, l_info, site_url) status_code := {HTTP_STATUS_CODE}.service_unavailable to_implement ("Check how to add the Retry-after, http://tools.ietf.org/html/rfc7231#section-6.6.4 and http://tools.ietf.org/html/rfc7231#section-7.1.3") end end theme: CMS_THEME -- Current theme -- (from CMS_RESPONSE) feature -- Theme helpers wsf_theme: WSF_THEME -- WSF Theme from CMS theme for Current response. -- (from CMS_RESPONSE) local t: like internal_wsf_theme do t := internal_wsf_theme if t = Void then create {CMS_TO_WSF_THEME} t.make (Current, theme) internal_wsf_theme := t end Result := t end feature {NONE} -- Theme helpers internal_wsf_theme: detachable WSF_THEME -- Once per object for wsf_theme. -- (from CMS_RESPONSE) feature -- URL utilities base_path: IMMUTABLE_STRING_8 -- Base path, default to "/". -- Always ends with '/' -- Could be /project/demo/ -- (from CMS_RESPONSE_I) base_url: detachable IMMUTABLE_STRING_8 -- Base url if any. -- (from CMS_RESPONSE_I) is_front: BOOLEAN -- Is current response related to "front" page? -- (from CMS_RESPONSE_I) local l_path_info: READABLE_STRING_8 do l_path_info := request.percent_encoded_path_info if attached setup.front_page_path as l_front_page_path then Result := l_front_page_path.same_string (l_path_info) else if base_path.same_string (l_path_info) then Result := True else Result := l_path_info.is_empty or else l_path_info.same_string ("/") end end end site_url: IMMUTABLE_STRING_8 -- Absolute site url. -- Always ends with '/' -- (from CMS_RESPONSE_I) feature -- Url absolute_url (a_path: STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- (from CMS_URL_UTILITIES) local l_opts: detachable CMS_API_OPTIONS do l_opts := opts if l_opts = Void then create l_opts.make (1) end l_opts.force (True, "absolute") Result := url (a_path, l_opts) end checked_plain (a_text: READABLE_STRING_GENERAL): STRING_8 -- (from CMS_URL_UTILITIES) do Result := html_encoded (a_text) end checked_url (a_url: READABLE_STRING_8): READABLE_STRING_8 -- (from CMS_URL_UTILITIES) do Result := a_url end url (a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 -- URL for path a_path and optional parameters from opts. -- (from CMS_URL_UTILITIES) local q, f: detachable STRING_8 l_abs: BOOLEAN do l_abs := False if opts /= Void then l_abs := opts.boolean_item ("absolute", l_abs) if attached opts.item ("query") as l_query then if attached {READABLE_STRING_8} l_query as s_value then q := s_value.as_string_8 elseif attached {ITERABLE [TUPLE [key: READABLE_STRING_GENERAL; value: READABLE_STRING_GENERAL]]} l_query as lst then create q.make_empty across lst as c loop if q.is_empty then else q.append_character ('&') end q.append (url_encoded (c.item.key)) q.append_character ('=') q.append (url_encoded (c.item.value)) end end end if attached opts.string_item ("fragment") as s_frag then f := s_frag.as_string_8 end end if l_abs then if a_path.substring_index ("://", 1) = 0 then create Result.make_from_string (site_url) if a_path.is_empty then elseif Result.ends_with ("/") then if a_path [1] = '/' then Result.append_string (a_path.substring (2, a_path.count)) else Result.append_string (a_path) end else if a_path [1] = '/' then Result.append_string (a_path) else Result.append_character ('/') Result.append_string (a_path) end end else Result := a_path.as_string_8 end else Result := based_path (a_path.as_string_8) end if q /= Void then Result.append ("?" + q) end if f /= Void then Result.append ("#" + f) end end feature -- User access is_authenticated: BOOLEAN -- Is user authenticated? -- (from CMS_RESPONSE_I) do Result := user /= Void end set_user (u: CMS_USER) -- Set active user to u. -- (from CMS_RESPONSE_I) require -- from CMS_RESPONSE_I attached_u: u /= Void do api.set_user (u) end unset_user -- Unset active user. -- (from CMS_RESPONSE_I) do api.unset_user end user: detachable CMS_USER -- Active user if authenticated. -- (from CMS_RESPONSE_I) do Result := api.user end invariant -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) note copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end -- class BAD_REQUEST_ERROR_CMS_RESPONSE
Generated by ISE EiffelStudio