downloads category and sub-catgory
Posted
#1311
(In Topic #318)
The Category (C) tree is somthing like this
C1 http://www.tctfhlc-hk.net/index.php?page=downloads&type=browse&id=untitled-6
C11
C12
C2 http://www.tctfhlc-hk.net/index.php?page=downloads&type=browse&id=untitled-4
C21
C22
C3 http://www.tctfhlc-hk.net/index.php?page=downloads&type=browse&id=untitled
C31
C32
Posted
I'm taking a look at this now.
It might help if you can get me a login to your site so I can see more closely, or a screenshot at least.
However I think the URL issue is due to Chinese characters not being good for URLs. I'm giving that some thought now.
Posted
I've added transliteration:
Code (php)
- <?php /*
- Composr
- Copyright (c) ocProducts, 2004-2016
- See text/EN/licence.txt for full licencing information.
- NOTE TO PROGRAMMERS:
- Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
- **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****
- */
- /**
- * @license http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
- * @copyright ocProducts Ltd
- * @package core
- */
- /**
- * Change whatever global context that is required in order to run from a different context.
- *
- * @sets_input_state
- *
- * @param array $new_get The URL component map (must contain 'page').
- * @param ID_TEXT $new_zone The zone.
- * @param ID_TEXT $new_current_script The running script.
- * @param boolean $erase_keep_also Whether to get rid of keep_ variables in current URL.
- * @return array A list of parameters that would be required to be passed back to reset the state.
- */
- function set_execution_context($new_get, $new_zone = '_SEARCH', $new_current_script = 'index', $erase_keep_also = false)
- {
- $old_get = $_GET;
- $old_zone = get_zone_name();
- $old_current_script = current_script();
- foreach ($_GET as $key => $val) {
- }
- }
- }
- foreach ($new_get as $key => $val) {
- }
- global $RELATIVE_PATH, $ZONE, $SELF_URL_CACHED;
- $RELATIVE_PATH = ($new_zone == '_SEARCH') ? get_page_zone(get_page_name()) : $new_zone;
- if ($new_zone != $old_zone) {
- $ZONE = null; // So zone details will have to reload
- }
- $SELF_URL_CACHED = null;
- global $PAGE_NAME_CACHE;
- $PAGE_NAME_CACHE = null;
- global $RUNNING_SCRIPT_CACHE, $WHAT_IS_RUNNING_CACHE;
- $WHAT_IS_RUNNING_CACHE = $new_current_script;
- }
- /**
- * Map spaces to %20 and put http:// in front of URLs starting www.
- *
- * @param URLPATH $url The URL to fix
- * @return URLPATH The fixed result
- */
- function remove_url_mistakes($url)
- {
- $url = 'http://' . $url;
- }
- return $url;
- }
- /**
- * Get hidden fields for a form representing 'keep_x'. If we are having a GET form instead of a POST form, we need to do this. This function also encodes the page name, as we'll always want that.
- *
- * @param ID_TEXT $page The page for the form to go to (blank: don't attach)
- * @param boolean $keep_all Whether to keep all elements of the current URL represented in this form (rather than just the keep_ fields, and page)
- * @param ?array $exclude A list of parameters to exclude (null: don't exclude any)
- * @return Tempcode The builtup hidden form fields
- *
- * @ignore
- */
- function _build_keep_form_fields($page = '', $keep_all = false, $exclude = null)
- {
- }
- if ($page == '_SELF') {
- $page = get_page_name();
- }
- $out = new Tempcode();
- foreach ($_GET as $key => $val) {
- foreach ($val as $_key => $_val) { // We'll only support one level deep. Also no keep parameter array support.
- }
- if ($process_for_key) {
- $out->attach(form_input_hidden($key . '[' . $_key . ']', $_val));
- }
- }
- } else {
- continue;
- }
- }
- }
- if ($process_for_key) {
- $out->attach(form_input_hidden($key, $val));
- }
- }
- }
- }
- if ($page != '') {
- $out->attach(form_input_hidden('page', $page));
- }
- return $out;
- }
- /**
- * Recurser helper function for _build_keep_post_fields.
- *
- * @param ID_TEXT $key Key name to put value under
- * @param mixed $value Value (string or array)
- * @return string The builtup hidden form fields
- *
- * @ignore
- */
- function _fixed_post_parser($key, $value)
- {
- $out = '';
- }
- foreach ($value as $k => $v) {
- $out .= _fixed_post_parser($key . '[' . $k . ']', $v);
- } else {
- }
- }
- } else {
- }
- }
- return $out;
- }
- /**
- * Relay all POST variables for this URL, to the URL embedded in the form.
- *
- * @param ?array $exclude A list of parameters to exclude (null: exclude none)
- * @param boolean $force_everything Force field labels and descriptions to copy through even when there are huge numbers of parameters
- * @return Tempcode The builtup hidden form fields
- *
- * @ignore
- */
- function _build_keep_post_fields($exclude = null, $force_everything = false)
- {
- $out = '';
- foreach ($_POST as $key => $val) {
- }
- continue;
- }
- continue;
- }
- continue;
- }
- continue;
- }
- }
- $out .= _fixed_post_parser($key, $val);
- }
- return make_string_tempcode($out);
- }
- /**
- * Takes a URL, and converts it into a file system storable filename. This is used to cache URL contents to the servers filesystem.
- *
- * @param URLPATH $url_full The URL to convert to an encoded filename
- * @return string A usable filename based on the URL
- *
- * @ignore
- */
- function _url_to_filename($url_full)
- {
- $new_name = $url_full;
- foreach ($bad_chars as $bad_char) {
- if ($bad_char == ':') {
- $good_char = ';'; // So page_links save nice
- }
- }
- if (strlen($new_name) <= 200/*technically 256 but something may get put on the start, so be cautious*/) {
- return $new_name;
- }
- // Non correspondance, but at least we have something
- }
- }
- /**
- * Take a URL and base-URL, and fully qualify the URL according to it.
- *
- * @param URLPATH $url The URL to fully qualified
- * @param URLPATH $url_base The base-URL
- * @return URLPATH Fully qualified URL
- *
- * @ignore
- */
- function _qualify_url($url, $url_base)
- {
- require_code('obfuscate');
- $mto = mailto_obfuscated();
- if (url_is_local($url)) {
- if ($url[0] == '/') {
- if ($parsed === false) {
- return '';
- }
- $parsed['scheme'] = 'http';
- }
- $parsed['host'] = 'localhost';
- }
- $url = $parsed['scheme'] . ':' . $url;
- } else {
- $url = $parsed['scheme'] . '://' . $parsed['host'] . (array_key_exists('port', $parsed) ? (':' . $parsed['port']) : '') . $url;
- }
- } else {
- $url = $url_base . '/' . $url;
- }
- }
- }
- while ($pos !== false) {
- if ($pos_2 === false) {
- break;
- }
- }
- return $url;
- }
- /**
- * Convert a URL to a local file path.
- *
- * @param URLPATH $url The value to convert
- * @return ?PATH File path (null: is not local)
- * @ignore
- */
- function _convert_url_to_path($url)
- {
- return null;
- }
- } else {
- }
- $_file_path_stub = get_custom_file_base() . '/' . $file_path_stub;
- $_file_path_stub = get_file_base() . '/' . $file_path_stub;
- }
- } else {
- $_file_path_stub = get_file_base() . '/' . $file_path_stub;
- }
- return null;
- }
- return $_file_path_stub;
- }
- return null;
- }
- /**
- * Sometimes users don't enter full URLs but do intend for them to be absolute. This code tries to see what relative URLs are actually absolute ones, via an algorithm. It then fixes the URL.
- *
- * @param URLPATH $in The URL to fix
- * @return URLPATH The fixed URL (or original one if no fix was needed)
- * @ignore
- */
- function _fixup_protocolless_urls($in)
- {
- if ($in == '') {
- return $in;
- }
- $in = remove_url_mistakes($in); // Chain in some other stuff
- return $in; // Absolute (e.g. http:// or mailto:)
- }
- return $in;
- }
- return $in;
- }
- return $in;
- }
- // Rule 1: // If we have a dot somewhere before a slash, then this dot is likely part of a domain name (not a file extension)- thus we have an absolute URL.
- return 'http://' . $in; // Fix it
- }
- // Rule 2: // If we have no slashes and we don't recognise a file type then they've probably just entered a domain name- thus we have an absolute URL.
- if ((preg_match('#^[^/]+$#', $in) != 0) && (preg_match('#\.(php|htm|asp|jsp|swf|gif|png|jpg|jpe|txt|pdf|odt|ods|odp|doc|mdb|xls|ppt|xml|rss|ppt|svg|wrl|vrml|gif|psd|rtf|bmp|avi|mpg|mpe|webm|mp4|mov|wmv|ram|rm|asf|ra|wma|wav|mp3|ogg|torrent|csv|ttf|tar|gz|rar|bz2)#', $in) == 0)) {
- return 'http://' . $in . '/'; // Fix it
- }
- return $in; // Relative
- }
- /**
- * Convert a local URL to a page-link.
- *
- * @param URLPATH $url The URL to convert. Note it may not be a URL Scheme, and it must be based on the local base URL (else failure WILL occur).
- * @param boolean $abs_only Whether to only convert absolute URLs. Turn this on if you're not sure what you're passing is a URL not and you want to be extra safe.
- * @param boolean $perfect_only Whether to only allow perfect conversions.
- * @return string The page-link (blank: could not convert).
- *
- * @ignore
- */
- function _url_to_page_link($url, $abs_only = false, $perfect_only = true)
- {
- return '';
- }
- // Try and strip any variants of the base URL from our $url variable, to make it relative
- $non_www_base_url = str_replace('https://www.', 'https://', str_replace('http://www.', 'http://', get_base_url()));
- $www_base_url = str_replace('https://', 'https://www.', str_replace('http://', 'http://www.', get_base_url()));
- return '';
- }
- return '';
- }
- $url = '/' . $url;
- }
- // Parse the URL
- if ($parsed_url === false) {
- require_code('site');
- attach_message(do_lang_tempcode('HTTP_DOWNLOAD_BAD_URL', escape_html($url)), 'warn');
- return '';
- }
- // Work out the zone
- $zone = '';
- $slash_pos = false;
- }
- $attributes['page'] = ''; // hopefully will get overwritten with a real one
- // Convert URL Scheme path info into extra implied attribute data
- require_code('url_remappings');
- $does_match = false;
- $mappings = get_remappings($url_scheme);
- foreach ($mappings as $mapping) { // e.g. array(array('page' => 'wiki', 'id' => null), 'pg/s/ID', true),
- continue;
- }
- $match_string_pattern = preg_replace('#[A-Z]+#', '[^\&\?]+', preg_quote($match_string)); // Turn match string into a regexp
- if ($does_match) {
- if ($url_scheme == 'HTM') {
- continue;
- }
- } else {
- continue;
- }
- $_match_string = $match_string;
- $_path = $parsed_url['path'];
- }
- foreach ($bits_pattern as $i => $bit) {
- if ((strtoupper($bit) == $bit) && (array_key_exists(strtolower($bit), $params)) && (is_null($params[strtolower($bit)]))) {
- }
- }
- foreach ($attributes as &$attribute) {
- }
- break 2;
- }
- }
- }
- if (!$does_match) {
- return ''; // No match was found
- }
- // Parse query string component into the waiting (and partly-filled-already) attribute data array
- foreach ($bits as $bit) {
- $attributes[$_bit[0]] = cms_url_decode_post_process($_bit[1]);
- if ($perfect_only) {
- return ''; // Could not convert this URL to a page-link, because it contains a colon
- }
- }
- }
- }
- }
- require_code('site');
- if (_request_page($attributes['page'], $zone) === false) {
- return '';
- }
- $page = fix_page_name_dashing($zone, $attributes['page']);
- // Put it together
- $page_link = $zone . ':' . $page;
- $page_link .= ':' . $attributes['type'];
- $page_link .= ':';
- }
- $page_link .= ':' . $attributes['id'];
- }
- foreach ($attributes as $key => $val) {
- }
- if (($key != 'page') && ($key != 'type') && ($key != 'id')) {
- $page_link .= ':' . $key . '=' . cms_url_encode($val);
- }
- }
- // Hash bit?
- $page_link .= '#' . $parsed_url['fragment'];
- }
- return $page_link;
- }
- /**
- * Convert a local page file path to a written page-link.
- *
- * @param string $page The path.
- * @return string The page-link (blank: could not convert).
- *
- * @ignore
- */
- function _page_path_to_page_link($page)
- {
- }
- if (preg_match('#^([^/]*)/?pages/([^/]+)/(\w\w/)?([^/\.]+)\.(php|txt|htm)$#', $page, $matches) == 1) {
- $page2 = $matches[1] . ':' . $matches[4];
- if (($matches[2] == 'comcode') || ($matches[2] == 'comcode_custom')) {
- $page2 .= ' (' . $matches[1] . ')';
- $page2 .= ' (' . $matches[1] . ')';
- }
- }
- }
- } else {
- $page2 = '';
- }
- return $page2;
- }
- /**
- * Called from 'find_id_moniker'. We tried to lookup a moniker, found a hook, but found no stored moniker. So we'll try and autogenerate one.
- *
- * @param array $ob_info The hooks info profile.
- * @param array $url_parts The URL component map (must contain 'page', 'type', and 'id' if this function is to do anything).
- * @param ID_TEXT $zone The URL zone name (only used for Comcode Page URL monikers).
- * @return ?string The moniker ID (null: error generating it somehow, can not do it)
- */
- function autogenerate_new_url_moniker($ob_info, $url_parts, $zone)
- {
- $effective_id = ($url_parts['type'] == '') ? $url_parts['page'] : $url_parts['id'];
- $bak = $GLOBALS['NO_DB_SCOPE_CHECK'];
- $GLOBALS['NO_DB_SCOPE_CHECK'] = true;
- require_code('content');
- append_content_select_for_id($select, $ob_info);
- $select[] = $ob_info['title_field'];
- }
- if ($ob_info['parent_category_field'] !== null) {
- $select[] = $ob_info['parent_category_field'];
- }
- $db = ((substr($ob_info['table'], 0, 2) != 'f_') || (get_forum_type() == 'none')) ? $GLOBALS['SITE_DB'] : $GLOBALS['FORUM_DB'];
- $where = get_content_where_for_str_id($effective_id, $ob_info);
- $where['the_zone'] = $zone;
- }
- $_moniker_src = $db->query_select($ob_info['table'], $select, $where); // NB: For Comcode pages visited, this won't return anything -- it will become more performant when the page actually loads, so the moniker won't need redoing each time
- $GLOBALS['NO_DB_SCOPE_CHECK'] = $bak;
- return null; // been deleted?
- }
- if ($ob_info['id_field_numeric']) {
- } else {
- if ($ob_info['title_field_dereference']) {
- $moniker_src = get_translated_text($_moniker_src[0][$ob_info['title_field']]);
- } else {
- $moniker_src = $_moniker_src[0][$ob_info['title_field']];
- }
- }
- } else {
- $moniker_src = $effective_id;
- }
- if ($moniker_src == '') {
- $moniker_src = 'untitled';
- }
- return suggest_new_idmoniker_for($url_parts['page'], isset($url_parts['type']) ? $url_parts['type'] : '', $url_parts['id'], $zone, $moniker_src, true);
- }
- /**
- * Called when content is added, or edited/moved, based upon a new form field that specifies what moniker to use.
- *
- * @param ID_TEXT $page Page name.
- * @param ID_TEXT $type Screen type code.
- * @param ID_TEXT $id Resource ID.
- * @param ID_TEXT $zone The URL zone name (only used for Comcode Page URL monikers).
- * @param string $moniker_src String from which a moniker will be chosen (may not be blank).
- * @param boolean $is_new Whether we are sure this is a new moniker (makes things more efficient, saves a query).
- * @param ?string $moniker Actual moniker to use (null: generate from $moniker_src). Usually this is left null.
- * @return string The chosen moniker.
- */
- function suggest_new_idmoniker_for($page, $type, $id, $zone, $moniker_src, $is_new = false, $moniker = null)
- {
- if (get_option('url_monikers_enabled') == '0') {
- return '';
- }
- $ref = $zone . ':' . $page . ':' . $type . ':' . $id;
- if ($moniker !== null) {
- $force_called[$ref] = $moniker;
- } else {
- return $force_called[$ref];
- }
- }
- if (!$is_new) {
- $manually_chosen = $GLOBALS['SITE_DB']->query_select_value_if_there('url_id_monikers', 'm_moniker', array('m_manually_chosen' => 1, 'm_resource_page' => $page, 'm_resource_type' => $type, 'm_resource_id' => $id));
- if ($manually_chosen !== null) {
- return $manually_chosen;
- }
- // Deprecate old one if already exists
- $old = $GLOBALS['SITE_DB']->query_select_value_if_there('url_id_monikers', 'm_moniker', array('m_resource_page' => $page, 'm_resource_type' => $type, 'm_resource_id' => $id, 'm_deprecated' => 0), 'ORDER BY id DESC');
- // See if it is same as current
- if ($moniker === null) {
- $scope = _give_moniker_scope($page, $type, $id, $zone, '');
- $moniker = $scope . _choose_moniker($page, $type, $id, $moniker_src, $old, $scope);
- }
- if ($moniker == $old) {
- return $old; // hmm, ok it can stay actually
- }
- // It's not. Although, the later call to _choose_moniker will allow us to use the same stem as the current active one, or even re-activate an old deprecated one, so long as it is on this same m_resource_page/m_resource_page/m_resource_id.
- // Deprecate
- // Deprecate anything underneath
- global $CONTENT_OBS;
- load_moniker_hooks();
- $looking_for = '_SEARCH:' . $page . ':' . $type . ':_WILD';
- $category_page = $parts[1];
- $GLOBALS['SITE_DB']->query('UPDATE ' . get_table_prefix() . 'url_id_monikers SET m_deprecated=1 WHERE ' . db_string_equal_to('m_resource_page', $category_page) . ' AND m_moniker LIKE \'' . db_encode_like($old . '/%') . '\''); // Deprecate
- }
- }
- }
- if ($moniker === null) {
- $moniker = $id;
- } else {
- $scope = _give_moniker_scope($page, $type, $id, $zone, '');
- $moniker = $scope . _choose_moniker($page, $type, $id, $moniker_src, null, $scope);
- if (($page == 'news') && ($type == 'view') && (get_value('google_news_urls') === '1')) {
- }
- }
- }
- // Insert
- $GLOBALS['SITE_DB']->query_delete('url_id_monikers', array( // It's possible we're re-activating a deprecated one
- 'm_resource_page' => $page,
- 'm_resource_type' => $type,
- 'm_resource_id' => $id,
- 'm_moniker' => $moniker,
- ), '', 1);
- 'm_resource_page' => $page,
- 'm_resource_type' => $type,
- 'm_resource_id' => $id,
- 'm_moniker' => $moniker,
- 'm_deprecated' => 0,
- 'm_manually_chosen' => 0,
- ));
- global $LOADED_MONIKERS_CACHE;
- return $moniker;
- }
- /**
- * Delete an old moniker, and place a new one.
- *
- * @param ID_TEXT $page Page name.
- * @param ID_TEXT $type Screen type code.
- * @param ID_TEXT $id Resource ID.
- * @param string $moniker_src String from which a moniker will be chosen (may not be blank).
- * @param ?string $no_exists_check_for Whether to skip the exists check for a certain moniker (will be used to pass "existing self" for edits) (null: nothing existing to check against).
- * @param ?string $scope_context Where the moniker will be placed in the moniker URL tree (null: unknown, so make so no duplicates anywhere).
- * @return string Chosen moniker.
- *
- * @ignore
- */
- function _choose_moniker($page, $type, $id, $moniker_src, $no_exists_check_for = null, $scope_context = null)
- {
- $moniker = _generate_moniker($moniker_src);
- // Check it does not already exist
- $moniker_origin = $moniker;
- $next_num = 1;
- $moniker .= '-1';
- }
- $test = mixed();
- do {
- return $moniker; // This one is okay, we know it is safe
- }
- }
- $dupe_sql = 'SELECT m_resource_id FROM ' . get_table_prefix() . 'url_id_monikers WHERE ';
- $dupe_sql .= db_string_equal_to('m_resource_page', $page);
- if ($type == '') {
- $dupe_sql .= ' AND ' . db_string_equal_to('m_resource_id', $id);
- } else {
- $dupe_sql .= ' AND ' . db_string_equal_to('m_resource_type', $type) . ' AND ' . db_string_not_equal_to('m_resource_id', $id);
- }
- $dupe_sql .= ' AND (';
- $dupe_sql .= db_string_equal_to('m_moniker', $scope_context . $moniker);
- } else {
- // Use reversing for better indexing performance
- }
- $dupe_sql .= ')';
- $test = $GLOBALS['SITE_DB']->query_value_if_there($dupe_sql, false, true);
- $next_num++;
- }
- return $moniker;
- }
- /**
- * Generate a moniker from an arbitrary raw string. Does not perform uniqueness checks.
- *
- * @param string $moniker_src Raw string.
- * @return ID_TEXT Moniker.
- *
- * @ignore
- */
- function _generate_moniker($moniker_src)
- {
- $moniker = strip_comcode($moniker_src);
- // Transliteration first
- if (get_charset() == 'utf-8') {
- $moniker = transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $moniker);
- } else {
- // German has inbuilt transliteration
- }
- }
- // Then strip down / substitute to force it to be URL-ready
- if (($pos === false) || ($pos < 12)) {
- $pos = $max_moniker_length;
- }
- }
- // A bit lame, but maybe we'll have to
- if ($moniker == '') {
- $moniker = 'untitled';
- }
- return $moniker;
- }
- /**
- * Take a moniker and it's page-link details, and make a full path from it.
- *
- * @param ID_TEXT $page Page name.
- * @param ID_TEXT $type Screen type code.
- * @param ID_TEXT $id Resource ID.
- * @param ID_TEXT $zone The URL zone name (only used for Comcode Page URL monikers).
- * @param string $main Pathless moniker.
- * @return string The fully qualified moniker.
- *
- * @ignore
- */
- function _give_moniker_scope($page, $type, $id, $zone, $main)
- {
- // Does this URL arrangement support monikers?
- global $CONTENT_OBS;
- load_moniker_hooks();
- $found = false;
- if ($type == '') {
- $looking_for = '_WILD:_WILD';
- } else {
- $looking_for = '_SEARCH:' . $page . ':' . $type . ':_WILD';
- }
- $moniker = $main;
- return $moniker;
- }
- if ($ob_info['parent_category_field'] == 'the_zone') {
- $ob_info['parent_category_field'] = 'p_parent_page'; // Special exception for Comcode page monikers
- }
- // Lookup DB record so we can discern the category
- $bak = $GLOBALS['NO_DB_SCOPE_CHECK'];
- $GLOBALS['NO_DB_SCOPE_CHECK'] = true;
- require_code('content');
- append_content_select_for_id($select, $ob_info);
- $select[] = $ob_info['title_field'];
- }
- $select[] = $ob_info['parent_category_field'];
- }
- $where = get_content_where_for_str_id(($type == '') ? $page : $id, $ob_info);
- $where['the_zone'] = $zone;
- }
- $_moniker_src = $GLOBALS['SITE_DB']->query_select($ob_info['table'], $select, $where);
- $GLOBALS['NO_DB_SCOPE_CHECK'] = $bak;
- return $moniker; // been deleted?
- }
- // Discern the path (will effectively recurse, due to find_id_moniker call)
- $parent = $_moniker_src[0][$ob_info['parent_category_field']];
- }
- $tree = null;
- } else {
- if ($type == '') {
- } else {
- $tree = find_id_moniker(array('page' => $view_category_page_link_pattern[1], 'type' => $view_category_page_link_pattern[2], 'id' => $parent), $zone);
- }
- }
- // Okay, so our full tree path is as follows
- $moniker = $tree . '/' . $main;
- }
- }
- return $moniker;
- }
- /**
- * Take a moniker and it's page-link details, and make a full path from it.
- *
- * @param ID_TEXT $content_type The content type.
- * @param SHORT_TEXT $url_moniker The URL moniker.
- * @return ?ID_TEXT The ID (null: not found).
- */
- function find_id_via_url_moniker($content_type, $url_moniker)
- {
- $path = 'hooks/systems/content_meta_aware/' . filter_naughty($content_type, true);
- if ((!file_exists(get_file_base() . '/sources/' . $path . '.php')) && (!file_exists(get_file_base() . '/sources_custom/' . $path . '.php'))) {
- return null;
- }
- require_code($path);
- $cma_ob = object_factory('Hook_content_meta_aware_' . $content_type);
- $cma_info = $cma_ob->info();
- if (!$cma_info['support_url_monikers']) {
- return null;
- }
- $where = array('m_resource_page' => $url_bits['page'], 'm_resource_type' => $url_bits['type'], 'm_moniker' => $url_moniker);
- $ret = $cma_info['connection']->query_select_value_if_there('url_id_monikers', 'm_resource_id', $where);
- return $ret;
- }
Here's the fix to do it:
Code (php)
- <?php /*
- Composr
- Copyright (c) ocProducts, 2004-2016
- See text/EN/licence.txt for full licencing information.
- NOTE TO PROGRAMMERS:
- Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
- **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****
- */
- /**
- * @license http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
- * @copyright ocProducts Ltd
- * @package core
- */
- /**
- * Change whatever global context that is required in order to run from a different context.
- *
- * @sets_input_state
- *
- * @param array $new_get The URL component map (must contain 'page').
- * @param ID_TEXT $new_zone The zone.
- * @param ID_TEXT $new_current_script The running script.
- * @param boolean $erase_keep_also Whether to get rid of keep_ variables in current URL.
- * @return array A list of parameters that would be required to be passed back to reset the state.
- */
- function set_execution_context($new_get, $new_zone = '_SEARCH', $new_current_script = 'index', $erase_keep_also = false)
- {
- $old_get = $_GET;
- $old_zone = get_zone_name();
- $old_current_script = current_script();
- foreach ($_GET as $key => $val) {
- }
- }
- }
- foreach ($new_get as $key => $val) {
- }
- global $RELATIVE_PATH, $ZONE, $SELF_URL_CACHED;
- $RELATIVE_PATH = ($new_zone == '_SEARCH') ? get_page_zone(get_page_name()) : $new_zone;
- if ($new_zone != $old_zone) {
- $ZONE = null; // So zone details will have to reload
- }
- $SELF_URL_CACHED = null;
- global $PAGE_NAME_CACHE;
- $PAGE_NAME_CACHE = null;
- global $RUNNING_SCRIPT_CACHE, $WHAT_IS_RUNNING_CACHE;
- $WHAT_IS_RUNNING_CACHE = $new_current_script;
- }
- /**
- * Map spaces to %20 and put http:// in front of URLs starting www.
- *
- * @param URLPATH $url The URL to fix
- * @return URLPATH The fixed result
- */
- function remove_url_mistakes($url)
- {
- $url = 'http://' . $url;
- }
- return $url;
- }
- /**
- * Get hidden fields for a form representing 'keep_x'. If we are having a GET form instead of a POST form, we need to do this. This function also encodes the page name, as we'll always want that.
- *
- * @param ID_TEXT $page The page for the form to go to (blank: don't attach)
- * @param boolean $keep_all Whether to keep all elements of the current URL represented in this form (rather than just the keep_ fields, and page)
- * @param ?array $exclude A list of parameters to exclude (null: don't exclude any)
- * @return Tempcode The builtup hidden form fields
- *
- * @ignore
- */
- function _build_keep_form_fields($page = '', $keep_all = false, $exclude = null)
- {
- }
- if ($page == '_SELF') {
- $page = get_page_name();
- }
- $out = new Tempcode();
- foreach ($_GET as $key => $val) {
- foreach ($val as $_key => $_val) { // We'll only support one level deep. Also no keep parameter array support.
- }
- if ($process_for_key) {
- $out->attach(form_input_hidden($key . '[' . $_key . ']', $_val));
- }
- }
- } else {
- continue;
- }
- }
- }
- if ($process_for_key) {
- $out->attach(form_input_hidden($key, $val));
- }
- }
- }
- }
- if ($page != '') {
- $out->attach(form_input_hidden('page', $page));
- }
- return $out;
- }
- /**
- * Recurser helper function for _build_keep_post_fields.
- *
- * @param ID_TEXT $key Key name to put value under
- * @param mixed $value Value (string or array)
- * @return string The builtup hidden form fields
- *
- * @ignore
- */
- function _fixed_post_parser($key, $value)
- {
- $out = '';
- }
- foreach ($value as $k => $v) {
- $out .= _fixed_post_parser($key . '[' . $k . ']', $v);
- } else {
- }
- }
- } else {
- }
- }
- return $out;
- }
- /**
- * Relay all POST variables for this URL, to the URL embedded in the form.
- *
- * @param ?array $exclude A list of parameters to exclude (null: exclude none)
- * @param boolean $force_everything Force field labels and descriptions to copy through even when there are huge numbers of parameters
- * @return Tempcode The builtup hidden form fields
- *
- * @ignore
- */
- function _build_keep_post_fields($exclude = null, $force_everything = false)
- {
- $out = '';
- foreach ($_POST as $key => $val) {
- }
- continue;
- }
- continue;
- }
- continue;
- }
- continue;
- }
- }
- $out .= _fixed_post_parser($key, $val);
- }
- return make_string_tempcode($out);
- }
- /**
- * Takes a URL, and converts it into a file system storable filename. This is used to cache URL contents to the servers filesystem.
- *
- * @param URLPATH $url_full The URL to convert to an encoded filename
- * @return string A usable filename based on the URL
- *
- * @ignore
- */
- function _url_to_filename($url_full)
- {
- $new_name = $url_full;
- foreach ($bad_chars as $bad_char) {
- if ($bad_char == ':') {
- $good_char = ';'; // So page_links save nice
- }
- }
- if (strlen($new_name) <= 200/*technically 256 but something may get put on the start, so be cautious*/) {
- return $new_name;
- }
- // Non correspondance, but at least we have something
- }
- }
- /**
- * Take a URL and base-URL, and fully qualify the URL according to it.
- *
- * @param URLPATH $url The URL to fully qualified
- * @param URLPATH $url_base The base-URL
- * @return URLPATH Fully qualified URL
- *
- * @ignore
- */
- function _qualify_url($url, $url_base)
- {
- require_code('obfuscate');
- $mto = mailto_obfuscated();
- if (url_is_local($url)) {
- if ($url[0] == '/') {
- if ($parsed === false) {
- return '';
- }
- $parsed['scheme'] = 'http';
- }
- $parsed['host'] = 'localhost';
- }
- $url = $parsed['scheme'] . ':' . $url;
- } else {
- $url = $parsed['scheme'] . '://' . $parsed['host'] . (array_key_exists('port', $parsed) ? (':' . $parsed['port']) : '') . $url;
- }
- } else {
- $url = $url_base . '/' . $url;
- }
- }
- }
- while ($pos !== false) {
- if ($pos_2 === false) {
- break;
- }
- }
- return $url;
- }
- /**
- * Convert a URL to a local file path.
- *
- * @param URLPATH $url The value to convert
- * @return ?PATH File path (null: is not local)
- * @ignore
- */
- function _convert_url_to_path($url)
- {
- return null;
- }
- } else {
- }
- $_file_path_stub = get_custom_file_base() . '/' . $file_path_stub;
- $_file_path_stub = get_file_base() . '/' . $file_path_stub;
- }
- } else {
- $_file_path_stub = get_file_base() . '/' . $file_path_stub;
- }
- return null;
- }
- return $_file_path_stub;
- }
- return null;
- }
- /**
- * Sometimes users don't enter full URLs but do intend for them to be absolute. This code tries to see what relative URLs are actually absolute ones, via an algorithm. It then fixes the URL.
- *
- * @param URLPATH $in The URL to fix
- * @return URLPATH The fixed URL (or original one if no fix was needed)
- * @ignore
- */
- function _fixup_protocolless_urls($in)
- {
- if ($in == '') {
- return $in;
- }
- $in = remove_url_mistakes($in); // Chain in some other stuff
- return $in; // Absolute (e.g. http:// or mailto:)
- }
- return $in;
- }
- return $in;
- }
- return $in;
- }
- // Rule 1: // If we have a dot somewhere before a slash, then this dot is likely part of a domain name (not a file extension)- thus we have an absolute URL.
- return 'http://' . $in; // Fix it
- }
- // Rule 2: // If we have no slashes and we don't recognise a file type then they've probably just entered a domain name- thus we have an absolute URL.
- if ((preg_match('#^[^/]+$#', $in) != 0) && (preg_match('#\.(php|htm|asp|jsp|swf|gif|png|jpg|jpe|txt|pdf|odt|ods|odp|doc|mdb|xls|ppt|xml|rss|ppt|svg|wrl|vrml|gif|psd|rtf|bmp|avi|mpg|mpe|webm|mp4|mov|wmv|ram|rm|asf|ra|wma|wav|mp3|ogg|torrent|csv|ttf|tar|gz|rar|bz2)#', $in) == 0)) {
- return 'http://' . $in . '/'; // Fix it
- }
- return $in; // Relative
- }
- /**
- * Convert a local URL to a page-link.
- *
- * @param URLPATH $url The URL to convert. Note it may not be a URL Scheme, and it must be based on the local base URL (else failure WILL occur).
- * @param boolean $abs_only Whether to only convert absolute URLs. Turn this on if you're not sure what you're passing is a URL not and you want to be extra safe.
- * @param boolean $perfect_only Whether to only allow perfect conversions.
- * @return string The page-link (blank: could not convert).
- *
- * @ignore
- */
- function _url_to_page_link($url, $abs_only = false, $perfect_only = true)
- {
- return '';
- }
- // Try and strip any variants of the base URL from our $url variable, to make it relative
- $non_www_base_url = str_replace('https://www.', 'https://', str_replace('http://www.', 'http://', get_base_url()));
- $www_base_url = str_replace('https://', 'https://www.', str_replace('http://', 'http://www.', get_base_url()));
- return '';
- }
- return '';
- }
- $url = '/' . $url;
- }
- // Parse the URL
- if ($parsed_url === false) {
- require_code('site');
- attach_message(do_lang_tempcode('HTTP_DOWNLOAD_BAD_URL', escape_html($url)), 'warn');
- return '';
- }
- // Work out the zone
- $zone = '';
- $slash_pos = false;
- }
- $attributes['page'] = ''; // hopefully will get overwritten with a real one
- // Convert URL Scheme path info into extra implied attribute data
- require_code('url_remappings');
- $does_match = false;
- $mappings = get_remappings($url_scheme);
- foreach ($mappings as $mapping) { // e.g. array(array('page' => 'wiki', 'id' => null), 'pg/s/ID', true),
- continue;
- }
- $match_string_pattern = preg_replace('#[A-Z]+#', '[^\&\?]+', preg_quote($match_string)); // Turn match string into a regexp
- if ($does_match) {
- if ($url_scheme == 'HTM') {
- continue;
- }
- } else {
- continue;
- }
- $_match_string = $match_string;
- $_path = $parsed_url['path'];
- }
- foreach ($bits_pattern as $i => $bit) {
- if ((strtoupper($bit) == $bit) && (array_key_exists(strtolower($bit), $params)) && (is_null($params[strtolower($bit)]))) {
- }
- }
- foreach ($attributes as &$attribute) {
- }
- break 2;
- }
- }
- }
- if (!$does_match) {
- return ''; // No match was found
- }
- // Parse query string component into the waiting (and partly-filled-already) attribute data array
- foreach ($bits as $bit) {
- $attributes[$_bit[0]] = cms_url_decode_post_process($_bit[1]);
- if ($perfect_only) {
- return ''; // Could not convert this URL to a page-link, because it contains a colon
- }
- }
- }
- }
- }
- require_code('site');
- if (_request_page($attributes['page'], $zone) === false) {
- return '';
- }
- $page = fix_page_name_dashing($zone, $attributes['page']);
- // Put it together
- $page_link = $zone . ':' . $page;
- $page_link .= ':' . $attributes['type'];
- $page_link .= ':';
- }
- $page_link .= ':' . $attributes['id'];
- }
- foreach ($attributes as $key => $val) {
- }
- if (($key != 'page') && ($key != 'type') && ($key != 'id')) {
- $page_link .= ':' . $key . '=' . cms_url_encode($val);
- }
- }
- // Hash bit?
- $page_link .= '#' . $parsed_url['fragment'];
- }
- return $page_link;
- }
- /**
- * Convert a local page file path to a written page-link.
- *
- * @param string $page The path.
- * @return string The page-link (blank: could not convert).
- *
- * @ignore
- */
- function _page_path_to_page_link($page)
- {
- }
- if (preg_match('#^([^/]*)/?pages/([^/]+)/(\w\w/)?([^/\.]+)\.(php|txt|htm)$#', $page, $matches) == 1) {
- $page2 = $matches[1] . ':' . $matches[4];
- if (($matches[2] == 'comcode') || ($matches[2] == 'comcode_custom')) {
- $page2 .= ' (' . $matches[1] . ')';
- $page2 .= ' (' . $matches[1] . ')';
- }
- }
- }
- } else {
- $page2 = '';
- }
- return $page2;
- }
- /**
- * Called from 'find_id_moniker'. We tried to lookup a moniker, found a hook, but found no stored moniker. So we'll try and autogenerate one.
- *
- * @param array $ob_info The hooks info profile.
- * @param array $url_parts The URL component map (must contain 'page', 'type', and 'id' if this function is to do anything).
- * @param ID_TEXT $zone The URL zone name (only used for Comcode Page URL monikers).
- * @return ?string The moniker ID (null: error generating it somehow, can not do it)
- */
- function autogenerate_new_url_moniker($ob_info, $url_parts, $zone)
- {
- $effective_id = ($url_parts['type'] == '') ? $url_parts['page'] : $url_parts['id'];
- $bak = $GLOBALS['NO_DB_SCOPE_CHECK'];
- $GLOBALS['NO_DB_SCOPE_CHECK'] = true;
- require_code('content');
- append_content_select_for_id($select, $ob_info);
- $select[] = $ob_info['title_field'];
- }
- if ($ob_info['parent_category_field'] !== null) {
- $select[] = $ob_info['parent_category_field'];
- }
- $db = ((substr($ob_info['table'], 0, 2) != 'f_') || (get_forum_type() == 'none')) ? $GLOBALS['SITE_DB'] : $GLOBALS['FORUM_DB'];
- $where = get_content_where_for_str_id($effective_id, $ob_info);
- $where['the_zone'] = $zone;
- }
- $_moniker_src = $db->query_select($ob_info['table'], $select, $where); // NB: For Comcode pages visited, this won't return anything -- it will become more performant when the page actually loads, so the moniker won't need redoing each time
- $GLOBALS['NO_DB_SCOPE_CHECK'] = $bak;
- return null; // been deleted?
- }
- if ($ob_info['id_field_numeric']) {
- } else {
- if ($ob_info['title_field_dereference']) {
- $moniker_src = get_translated_text($_moniker_src[0][$ob_info['title_field']]);
- } else {
- $moniker_src = $_moniker_src[0][$ob_info['title_field']];
- }
- }
- } else {
- $moniker_src = $effective_id;
- }
- if ($moniker_src == '') {
- $moniker_src = 'untitled';
- }
- return suggest_new_idmoniker_for($url_parts['page'], isset($url_parts['type']) ? $url_parts['type'] : '', $url_parts['id'], $zone, $moniker_src, true);
- }
- /**
- * Called when content is added, or edited/moved, based upon a new form field that specifies what moniker to use.
- *
- * @param ID_TEXT $page Page name.
- * @param ID_TEXT $type Screen type code.
- * @param ID_TEXT $id Resource ID.
- * @param ID_TEXT $zone The URL zone name (only used for Comcode Page URL monikers).
- * @param string $moniker_src String from which a moniker will be chosen (may not be blank).
- * @param boolean $is_new Whether we are sure this is a new moniker (makes things more efficient, saves a query).
- * @param ?string $moniker Actual moniker to use (null: generate from $moniker_src). Usually this is left null.
- * @return string The chosen moniker.
- */
- function suggest_new_idmoniker_for($page, $type, $id, $zone, $moniker_src, $is_new = false, $moniker = null)
- {
- if (get_option('url_monikers_enabled') == '0') {
- return '';
- }
- $ref = $zone . ':' . $page . ':' . $type . ':' . $id;
- if ($moniker !== null) {
- $force_called[$ref] = $moniker;
- } else {
- return $force_called[$ref];
- }
- }
- if (!$is_new) {
- $manually_chosen = $GLOBALS['SITE_DB']->query_select_value_if_there('url_id_monikers', 'm_moniker', array('m_manually_chosen' => 1, 'm_resource_page' => $page, 'm_resource_type' => $type, 'm_resource_id' => $id));
- if ($manually_chosen !== null) {
- return $manually_chosen;
- }
- // Deprecate old one if already exists
- $old = $GLOBALS['SITE_DB']->query_select_value_if_there('url_id_monikers', 'm_moniker', array('m_resource_page' => $page, 'm_resource_type' => $type, 'm_resource_id' => $id, 'm_deprecated' => 0), 'ORDER BY id DESC');
- // See if it is same as current
- if ($moniker === null) {
- $scope = _give_moniker_scope($page, $type, $id, $zone, '');
- $moniker = $scope . _choose_moniker($page, $type, $id, $moniker_src, $old, $scope);
- }
- if ($moniker == $old) {
- return $old; // hmm, ok it can stay actually
- }
- // It's not. Although, the later call to _choose_moniker will allow us to use the same stem as the current active one, or even re-activate an old deprecated one, so long as it is on this same m_resource_page/m_resource_page/m_resource_id.
- // Deprecate
- // Deprecate anything underneath
- global $CONTENT_OBS;
- load_moniker_hooks();
- $looking_for = '_SEARCH:' . $page . ':' . $type . ':_WILD';
- $category_page = $parts[1];
- $GLOBALS['SITE_DB']->query('UPDATE ' . get_table_prefix() . 'url_id_monikers SET m_deprecated=1 WHERE ' . db_string_equal_to('m_resource_page', $category_page) . ' AND m_moniker LIKE \'' . db_encode_like($old . '/%') . '\''); // Deprecate
- }
- }
- }
- if ($moniker === null) {
- $moniker = $id;
- } else {
- $scope = _give_moniker_scope($page, $type, $id, $zone, '');
- $moniker = $scope . _choose_moniker($page, $type, $id, $moniker_src, null, $scope);
- if (($page == 'news') && ($type == 'view') && (get_value('google_news_urls') === '1')) {
- }
- }
- }
- // Insert
- $GLOBALS['SITE_DB']->query_delete('url_id_monikers', array( // It's possible we're re-activating a deprecated one
- 'm_resource_page' => $page,
- 'm_resource_type' => $type,
- 'm_resource_id' => $id,
- 'm_moniker' => $moniker,
- ), '', 1);
- 'm_resource_page' => $page,
- 'm_resource_type' => $type,
- 'm_resource_id' => $id,
- 'm_moniker' => $moniker,
- 'm_deprecated' => 0,
- 'm_manually_chosen' => 0,
- ));
- global $LOADED_MONIKERS_CACHE;
- return $moniker;
- }
- /**
- * Delete an old moniker, and place a new one.
- *
- * @param ID_TEXT $page Page name.
- * @param ID_TEXT $type Screen type code.
- * @param ID_TEXT $id Resource ID.
- * @param string $moniker_src String from which a moniker will be chosen (may not be blank).
- * @param ?string $no_exists_check_for Whether to skip the exists check for a certain moniker (will be used to pass "existing self" for edits) (null: nothing existing to check against).
- * @param ?string $scope_context Where the moniker will be placed in the moniker URL tree (null: unknown, so make so no duplicates anywhere).
- * @return string Chosen moniker.
- *
- * @ignore
- */
- function _choose_moniker($page, $type, $id, $moniker_src, $no_exists_check_for = null, $scope_context = null)
- {
- $moniker = _generate_moniker($moniker_src);
- // Check it does not already exist
- $moniker_origin = $moniker;
- $next_num = 1;
- $moniker .= '-1';
- }
- $test = mixed();
- do {
- return $moniker; // This one is okay, we know it is safe
- }
- }
- $dupe_sql = 'SELECT m_resource_id FROM ' . get_table_prefix() . 'url_id_monikers WHERE ';
- $dupe_sql .= db_string_equal_to('m_resource_page', $page);
- if ($type == '') {
- $dupe_sql .= ' AND ' . db_string_equal_to('m_resource_id', $id);
- } else {
- $dupe_sql .= ' AND ' . db_string_equal_to('m_resource_type', $type) . ' AND ' . db_string_not_equal_to('m_resource_id', $id);
- }
- $dupe_sql .= ' AND (';
- $dupe_sql .= db_string_equal_to('m_moniker', $scope_context . $moniker);
- } else {
- // Use reversing for better indexing performance
- }
- $dupe_sql .= ')';
- $test = $GLOBALS['SITE_DB']->query_value_if_there($dupe_sql, false, true);
- $next_num++;
- }
- return $moniker;
- }
- /**
- * Generate a moniker from an arbitrary raw string. Does not perform uniqueness checks.
- *
- * @param string $moniker_src Raw string.
- * @return ID_TEXT Moniker.
- *
- * @ignore
- */
- function _generate_moniker($moniker_src)
- {
- $moniker = strip_comcode($moniker_src);
- // Transliteration first
- if (get_charset() == 'utf-8') {
- $moniker = transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $moniker);
- } else {
- // German has inbuilt transliteration
- }
- }
- // Then strip down / substitute to force it to be URL-ready
- if (($pos === false) || ($pos < 12)) {
- $pos = $max_moniker_length;
- }
- }
- // A bit lame, but maybe we'll have to
- if ($moniker == '') {
- $moniker = 'untitled';
- }
- return $moniker;
- }
- /**
- * Take a moniker and it's page-link details, and make a full path from it.
- *
- * @param ID_TEXT $page Page name.
- * @param ID_TEXT $type Screen type code.
- * @param ID_TEXT $id Resource ID.
- * @param ID_TEXT $zone The URL zone name (only used for Comcode Page URL monikers).
- * @param string $main Pathless moniker.
- * @return string The fully qualified moniker.
- *
- * @ignore
- */
- function _give_moniker_scope($page, $type, $id, $zone, $main)
- {
- // Does this URL arrangement support monikers?
- global $CONTENT_OBS;
- load_moniker_hooks();
- $found = false;
- if ($type == '') {
- $looking_for = '_WILD:_WILD';
- } else {
- $looking_for = '_SEARCH:' . $page . ':' . $type . ':_WILD';
- }
- $moniker = $main;
- return $moniker;
- }
- if ($ob_info['parent_category_field'] == 'the_zone') {
- $ob_info['parent_category_field'] = 'p_parent_page'; // Special exception for Comcode page monikers
- }
- // Lookup DB record so we can discern the category
- $bak = $GLOBALS['NO_DB_SCOPE_CHECK'];
- $GLOBALS['NO_DB_SCOPE_CHECK'] = true;
- require_code('content');
- append_content_select_for_id($select, $ob_info);
- $select[] = $ob_info['title_field'];
- }
- $select[] = $ob_info['parent_category_field'];
- }
- $where = get_content_where_for_str_id(($type == '') ? $page : $id, $ob_info);
- $where['the_zone'] = $zone;
- }
- $_moniker_src = $GLOBALS['SITE_DB']->query_select($ob_info['table'], $select, $where);
- $GLOBALS['NO_DB_SCOPE_CHECK'] = $bak;
- return $moniker; // been deleted?
- }
- // Discern the path (will effectively recurse, due to find_id_moniker call)
- $parent = $_moniker_src[0][$ob_info['parent_category_field']];
- }
- $tree = null;
- } else {
- if ($type == '') {
- } else {
- $tree = find_id_moniker(array('page' => $view_category_page_link_pattern[1], 'type' => $view_category_page_link_pattern[2], 'id' => $parent), $zone);
- }
- }
- // Okay, so our full tree path is as follows
- $moniker = $tree . '/' . $main;
- }
- }
- return $moniker;
- }
- /**
- * Take a moniker and it's page-link details, and make a full path from it.
- *
- * @param ID_TEXT $content_type The content type.
- * @param SHORT_TEXT $url_moniker The URL moniker.
- * @return ?ID_TEXT The ID (null: not found).
- */
- function find_id_via_url_moniker($content_type, $url_moniker)
- {
- $path = 'hooks/systems/content_meta_aware/' . filter_naughty($content_type, true);
- if ((!file_exists(get_file_base() . '/sources/' . $path . '.php')) && (!file_exists(get_file_base() . '/sources_custom/' . $path . '.php'))) {
- return null;
- }
- require_code($path);
- $cma_ob = object_factory('Hook_content_meta_aware_' . $content_type);
- $cma_info = $cma_ob->info();
- if (!$cma_info['support_url_monikers']) {
- return null;
- }
- $where = array('m_resource_page' => $url_bits['page'], 'm_resource_type' => $url_bits['type'], 'm_moniker' => $url_moniker);
- $ret = $cma_info['connection']->query_select_value_if_there('url_id_monikers', 'm_resource_id', $where);
- return $ret;
- }
Posted
two of the three view buttons lead to sub-categories
This is where I'm not following, I don't understand the nature of the structural problem you're having.
Posted
But I find after added the English translation before Chinese characters, the "view" buttons are in order, i.e. jumping to where they should have been.
Thank you Chris for your great and prompt reply.
Posted
Transliteration is converting the script. In this case converting Chinese script to English/Latin/Roman script because that's what's used in URLs. See how "你好" automatically became "nin-hao" for the URL?
I'll take a look at GoDaddy's situation.
Posted
Transliteration
This provides transliteration support to those without the PHP intl extension. This is used for URL moniker generation. Licence ------- Artistic License (https://github.com/Behat/Transliterator/blob/master/LICENSE) Additional credits/attributions ------------------------------- Konsta Vesterinen, Jonathan H. Wage, Other unknown developers
I think you've given me site access (I haven't gone through my emails fully yet), so if so I'll install it for you.
Posted
I deployed the new addon to your site, it's working well.
I did find a problem with the URL monikers, you had monikers in the cms_url_id_monikers table for download categories that didn't exist yet, so when new categories were made it re-used those old monikers. It looks to me like the cms_download_categories AUTO_INCREMENT value got changed somehow, as usually it will never re-use the same ID. I fixed that for you, and then the new monikers were generating nicely with my addon. I think this might have been the problem you were trying to explain that I didn't understand initially.
Posted
Would it be even better if "/" could be used after transliteration instead of "%2F" in the url, i.e. in "id=tsui-ping-church%2Fjing-bai-bu%2Fjiang-dao-lu-yin"?
Posted
Yes, just enable a "URL Scheme" and the ID component will become a URL path component, it'll look much more natural without the % encoding.
2 guests and 0 members have recently viewed this.
