From 502b837dd6b49674671ba2c7e882d52b1f0edfb4 Mon Sep 17 00:00:00 2001 From: Stephan Brunker Date: Sun, 13 Oct 2019 22:49:03 +0200 Subject: [PATCH] Fix a lot of single issues and overhaul the language settings see docs/NEWS and the plugin/changelog files for details --- docs/NEWS | 33 + include/admin/personal.inc.php | 5 - include/admin/plugins.inc.php | 10 +- include/compat.inc.php | 5 +- include/functions_config.inc.php | 142 +-- include/functions_entries.inc.php | 32 +- include/functions_routing.inc.php | 6 +- include/plugin_api.inc.php | 44 +- .../ChangeLog | 6 + .../serendipity_event_entryproperties.php | 8 +- .../serendipity_event_nl2br.php | 996 +++++++++--------- plugins/serendipity_event_spartacus/ChangeLog | 5 + .../serendipity_event_spartacus.php | 4 +- .../serendipity_plugin_categories/ChangeLog | 2 + .../serendipity_plugin_categories.php | 5 +- .../ChangeLog | 4 + .../serendipity_plugin_recententries.php | 14 +- .../serendipity_plugin_superuser.php | 5 +- 18 files changed, 730 insertions(+), 596 deletions(-) create mode 100644 plugins/serendipity_plugin_categories/ChangeLog create mode 100644 plugins/serendipity_plugin_recententries/ChangeLog diff --git a/docs/NEWS b/docs/NEWS index fb327d4f..54556fe7 100644 --- a/docs/NEWS +++ b/docs/NEWS @@ -1,3 +1,36 @@ + * admin/personal.inc.php: removed setting of $_SESSION: serendipity_lang + (already set in serendipity_config.inc.php for all scenarios) + * compat.inc.php: function detectLanguage returns now NULL if + the detection failed, also doesn't change $serendipity['autolang'] + anymore which remains 'en' as general fallback. + * functions.entries.php: + * function serendipity_printArchives() hooks now + into hook_event::'frontend_fetchentries' to get multilingual data, + also doesn't show months and years with zero entries. + * function fetchEntryCategories, fetchEntryData and fetchCategories + strips now data of multilingual tags + * plugin_api.inc.php: added function find_plugin_id which returns an + array of the ids of the installed instances of the given plugin + this is used for checking the configuration of that plugin in other + plugins + * functions.config.inc.php: function serendipity_load_configuration + sets the language back to 'autolang' (which is 'en') if the language + loaded does not exist. Also sets the value $serendipity['default_lang'] + to the default language of the blog. + * functions.config.inc.php: removed the Cookie 'userDefLang' which is no + longer needed + * functions.config.inc.php: major rework of the functions + serendipity_getSessionLanguage and serendipity_getPostAuthSessionLanguage. + Those two functions should now process the user input via GET and POST, + store it into SESSION and COOKIE, and if no such input is given, fallback + to browser language negotiation and default language. More details in the + comments to that functions. $serendipity['detected_lang'] is the language + found from user input or browser negotiation. + * functions.routing.inc.php: fix some lookups from $_GET to $serendipity['GET'] + * admin/plugins.inc.php: fix some lookups from $_GET to $serendipity['GET'] + * created a new event hook 'multilingual_strip_langs' to strip tagged translation of elements + outside the sidebar (mostly categories in entry display). + Version 2.4-alpha1 () ------------------------------------------------------------------------ diff --git a/include/admin/personal.inc.php b/include/admin/personal.inc.php index 5e2555cf..194bd5a3 100644 --- a/include/admin/personal.inc.php +++ b/include/admin/personal.inc.php @@ -104,11 +104,6 @@ if ($serendipity['GET']['adminAction'] == 'save' && serendipity_checkFormToken() serendipity_updatePermalink($pl_data, 'author'); serendipity_plugin_api::hook_event('backend_users_edit', $pl_data); } - if ($serendipity['authorid'] === $_SESSION['serendipityAuthorid']) { - if (is_null($serendipity['detected_lang'])) { - $_SESSION['serendipityLanguage'] = $serendipity['lang']; - } - } $from = $_POST; } } diff --git a/include/admin/plugins.inc.php b/include/admin/plugins.inc.php index f2f67836..5950b37a 100644 --- a/include/admin/plugins.inc.php +++ b/include/admin/plugins.inc.php @@ -18,9 +18,9 @@ if (!class_exists('Smarty')) { include_once SMARTY_DIR . 'Smarty.class.php'; } -if (isset($_GET['serendipity']['plugin_to_move']) && isset($_GET['submit']) && serendipity_checkFormToken()) { +if (isset($serendipity['GET']['plugin_to_move']) && isset($serendipity['GET']['submit']) && serendipity_checkFormToken()) { - if (isset($_GET['serendipity']['event_plugin'])) { + if (isset($serendipity['GET']['event_plugin'])) { $plugins = serendipity_plugin_api::enum_plugins('event', false); } else { $plugins = serendipity_plugin_api::enum_plugins('event', true); @@ -32,7 +32,7 @@ if (isset($_GET['serendipity']['plugin_to_move']) && isset($_GET['submit']) && s for($idx = 0; $idx < count($plugins); $idx++) { $plugins[$idx]['sort_order'] = $idx; - if ($plugins[$idx]['name'] == $_GET['serendipity']['plugin_to_move']) { + if ($plugins[$idx]['name'] == $serendipity['GET']['plugin_to_move']) { $idx_to_move = $idx; } } @@ -60,10 +60,10 @@ if (isset($_GET['serendipity']['plugin_to_move']) && isset($_GET['submit']) && s It's a behavior which really has no meaning. */ } -if (isset($_GET['serendipity']['plugin_to_conf'])) { +if (isset($serendipity['GET']['plugin_to_conf'])) { /* configure a specific instance */ - $plugin =& serendipity_plugin_api::load_plugin($_GET['serendipity']['plugin_to_conf']); + $plugin =& serendipity_plugin_api::load_plugin($serendipity['GET']['plugin_to_conf']); if (!($plugin->protected === FALSE || $plugin->serendipity_owner == '0' || $plugin->serendipity_owner == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'))) { return; diff --git a/include/compat.inc.php b/include/compat.inc.php index ae6b9292..b4b62d3c 100644 --- a/include/compat.inc.php +++ b/include/compat.inc.php @@ -464,14 +464,15 @@ function serendipity_detectLang($use_include = false) { if (in_array($preferred_language, $supported_languages)) { if ($use_include) { @include_once(S9Y_INCLUDE_PATH . 'lang/' . $charset . 'serendipity_lang_' . $preferred_language . '.inc.php'); - $serendipity['autolang'] = $preferred_language; + //$serendipity['autolang'] = $preferred_language; -> according to the documentation, it should remain on 'en' } return $preferred_language; } // endif } // endforeach } // endif - return $serendipity['lang']; + // negotiation failed + return null; } /** diff --git a/include/functions_config.inc.php b/include/functions_config.inc.php index 35509a9c..3f5d6dc4 100644 --- a/include/functions_config.inc.php +++ b/include/functions_config.inc.php @@ -328,10 +328,17 @@ function serendipity_load_configuration($author = null) { $serendipity['baseURL'] = $serendipity['defaultBaseURL']; } - // Store default language + // check language selection or fallback + if (isset($serendipity['lang']) && !isset($serendipity['languages'][$serendipity['lang']])) { + $serendipity['lang'] = $serendipity['autolang']; + } + + if (empty($author)) { $serendipity['default_lang'] = $serendipity['lang']; } +} + /** * Perform logout functions (destroys session data) * @@ -661,7 +668,6 @@ function serendipity_load_userdata($username) { $_SESSION['serendipityHashType'] = $serendipity['serendipityHashType'] = $row['hashtype']; serendipity_load_configuration($serendipity['authorid']); - serendipity_setCookie('userDefLang', $serendipity['lang'], false); return true; } @@ -989,73 +995,96 @@ function serendipity_header($header) { * having loaded the right language. * Find a way to let plugins hook into that sequence :-) * + * Rules of precedence: + * active user selection: + * 1. POST 'user_language' from plugin_multilingual sidebar dropdown + * 2. GET 'user_language' from article footer with option 'force full lanugage switch' + * + * prior user selection: + * 3. $_SESSION 'serendipityLanguage' from the running browser session + * 4. $_COOKIE 'serendipityLanguage' new session - user precedence + * + * no user selection: + * 5. new user - browser autodetect with serendipity_detectLang() + * 6. blog language from serendipity_load_configuration() - prior value of $serendipity['lang'] + * + * or if a user is logged in + * 6. user language from serendipity_load_configuration(user) -> handled with a later call to + * serendipity_getPostAuthSessionLanguage() + * 8. default language + * * @access public * @return string Returns the name of the selected language. */ function serendipity_getSessionLanguage() { global $serendipity; - // DISABLE THIS! -/* - if ($_SESSION['serendipityAuthedUser']) { - serendipity_header('X-Serendipity-InterfaceLangSource: Database'); - return $serendipity['lang']; - } -*/ - if (isset($serendipity['lang']) && !isset($serendipity['languages'][$serendipity['lang']])) { - $serendipity['lang'] = $serendipity['autolang']; - } - - if (isset($_REQUEST['user_language']) && (!empty($serendipity['languages'][$_REQUEST['user_language']])) && !headers_sent()) { - serendipity_setCookie('serendipityLanguage', $_REQUEST['user_language'], false); - } - - if (isset($serendipity['COOKIE']['serendipityLanguage'])) { - if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: Cookie'); - $lang = $serendipity['COOKIE']['serendipityLanguage']; - } elseif (isset($serendipity['GET']['lang_selected']) && !empty($serendipity['languages'][$serendipity['GET']['lang_selected']])) { + // try POST + if (isset($serendipity['POST']['user_language']) && !empty($serendipity['languages'][$serendipity['POST']['user_language']])) { + $lang = $serendipity['POST']['user_language']; + if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: POST'); + + // try GET + } elseif (isset($serendipity['GET']['user_language']) && !empty($serendipity['languages'][$serendipity['GET']['user_language']])) { + $lang = $serendipity['GET']['user_language']; if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: GET'); - $lang = $serendipity['GET']['lang_selected']; - } elseif (serendipity_db_bool($serendipity['lang_content_negotiation'])) { - if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: Content-Negotiation'); - $lang = serendipity_detectLang(); + } + + // save user selection into COOKIE and SESSION + if (isset($lang) && !headers_sent()) { + serendipity_setCookie('serendipityLanguage', $lang, false); + $serendipity['COOKIE']['serendipityLanguage'] = $lang; } if (isset($lang)) { - $serendipity['detected_lang'] = $lang; - } else { - if (! empty($_SESSION['serendipityLanguage'])) { + $_SESSION['serendipityLanguage'] = $lang; + } + + // no active user selection, fall back to saved prior selections + if (!isset($lang)) { + // try SESSION + if (isset($_SESSION['serendipityLanguage']) && !empty($serendipity['languages'][$_SESSION['serendipityLanguage']])) { $lang = $_SESSION['serendipityLanguage']; - } else { - if (isset($serendipity['COOKIE']['userDefLang']) && ! empty($serendipity['COOKIE']['userDefLang'])) { - $lang = $serendipity['COOKIE']['userDefLang']; - } else { - if ($serendipity['lang']) { + if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: SESSION'); + + // try COOKIE + } elseif (isset($serendipity['COOKIE']['serendipityLanguage']) && !empty($serendipity['languages'][$serendipity['COOKIE']['serendipityLanguage']])) { + $lang = $serendipity['COOKIE']['serendipityLanguage']; + if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: COOKIE'); + + // try Browser language negotiation + } elseif (serendipity_db_bool($serendipity['lang_content_negotiation'])) { + $lang = serendipity_detectLang(); // returns negotiated language + if (!empty($lang) && $serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: Content-Negotiation'); + } + + // cache the result + if ($lang) $serendipity['detected_lang'] = $lang; + + // try configuration: blog default language + if (empty($lang) && $serendipity['lang']) { $lang = $serendipity['lang']; - } else { - // serendipity_load_configuration() failed to load language, go default + if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: Configuration'); + } + + // if everthing failed, fall back to autolang which is still 'en' because detectLang failed too + if (empty($lang)) { $lang = $serendipity['autolang']; } - } - } - $serendipity['detected_lang'] = null; - } - - if (!isset($serendipity['languages'][$lang])) { - $serendipity['detected_lang'] = null; - return $serendipity['lang']; } else { - $_SESSION['serendipityLanguage'] = $lang; - if (!is_null($serendipity['detected_lang'])) { - if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLang: ' . $lang); - } + // cache the result + if ($lang) $serendipity['detected_lang'] = $lang; } + // save the result into SESSION + if ($lang) $_SESSION['serendipityLanguage'] = $lang; + if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLang: ' . $lang); return $lang; } /** * Gets the selected language from personal configuration if needed + * if getSessionLanguage detected a language by user selection or browser negotiation, it has priority * * This function also sets HTTP Headers and cookies to contain the language for follow-up requests * @@ -1065,29 +1094,20 @@ function serendipity_getSessionLanguage() { function serendipity_getPostAuthSessionLanguage() { global $serendipity; - if (! is_null($serendipity['detected_lang'])) { - return $serendipity['detected_lang']; - } + // cached result from getSessionLanguage() + if (!empty($serendipity['detected_lang']) && !defined('IN_serendipity_admin')) return $serendipity['detected_lang']; + // if that returned the fallback language, try user default language or fallback if ($_SESSION['serendipityAuthedUser']) { if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLangSource: Database'); - $lang = $serendipity['lang']; - } else { - $lang = (isset($_SESSION['serendipityLanguage'])) ? $_SESSION['serendipityLanguage'] : $serendipity['lang']; - } - - if (!isset($serendipity['languages'][$lang])) { - $lang = $serendipity['lang']; + $lang = $serendipity['lang']; //$serendipity['lang'] is overwritten by load_configuration(user) and points to the user default language } + // save the result into SESSION $_SESSION['serendipityLanguage'] = $lang; if ($serendipity['expose_s9y']) serendipity_header('X-Serendipity-InterfaceLang: ' . $lang); - if ($lang != $serendipity['lang']) { - $serendipity['content_lang'] = $lang; - } - return $lang; } diff --git a/include/functions_entries.inc.php b/include/functions_entries.inc.php index daf9ec44..156bee14 100644 --- a/include/functions_entries.inc.php +++ b/include/functions_entries.inc.php @@ -146,10 +146,15 @@ function &serendipity_fetchEntryCategories($entryid) { ORDER BY c.category_name ASC"; $cat =& serendipity_db_query($query); + if (!is_array($cat)) { $arr = array(); return $arr; } else { + foreach ($cat as $key => $catdata) { + serendipity_plugin_api::hook_event('multilingual_strip_langs',$cat[$key]['category_name']); + serendipity_plugin_api::hook_event('multilingual_strip_langs',$cat[$key]['category_description']); + } return $cat; } } @@ -511,6 +516,8 @@ function serendipity_fetchEntryData(&$ret) { if (is_array($search_ret)) { foreach($search_ret AS $i => $entry) { + serendipity_plugin_api::hook_event('multilingual_strip_langs',$entry['category_name']); + serendipity_plugin_api::hook_event('multilingual_strip_langs',$entry['category_description']); $ret[$assoc_ids[$entry['entryid']]]['categories'][] = $entry; } } @@ -722,9 +729,16 @@ function &serendipity_fetchCategories($authorid = null, $name = null, $order = n $flat_cats = array(); $flat_cats[0] = NO_CATEGORY; foreach($cats AS $catidx => $catdata) { + serendipity_plugin_api::hook_event('multilingual_strip_langs', $catdata['category_name']); $flat_cats[$catdata['categoryid']] = str_repeat(' ', $catdata['depth']*2) . serendipity_specialchars($catdata['category_name']); } return $flat_cats; + } else { + foreach ($ret as $key => $catdata) { + serendipity_plugin_api::hook_event('multilingual_strip_langs',$ret[$key]['category_name']); + serendipity_plugin_api::hook_event('multilingual_strip_langs',$ret[$key]['category_description']); + } + return $ret; } } return $ret; @@ -1659,18 +1673,25 @@ function serendipity_printArchives() { $distinct = ''; } + // if another language than default is selected and hide option is set, hide untranslated articles + $sql_condition = array(); + serendipity_plugin_api::hook_event('frontend_fetchentries', $sql_condition); + $q = "SELECT $distinct e.timestamp FROM {$serendipity['dbPrefix']}entries e " . (!empty($cat_sql) ? " LEFT JOIN {$serendipity['dbPrefix']}entrycat ec ON e.id = ec.entryid LEFT JOIN {$serendipity['dbPrefix']}category c - ON ec.categoryid = c.categoryid" : "") . " - WHERE isdraft = 'false'" + ON ec.categoryid = c.categoryid" : "") . + $sql_condition['joins'] . + " WHERE isdraft = 'false'" + . $sql_condition['and'] . (!serendipity_db_bool($serendipity['showFutureEntries']) ? " AND timestamp <= " . serendipity_db_time() : '') . (!empty($cat_sql) ? ' AND ' . $cat_sql : '') . (!empty($serendipity['GET']['viewAuthor']) ? ' AND e.authorid = ' . (int)$serendipity['GET']['viewAuthor'] : '') . (!empty($cat_sql) ? " GROUP BY e.id, e.timestamp" : ''); + $entries =& serendipity_db_query($q, false, 'assoc'); $group = array(); @@ -1682,7 +1703,7 @@ function serendipity_printArchives() { $output = array(); for ($y = $thisYear; $y >= $lastYear; $y--) { - $output[$y]['year'] = $y; + for ($m = 12; $m >= 1; $m--) { /* If the month we are checking are in the future, we drop it */ @@ -1710,6 +1731,10 @@ function serendipity_printArchives() { $entry_count = (int)$group[$y . (strlen($m) == 1 ? '0' : '') . $m]; + if ($entry_count > 0) { + + if (!array_key_exists($y,$output)) $output[$y]['year'] = $y; + /* A silly hack to get the maximum amount of entries per month */ if ($entry_count > $max) { $max = $entry_count; @@ -1721,6 +1746,7 @@ function serendipity_printArchives() { $data['link_summary'] = serendipity_archiveDateUrl($y . '/'. sprintf('%02s', $m) . $cat_get . $author_get, true); $data['date'] = $s; $output[$y]['months'][] = $data; + } } } diff --git a/include/functions_routing.inc.php b/include/functions_routing.inc.php index 504c949e..aa3a1c21 100644 --- a/include/functions_routing.inc.php +++ b/include/functions_routing.inc.php @@ -47,7 +47,7 @@ function locateHiddenVariables($_args) { } elseif ($v[0] == 'A') { /* Author */ $url_author = substr($v, 1); if (is_numeric($url_author)) { - $serendipity['GET']['viewAuthor'] = $_GET['viewAuthor'] = (int)$url_author; + $serendipity['GET']['viewAuthor'] = (int)$url_author; unset($_args[$k]); } } elseif ($v == 'summary') { /* Summary */ @@ -366,8 +366,8 @@ function serveEntry($matches) { $id = false; } - $_GET['serendipity']['action'] = 'read'; - $_GET['serendipity']['id'] = $id; + $serendipity['GET']['action'] = 'read'; + $serendipity['GET']['id'] = $id; $title = serendipity_db_query("SELECT title FROM {$serendipity['dbPrefix']}entries WHERE id=$id AND isdraft = 'false' " . (!serendipity_db_bool($serendipity['showFutureEntries']) ? " AND timestamp <= " . serendipity_db_time() : ''), true); if (is_array($title)) { diff --git a/include/plugin_api.inc.php b/include/plugin_api.inc.php index f72aa559..901de38a 100644 --- a/include/plugin_api.inc.php +++ b/include/plugin_api.inc.php @@ -93,7 +93,7 @@ function errorHandlerCreateDOM(htmlStr) { case 'backend_save': case 'backend_publish': // this is preview_iframe.tpl updertHooks [ NOT ONLY!! See freetags ] - if ($_GET['serendipity']['is_iframe'] == 'true' && $_GET['serendipity']['iframe_mode'] == 'save') { + if ($serendipity['GET']['is_iframe'] == 'true' && $serendipity['GET']['iframe_mode'] == 'save') { echo "\n".''."\n"; } break; @@ -263,6 +263,8 @@ class serendipity_plugin_api } serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}config where name LIKE '$plugin_instance_id/%'"); + return; + } /** @@ -1204,6 +1206,46 @@ class serendipity_plugin_api return $instance; } + + /** + * Find the plugin instances for a given classname + * + * @access public + * @param string The classname of the plugin + * @param int The owner author + * @param boolean ignore hidden (deactivated) plugins + * @return object Array with ids of the installed plugin + */ + static function find_plugin_id($plugin_name,$authorid = 0, $ignore_hidden = true) { + global $serendipity; + + $sql = "SELECT * from {$serendipity['dbPrefix']}plugins "; + $where = array(); + + $where[] = "(name LIKE '@" . serendipity_db_escape_string($plugin_name) . "%' OR name LIKE '" . serendipity_db_escape_string($plugin_name) . "%') "; + $where[] = "authorid='" . serendipity_db_escape_string($authorid) . "' "; + + if ($ignore_hidden) $where[] = "NOT ( placement = 'hidden' OR placement = 'eventh') "; + + if (count($where) > 0) { + $sql .= ' WHERE ' . implode(' AND ', $where); + } + + $rs = serendipity_db_query($sql,false,'assoc'); + $ids = array(); + + if (!empty($rs) & is_Array($rs)) { + foreach($rs as $line) { + $ex = explode(':',$line['name']); + $ids[] = $ex[1]; + } + return $ids; + } else { + return null; + } + + } + /** * Probe for a language include with constants. Still include defines later on, if some constants were missing diff --git a/plugins/serendipity_event_entryproperties/ChangeLog b/plugins/serendipity_event_entryproperties/ChangeLog index 4a5b4fde..b031f145 100644 --- a/plugins/serendipity_event_entryproperties/ChangeLog +++ b/plugins/serendipity_event_entryproperties/ChangeLog @@ -1,3 +1,9 @@ +1.41.4: +------- + * removed 'WHERE' keyword from fetchentries event hook, because that should be handled + by the issuing sql + + 1.41.3: ------- * Add missing English language constant. diff --git a/plugins/serendipity_event_entryproperties/serendipity_event_entryproperties.php b/plugins/serendipity_event_entryproperties/serendipity_event_entryproperties.php index 2cda131f..2c6301fe 100644 --- a/plugins/serendipity_event_entryproperties/serendipity_event_entryproperties.php +++ b/plugins/serendipity_event_entryproperties/serendipity_event_entryproperties.php @@ -19,7 +19,7 @@ class serendipity_event_entryproperties extends serendipity_event $propbag->add('description', PLUGIN_EVENT_ENTRYPROPERTIES_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Garvin Hicking'); - $propbag->add('version', '1.41.3'); + $propbag->add('version', '1.41.4'); $propbag->add('requirements', array( 'serendipity' => '1.6', 'smarty' => '2.6.27', @@ -915,9 +915,7 @@ class serendipity_event_entryproperties extends serendipity_event if (count($conds) > 0) { $cond = implode(' AND ', $conds); - if (empty($eventData['and'])) { - $eventData['and'] = " WHERE $cond "; - } else { + if (!empty($eventData['and'])) { $eventData['and'] .= " AND $cond "; } } @@ -934,7 +932,7 @@ class serendipity_event_entryproperties extends serendipity_event $conds[] = 'ep_cache_body.value AS ep_cache_body,'; } - $cond = implode("\n", $conds); + $cond = implode("\n", $conds) . "\n"; if (empty($eventData['addkey'])) { $eventData['addkey'] = $cond; } else { diff --git a/plugins/serendipity_event_nl2br/serendipity_event_nl2br.php b/plugins/serendipity_event_nl2br/serendipity_event_nl2br.php index 239b8422..6b4e4b30 100644 --- a/plugins/serendipity_event_nl2br/serendipity_event_nl2br.php +++ b/plugins/serendipity_event_nl2br/serendipity_event_nl2br.php @@ -401,547 +401,547 @@ p.wl_notopbottom { } - /** ==================================== - * NL2P OPERATION - * ==================================== - */ + /** ==================================== + * NL2P OPERATION + * ==================================== + */ - // following w3.org, these elements close p elements automatically: - var $block_elements = array('table', - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'menu', 'section', - 'address', 'article', 'aside', 'fieldset', 'footer', - 'form', 'header', 'hgroup', 'hr', 'main', 'nav', 'p' - ); + // following w3.org, these elements close p elements automatically: + var $block_elements = array('table', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'menu', 'section', + 'address', 'article', 'aside', 'fieldset', 'footer', + 'form', 'header', 'hgroup', 'hr', 'main', 'nav', 'p' + ); - var $nested_block_elements = array('div','table','blockquote','ul','ol','dl'); - - var $singleton_block_elements = array('hr'); + var $nested_block_elements = array('div','table','blockquote','ul','ol','dl'); + + var $singleton_block_elements = array('hr'); - var $isolation_block_elements = array('pre','textarea'); + var $isolation_block_elements = array('pre','textarea'); - var $isolation_inline_elements = array('svg','style'); + var $isolation_inline_elements = array('svg','style'); - var $ignored_elements = array('area', 'br', 'col', 'command', 'embed', - 'img', 'input', 'keygen', 'link', 'param', 'source', - 'track', 'wbr', '!--', 'iframe', - 'li','tr','th','col','colgroup', - 'thead', 'tbody', 'tfoot', 'caption', 'ins','del', - 'video','audio','title','desc','path','circle', - 'ellipse', 'rect', 'line', 'polyline', 'polygon', 'text', - 'image', 'g', 'defs'); //includes svg tags + var $ignored_elements = array('area', 'br', 'col', 'command', 'embed', + 'img', 'input', 'keygen', 'link', 'param', 'source', + 'track', 'wbr', '!--', 'iframe', + 'li','tr','th','col','colgroup', + 'thead', 'tbody', 'tfoot', 'caption', 'ins','del', + 'video','audio','title','desc','path','circle', + 'ellipse', 'rect', 'line', 'polyline', 'polygon', 'text', + 'image', 'g', 'defs'); //includes svg tags - //paragraphs aren't allowed in these inline elements -> p closes these elements: - var $inline_elements = array('b', 'big', 'i', 'small', 'tt', 'abbr', - 'acronym', 'cite', 'code', 'dfn', 'em', 'kbd', 'strong', - 'samp', 'var', 'a', 'bdo', 'bdi', 'map', 'object', - 'q', 'script', 'span', 'sub', 'sup', 'button', - 'label', 'select', 'textarea', 's', 'strike' - ); + //paragraphs aren't allowed in these inline elements -> p closes these elements: + var $inline_elements = array('b', 'big', 'i', 'small', 'tt', 'abbr', + 'acronym', 'cite', 'code', 'dfn', 'em', 'kbd', 'strong', + 'samp', 'var', 'a', 'bdo', 'bdi', 'map', 'object', + 'q', 'script', 'span', 'sub', 'sup', 'button', + 'label', 'select', 'textarea', 's', 'strike' + ); - var $allowed_p_parents = array('blockquote', 'td', 'div', 'article', 'aside', 'dd', - 'details', 'dl', 'dt', 'footer', 'header', 'summary' - ); + var $allowed_p_parents = array('blockquote', 'td', 'div', 'article', 'aside', 'dd', + 'details', 'dl', 'dt', 'footer', 'header', 'summary' + ); - const P_END = '

'; - const P = '

'; - const P_NOTOP = '

'; - const P_NOBOTTOM = '

'; - const P_NOTOPBOTTOM = '

'; + const P_END = '

'; + const P = '

'; + const P_NOTOP = '

'; + const P_NOBOTTOM = '

'; + const P_NOTOPBOTTOM = '

'; - function nl2p($text) - { - //homogenize tags - $text = $this->tag_clean($text); - - //delete isolation tags from other arrays - if ($this->isolationtags) - { - $this->block_elements = array_diff($this->block_elements,$this->isolationtags); - $this->allowed_p_parents = array_diff($this->allowed_p_parents,$this->isolationtags); - $this->nested_block_elements = array_diff($this->nested_block_elements,$this->isolationtags); - $this->inline_elements = array_diff($this->inline_elements,$this->isolationtags); - $this->singleton_block_elements = array_diff($this->singleton_block_elements,$this->isolationtags); - $this->ignored_elements = array_diff($this->ignored_elements,$this->isolationtags); - $this->isolation_block_elements = array_diff($this->isolation_block_elements,$this->isolationtags); - } - if (empty($text)) { return ''; } - return $this->blocktag_nl2p($text); - } + function nl2p($text) + { + //homogenize tags + $text = $this->tag_clean($text); + + //delete isolation tags from other arrays + if ($this->isolationtags) + { + $this->block_elements = array_diff($this->block_elements,$this->isolationtags); + $this->allowed_p_parents = array_diff($this->allowed_p_parents,$this->isolationtags); + $this->nested_block_elements = array_diff($this->nested_block_elements,$this->isolationtags); + $this->inline_elements = array_diff($this->inline_elements,$this->isolationtags); + $this->singleton_block_elements = array_diff($this->singleton_block_elements,$this->isolationtags); + $this->ignored_elements = array_diff($this->ignored_elements,$this->isolationtags); + $this->isolation_block_elements = array_diff($this->isolation_block_elements,$this->isolationtags); + } + if (empty($text)) { return ''; } + return $this->blocktag_nl2p($text); + } - /** Make sure that all the tags are in lowercase - * purge all \n from inside tags - * remove spaces in endtags - * replace < > with < $gt; for non-tags - * tags are split in three parts: - * tagstart - '<' character - * tagdef - type of tag like 'img' - * style - following content after a space - * isolation by quotes in the style part - * @param string text - * @return text - */ - function tag_clean($textstring) - { - $text = str_split($textstring); - $tagstart = false; - $tagstart_b = false; - $tagdef = false; - $endtag = false; - $tagstyle = false; - $singlequote = false; - $doublequote = false; + /** Make sure that all the tags are in lowercase + * purge all \n from inside tags + * remove spaces in endtags + * replace < > with < $gt; for non-tags + * tags are split in three parts: + * tagstart - '<' character + * tagdef - type of tag like 'img' + * style - following content after a space + * isolation by quotes in the style part + * @param string text + * @return text + */ + function tag_clean($textstring) + { + $text = str_split($textstring); + $tagstart = false; + $tagstart_b = false; + $tagdef = false; + $endtag = false; + $tagstyle = false; + $singlequote = false; + $doublequote = false; - for ($i = 0; $i < count($text); $i++) - { - // start tag without closing tag - if ($text[$i] == '<' && !strpos($textstring,'>',$i+1) ) - { $text[$i] = '<'; } - // end tag without previous start, definition or style section - elseif ($text[$i] == '>' && !($tagstart !== false || $tagdef || $tagstyle) ) - { $text[$i] = '>'; } - // start tag inside quotes - elseif ( $text[$i] == '<' && ($singlequote || $doublequote) ) - { $text[$i] = '<'; } - // end tag inside quotes - elseif ( $text[$i] == '>' && ($singlequote || $doublequote) ) - { $text[$i] = '>'; } - // start tag inside tag - elseif ($text[$i] == '<' && $tagstart !== false ) - { $text[$i] = '<'; } - // real start tag - elseif ($text[$i] == '<' ) - { $tagstart = $i; } - // space after the start - not allowed in html - elseif ($text[$i] == ' ' && $tagstart !== false ) - { - $text[$tagstart] = '<'; - $tagstart = false; - } - // < > without content - elseif ($text[$i] == '>' && $tagstart !== false ) - { - $text[$tagstart] = '<'; - $text[$i] = '>'; - } - // first space or closing tag in definition part - elseif ( ($text[$i] == ' ' || $text[$i] == '>') && $tagdef) - { - //check if it is a real tag - $tag = substr($textstring,$tagdef,$i-$tagdef); - - if ( !(in_array($tag,$this->block_elements) - || in_array($tag,$this->singleton_block_elements) - || in_array($tag,$this->inline_elements) - || in_array($tag,$this->allowed_p_parents) - || in_array($tag,$this->isolation_block_elements) - || in_array($tag,$this->isolation_inline_elements) - || in_array($tag,$this->nested_block_elements) - || in_array($tag,$this->ignored_elements) - || in_array($tag,$this->isolationtags) ) ) - { - // unknown tag definition - $text[$tagstart_b] = '<'; - $tagstart = false; - $tagdef = false; - if ( $text[$i] == '>' ) { $text[$i] = '>'; } - } else - { - //convert to lowercase - for ($j = $tagdef; $j <= $i; $j++) - { - $text[$j] = strtolower($text[$j]); - } - $tagdef = false; - // closing > - if ($text[$i] == '>') - { - $tagstart = false; - $tagstyle = false; - $endtag = false; - } - // start of style part - else - { - $tagstyle = true; - } - } - } - // endtag starting with - elseif ($text[$i] == ' ' && $endtag) - { $text[$i] = ''; } - // remove newline in tags - elseif (($tagstart !== false || $tagdef || $tagstyle) && $text[$i] == "\n") - { $text[$i] = ''; } - // closing > after style part - elseif ($text[$i] == '>' && $tagstyle && !($singlequote || $doublequote) ) - { - $tagstart = false; - $tagdef = false; - $tagstyle = false; - $endtag = false; - } - // first definition character after < - elseif ($tagstart !== false && !($tagdef || $tagstyle) ) - { - $tagdef = $i; - $tagstart_b = $tagstart; - $tagstart = false; - } - // quotes in style - isolate - elseif ($tagstyle && $text[$i] == '\'' && !$doublequote ) - { - if ($singlequote) - { $singlequote = false; } - else - { $singlequote = true; } - } - elseif ($tagstyle && $text[$i] == '"' && !$singlequote ) - { - if ($doublequote) - { $doublequote = false; } - else - { $doublequote = true; } - } - } - return implode($text); - } + for ($i = 0; $i < count($text); $i++) + { + // start tag without closing tag + if ($text[$i] == '<' && !strpos($textstring,'>',$i+1) ) + { $text[$i] = '<'; } + // end tag without previous start, definition or style section + elseif ($text[$i] == '>' && !($tagstart !== false || $tagdef || $tagstyle) ) + { $text[$i] = '>'; } + // start tag inside quotes + elseif ( $text[$i] == '<' && ($singlequote || $doublequote) ) + { $text[$i] = '<'; } + // end tag inside quotes + elseif ( $text[$i] == '>' && ($singlequote || $doublequote) ) + { $text[$i] = '>'; } + // start tag inside tag + elseif ($text[$i] == '<' && $tagstart !== false ) + { $text[$i] = '<'; } + // real start tag + elseif ($text[$i] == '<' ) + { $tagstart = $i; } + // space after the start - not allowed in html + elseif ($text[$i] == ' ' && $tagstart !== false ) + { + $text[$tagstart] = '<'; + $tagstart = false; + } + // < > without content + elseif ($text[$i] == '>' && $tagstart !== false ) + { + $text[$tagstart] = '<'; + $text[$i] = '>'; + } + // first space or closing tag in definition part + elseif ( ($text[$i] == ' ' || $text[$i] == '>') && $tagdef) + { + //check if it is a real tag + $tag = substr($textstring,$tagdef,$i-$tagdef); + + if ( !(in_array($tag,$this->block_elements) + || in_array($tag,$this->singleton_block_elements) + || in_array($tag,$this->inline_elements) + || in_array($tag,$this->allowed_p_parents) + || in_array($tag,$this->isolation_block_elements) + || in_array($tag,$this->isolation_inline_elements) + || in_array($tag,$this->nested_block_elements) + || in_array($tag,$this->ignored_elements) + || in_array($tag,$this->isolationtags) ) ) + { + // unknown tag definition + $text[$tagstart_b] = '<'; + $tagstart = false; + $tagdef = false; + if ( $text[$i] == '>' ) { $text[$i] = '>'; } + } else + { + //convert to lowercase + for ($j = $tagdef; $j <= $i; $j++) + { + $text[$j] = strtolower($text[$j]); + } + $tagdef = false; + // closing > + if ($text[$i] == '>') + { + $tagstart = false; + $tagstyle = false; + $endtag = false; + } + // start of style part + else + { + $tagstyle = true; + } + } + } + // endtag starting with + elseif ($text[$i] == ' ' && $endtag) + { $text[$i] = ''; } + // remove newline in tags + elseif (($tagstart !== false || $tagdef || $tagstyle) && $text[$i] == "\n") + { $text[$i] = ''; } + // closing > after style part + elseif ($text[$i] == '>' && $tagstyle && !($singlequote || $doublequote) ) + { + $tagstart = false; + $tagdef = false; + $tagstyle = false; + $endtag = false; + } + // first definition character after < + elseif ($tagstart !== false && !($tagdef || $tagstyle) ) + { + $tagdef = $i; + $tagstart_b = $tagstart; + $tagstart = false; + } + // quotes in style - isolate + elseif ($tagstyle && $text[$i] == '\'' && !$doublequote ) + { + if ($singlequote) + { $singlequote = false; } + else + { $singlequote = true; } + } + elseif ($tagstyle && $text[$i] == '"' && !$singlequote ) + { + if ($doublequote) + { $doublequote = false; } + else + { $doublequote = true; } + } + } + return implode($text); + } - /* - * sophisticated nl to p - blocktag stage - * handles content with blocktags, apply nl2p to the block elements if tag allows it - * works also for ommitted closing tags - * @param: text - * return string - */ - function blocktag_nl2p($text) - { - //explode string into array of tags and contents - $textarray = $this->explode_along_tags($text); - $content = ""; - $start = 0; - $tagstack = array(); - $isolation_flag = false; + /* + * sophisticated nl to p - blocktag stage + * handles content with blocktags, apply nl2p to the block elements if tag allows it + * works also for ommitted closing tags + * @param: text + * return string + */ + function blocktag_nl2p($text) + { + //explode string into array of tags and contents + $textarray = $this->explode_along_tags($text); + $content = ""; + $start = 0; + $tagstack = array(); + $isolation_flag = false; if (! is_array($textarray)) { return $text; } - for ($i=0; $i < count($textarray); $i++) - { + for ($i=0; $i < count($textarray); $i++) + { - //get tag or false if none - $tag = $this->extract_tag($textarray[$i]); + //get tag or false if none + $tag = $this->extract_tag($textarray[$i]); - //new blocktag - e.g. - if ($tag && $this->is_starttag($textarray[$i]) - && (in_array($tag, $this->block_elements) || in_array($tag, $this->nested_block_elements) )) - { - //merge previous content, apply nl2p if needed and concatenate - if (!$isolation_flag && ( empty($tagstack) || in_array($tagstack[0], $this->allowed_p_parents) )) - { - $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; - } else - { - $content .= implode(array_slice($textarray,$start,$i-$start)); - } - // clear stack of block elements and insert - if (in_array($tag, $this->block_elements) ) - { - $tagstack = array_diff($tagstack, $this->block_elements); - } - // concatenate tag - $content .= $textarray[$i]; - - if (!in_array($tag, $this->singleton_block_elements) ) - { - array_unshift($tagstack, $tag); - } - $start = $i+1; - } - //new tag which can contain paragraphs and can be inside a blocktag - e.g. - elseif($tag && !$this->is_starttag($textarray[$i]) && !empty($tagstack) && $tag == $tagstack[0]) - { - //content, apply nl2p if needed - if ($i != $start) - { - if (!$isolation_flag && in_array($tagstack[0], $this->allowed_p_parents) ) - { - $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; - } else - { - $content .= implode(array_slice($textarray,$start,$i-$start)); - } - } - //closing tag - $content .= $textarray[$i]; + // concatenate tag if it's standard html + if (in_array($tag, $this->isolation_block_elements) ) + { + $content .= $textarray[$i]; + } + + $isolation_flag = $tag; //isolation has to be started and ended with the same tag + $start = $i+1; + } + //closing isolation tag + elseif($tag && !$this->is_starttag($textarray[$i]) && $tag == $isolation_flag ) + { + //content, no nl2p + $content .= implode(array_slice($textarray,$start,$i-$start)); + $isolation_flag = false; + $start = $i+1; + // concatenate closing tag if it's standard html + if (in_array($tag, $this->isolation_block_elements) ) + { + $content .= $textarray[$i]; + } + } + //closing blocktag or p parent - e.g.
- elseif ($tag && $this->is_starttag($textarray[$i]) && in_array($tag, $this->allowed_p_parents)) - { - //merge previous content, apply nl2p if needed and concatenate - if (!$isolation_flag && ( empty($tagstack) || in_array($tagstack[0], $this->allowed_p_parents) )) - { - $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; - } else - { - $content .= implode(array_slice($textarray,$start,$i-$start)); - } - //insert tag into the stack and concatenate - array_unshift($tagstack, $tag); - $content .= $textarray[$i]; - $start = $i+1; - } - //isolation tag - elseif($tag && !$isolation_flag && $this->is_starttag($textarray[$i]) - && (in_array($tag, $this->isolation_block_elements) || in_array($tag, $this->isolationtags) ) ) - { - //merge previous content, apply nl2p if needed and concatenate - if (empty($tagstack) ) - { - $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; - } elseif (in_array($tagstack[0], $this->allowed_p_parents) ) - { - $content .= $textarray[$start] - . $this->nl2pblock(implode(array_slice($textarray,$start+1,$i-$start-1))) . "\n"; - } else - { - $content .= implode(array_slice($textarray,$start,$i-$start)); - } + //new blocktag - e.g. + if ($tag && $this->is_starttag($textarray[$i]) + && (in_array($tag, $this->block_elements) || in_array($tag, $this->nested_block_elements) )) + { + //merge previous content, apply nl2p if needed and concatenate + if (!$isolation_flag && ( empty($tagstack) || in_array($tagstack[0], $this->allowed_p_parents) )) + { + $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; + } else + { + $content .= implode(array_slice($textarray,$start,$i-$start)); + } + // clear stack of block elements and insert + if (in_array($tag, $this->block_elements) ) + { + $tagstack = array_diff($tagstack, $this->block_elements); + } + // concatenate tag + $content .= $textarray[$i]; + + if (!in_array($tag, $this->singleton_block_elements) ) + { + array_unshift($tagstack, $tag); + } + $start = $i+1; + } + //new tag which can contain paragraphs and can be inside a blocktag - e.g.
+ elseif ($tag && $this->is_starttag($textarray[$i]) && in_array($tag, $this->allowed_p_parents)) + { + //merge previous content, apply nl2p if needed and concatenate + if (!$isolation_flag && ( empty($tagstack) || in_array($tagstack[0], $this->allowed_p_parents) )) + { + $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; + } else + { + $content .= implode(array_slice($textarray,$start,$i-$start)); + } + //insert tag into the stack and concatenate + array_unshift($tagstack, $tag); + $content .= $textarray[$i]; + $start = $i+1; + } + //isolation tag + elseif($tag && !$isolation_flag && $this->is_starttag($textarray[$i]) + && (in_array($tag, $this->isolation_block_elements) || in_array($tag, $this->isolationtags) ) ) + { + //merge previous content, apply nl2p if needed and concatenate + if (empty($tagstack) ) + { + $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; + } elseif (in_array($tagstack[0], $this->allowed_p_parents) ) + { + $content .= $textarray[$start] + . $this->nl2pblock(implode(array_slice($textarray,$start+1,$i-$start-1))) . "\n"; + } else + { + $content .= implode(array_slice($textarray,$start,$i-$start)); + } - // concatenate tag if it's standard html - if (in_array($tag, $this->isolation_block_elements) ) - { - $content .= $textarray[$i]; - } - - $isolation_flag = $tag; //isolation has to be started and ended with the same tag - $start = $i+1; - } - //closing isolation tag - elseif($tag && !$this->is_starttag($textarray[$i]) && $tag == $isolation_flag ) - { - //content, no nl2p - $content .= implode(array_slice($textarray,$start,$i-$start)); - $isolation_flag = false; - $start = $i+1; - // concatenate closing tag if it's standard html - if (in_array($tag, $this->isolation_block_elements) ) - { - $content .= $textarray[$i]; - } - } - //closing blocktag or p parent - e.g.
or
or + elseif($tag && !$this->is_starttag($textarray[$i]) && !empty($tagstack) && $tag == $tagstack[0]) + { + //content, apply nl2p if needed + if ($i != $start) + { + if (!$isolation_flag && in_array($tagstack[0], $this->allowed_p_parents) ) + { + $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; + } else + { + $content .= implode(array_slice($textarray,$start,$i-$start)); + } + } + //closing tag + $content .= $textarray[$i]; - $start = $i+1; - array_shift($tagstack); - } - } + $start = $i+1; + array_shift($tagstack); + } + } - //merge remainder - if (!$isolation_flag && ( empty($tagstack) || in_array($tagstack[0], $this->allowed_p_parents) )) - { - $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; - } else - { - $content .= implode(array_slice($textarray,$start,$i-$start)); - } - return $content; - } + //merge remainder + if (!$isolation_flag && ( empty($tagstack) || in_array($tagstack[0], $this->allowed_p_parents) )) + { + $content .= $this->nl2pblock(implode(array_slice($textarray,$start,$i-$start))) . "\n"; + } else + { + $content .= implode(array_slice($textarray,$start,$i-$start)); + } + return $content; + } - /* - * sophisticated nl to p for content which is already - * purged from block elements by blocktag_nl2p - * explode content along tags - * build stack of active tags - * isolate content inside isolation tags or - * explode along newlines - * single breaks converted to
- * build every paragraph: p class | reopen active tags | content ... | new open tags | closing p tag - * class depends on framing newlines: - * Insert P_NOBOTTOM class at last paragraph if no newline is following - * Insert P_NOTOP class at the first paragraph if is not starting with a nl - * Insert P_NOTOPBOTTOM class if it is just one paragraph - * normal P for everything else (default CSS has margin top,bottom) - * @param string text - * @return string - */ - function nl2pblock($textstring) - { + /* + * sophisticated nl to p for content which is already + * purged from block elements by blocktag_nl2p + * explode content along tags + * build stack of active tags + * isolate content inside isolation tags or + * explode along newlines + * single breaks converted to
+ * build every paragraph: p class | reopen active tags | content ... | new open tags | closing p tag + * class depends on framing newlines: + * Insert P_NOBOTTOM class at last paragraph if no newline is following + * Insert P_NOTOP class at the first paragraph if is not starting with a nl + * Insert P_NOTOPBOTTOM class if it is just one paragraph + * normal P for everything else (default CSS has margin top,bottom) + * @param string text + * @return string + */ + function nl2pblock($textstring) + { - //check for empty content - if (empty(trim($textstring))) { return $textstring; } + //check for empty content + if (empty(trim($textstring))) { return $textstring; } - //check for start/end newlines - $startnl = ( strspn($textstring,"\n") ) ? true : false; - $endnl = ( strspn($textstring,"\n",-1 ) ) ? true : false; - $firstp = true; - $textstring = trim($textstring,"\n"); - if (empty($textstring)) { return ''; } + //check for start/end newlines + $startnl = ( strspn($textstring,"\n") ) ? true : false; + $endnl = ( strspn($textstring,"\n",-1 ) ) ? true : false; + $firstp = true; + $textstring = trim($textstring,"\n"); + if (empty($textstring)) { return ''; } - $tagexplode = array(); + $tagexplode = array(); - //explode in tags and content - $tagexplode = $this->explode_along_tags($textstring); - $tagstack = array(); + //explode in tags and content + $tagexplode = $this->explode_along_tags($textstring); + $tagstack = array(); - $textline = array(); - $buffer = ''; - $bufferhastext = false; - $content = ''; - $tag = false; - $isolation_tag = false; + $textline = array(); + $buffer = ''; + $bufferhastext = false; + $content = ''; + $tag = false; + $isolation_tag = false; - //first stage: explode in tags - for($i=0; $iextract_tag($tagexplode[$i]); - // start isolation - if ($tag && $this->is_starttag($tagexplode[$i]) && in_array($tag,$this->isolation_inline_elements)) - { - $isolation_tag = $tag; - } - // end isolation - elseif ($tag && !$this->is_starttag($tagexplode[$i]) && $tag == $isolation_tag) - { - $isolation_tag = false; - } - // put inlinetag to stack - elseif ($tag && !$isolation_tag && $this->is_starttag($tagexplode[$i]) && in_array($tag,$this->inline_elements) ) - { - array_unshift($tagstack, $tagexplode[$i]); - } - // remove inlinetag from stack - elseif ($tag && !$isolation_tag && !$this->is_starttag($tagexplode[$i]) && !empty($tagstack) && $tag == $this->extract_tag($tagstack[0])) - { - array_shift($tagstack); - } + //first stage: explode in tags + for($i=0; $iextract_tag($tagexplode[$i]); + // start isolation + if ($tag && $this->is_starttag($tagexplode[$i]) && in_array($tag,$this->isolation_inline_elements)) + { + $isolation_tag = $tag; + } + // end isolation + elseif ($tag && !$this->is_starttag($tagexplode[$i]) && $tag == $isolation_tag) + { + $isolation_tag = false; + } + // put inlinetag to stack + elseif ($tag && !$isolation_tag && $this->is_starttag($tagexplode[$i]) && in_array($tag,$this->inline_elements) ) + { + array_unshift($tagstack, $tagexplode[$i]); + } + // remove inlinetag from stack + elseif ($tag && !$isolation_tag && !$this->is_starttag($tagexplode[$i]) && !empty($tagstack) && $tag == $this->extract_tag($tagstack[0])) + { + array_shift($tagstack); + } - // put isolated content into buffer - if ($isolation_tag || $tag) - { - $buffer .= $tagexplode[$i]; - } - // explode content in textlines - else - { - $textline = explode("\n",$tagexplode[$i]); + // put isolated content into buffer + if ($isolation_tag || $tag) + { + $buffer .= $tagexplode[$i]; + } + // explode content in textlines + else + { + $textline = explode("\n",$tagexplode[$i]); - //iterate through the paragraphs and build content - for ($j=0; $jhtml_end_tag($this->extract_tag($ins_tag)); } + //close open tags + foreach($tagstack as $ins_tag) { $content .= $this->html_end_tag($this->extract_tag($ins_tag)); } - //paragraph closing tag - $content .= self::P_END . "\n"; + //paragraph closing tag + $content .= self::P_END . "\n"; - //put closed tags into buffer - foreach($tagstack as $ins_tag) { $buffer .= $ins_tag; } + //put closed tags into buffer + foreach($tagstack as $ins_tag) { $buffer .= $ins_tag; } - //skip newline - $j += 1; - } - elseif ($j < count($textline) - 1) // single break - { - $buffer .= $textline[$j] . "
\n"; - $bufferhastext = true; - } - else // last line - { - // append textline - $buffer .= $textline[$j]; - $bufferhastext = true; - } - } - } - } + //skip newline + $j += 1; + } + elseif ($j < count($textline) - 1) // single break + { + $buffer .= $textline[$j] . "
\n"; + $bufferhastext = true; + } + else // last line + { + // append textline + $buffer .= $textline[$j]; + $bufferhastext = true; + } + } + } + } - // handle last paragraph - if (!$bufferhastext) { $content .= $buffer; } - else - { - if ($firstp && !$startnl && !$endnl ) { $content .= self::P_NOTOPBOTTOM; } - elseif ($firstp && !$startnl) { $content .= self::P_NOTOP; } - elseif (!$endnl) { $content .= self::P_NOBOTTOM; } - else { $content .= self::P; } - $content .= $buffer; - foreach($tagstack as $ins_tag) { $content .= $this->html_end_tag($this->extract_tag($ins_tag)); } - $content .= self::P_END; - } + // handle last paragraph + if (!$bufferhastext) { $content .= $buffer; } + else + { + if ($firstp && !$startnl && !$endnl ) { $content .= self::P_NOTOPBOTTOM; } + elseif ($firstp && !$startnl) { $content .= self::P_NOTOP; } + elseif (!$endnl) { $content .= self::P_NOBOTTOM; } + else { $content .= self::P; } + $content .= $buffer; + foreach($tagstack as $ins_tag) { $content .= $this->html_end_tag($this->extract_tag($ins_tag)); } + $content .= self::P_END; + } - return $content; - } + return $content; + } - /** explode textstring into array of substrings - * array element can be tag or content - * @param text - * $return array of tags and contents - */ - function explode_along_tags($text) - { - $startpos = 0; - $endpos = 0; - $textarray = array(); - do - { - //find tag start - $endpos = strpos($text,'<',$startpos); - if ($endpos === false) - { - //no more tags, copy remainder to array - $endpos = strlen($text); - if ($endpos - $startpos > 0) - { $textarray[] = substr($text,$startpos,$endpos - $startpos); } - return $textarray; - } - elseif (($endpos - $startpos) > 0) - { - //copy preliminary text to array - $textarray[] = substr($text,$startpos,$endpos - $startpos); - } - $startpos = $endpos; - //find tag end - $endpos = strpos($text,'>',$startpos); - if ($endpos === false) { return false; } - elseif (($endpos - $startpos) > 1) - { - //copy tag to array - $textarray[] = substr($text,$startpos,$endpos - $startpos + 1); - $startpos = $endpos + 1; - } - else { return false; } - } while (1); - return false; - } + /** explode textstring into array of substrings + * array element can be tag or content + * @param text + * $return array of tags and contents + */ + function explode_along_tags($text) + { + $startpos = 0; + $endpos = 0; + $textarray = array(); + do + { + //find tag start + $endpos = strpos($text,'<',$startpos); + if ($endpos === false) + { + //no more tags, copy remainder to array + $endpos = strlen($text); + if ($endpos - $startpos > 0) + { $textarray[] = substr($text,$startpos,$endpos - $startpos); } + return $textarray; + } + elseif (($endpos - $startpos) > 0) + { + //copy preliminary text to array + $textarray[] = substr($text,$startpos,$endpos - $startpos); + } + $startpos = $endpos; + //find tag end + $endpos = strpos($text,'>',$startpos); + if ($endpos === false) { return false; } + elseif (($endpos - $startpos) > 1) + { + //copy tag to array + $textarray[] = substr($text,$startpos,$endpos - $startpos + 1); + $startpos = $endpos + 1; + } + else { return false; } + } while (1); + return false; + } - function extract_tag($text) - { - if ($text[0] != '<') { return false; } - $n = strcspn($text,' >'); - return ltrim(substr($text,0,$n),''); + return ltrim(substr($text,0,$n),''; } - function html_start_tag($text) { return '<' . $text . '>'; } - function is_starttag($text) { return ($text[1] == "/") ? false : true; } + function html_end_tag($text) { return ''; } + function html_start_tag($text) { return '<' . $text . '>'; } + function is_starttag($text) { return ($text[1] == "/") ? false : true; } } diff --git a/plugins/serendipity_event_spartacus/ChangeLog b/plugins/serendipity_event_spartacus/ChangeLog index 70c1760e..c4c4b194 100644 --- a/plugins/serendipity_event_spartacus/ChangeLog +++ b/plugins/serendipity_event_spartacus/ChangeLog @@ -1,3 +1,8 @@ +2.38.2 +------- + * Fix a call to NULL if no connection to the repositiory could + be archieved. + 2.38.1: ------- * Fix count_plugin_upgrades(): diff --git a/plugins/serendipity_event_spartacus/serendipity_event_spartacus.php b/plugins/serendipity_event_spartacus/serendipity_event_spartacus.php index d0f99846..bf560291 100644 --- a/plugins/serendipity_event_spartacus/serendipity_event_spartacus.php +++ b/plugins/serendipity_event_spartacus/serendipity_event_spartacus.php @@ -27,7 +27,7 @@ class serendipity_event_spartacus extends serendipity_event $propbag->add('description', PLUGIN_EVENT_SPARTACUS_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Garvin Hicking'); - $propbag->add('version', '2.38.1'); + $propbag->add('version', '2.38.2'); $propbag->add('requirements', array( 'serendipity' => '1.6', )); @@ -457,7 +457,7 @@ class serendipity_event_spartacus extends serendipity_event $resolved_url = $url . ' (IP ' . $url_ip . ')'; $this->outputMSG('error', sprintf(PLUGIN_EVENT_SPARTACUS_FETCHERROR, $resolved_url)); //--JAM: START FIREWALL DETECTION - if ($response->getStatus()) { + if ((isset($response) && $response->getStatus())) { $this->outputMSG('error', sprintf(PLUGIN_EVENT_SPARTACUS_REPOSITORY_ERROR, $response->getStatus())); } $check_health = true; diff --git a/plugins/serendipity_plugin_categories/ChangeLog b/plugins/serendipity_plugin_categories/ChangeLog new file mode 100644 index 00000000..04154401 --- /dev/null +++ b/plugins/serendipity_plugin_categories/ChangeLog @@ -0,0 +1,2 @@ +2.05.2 + * Strip the translation tags in the category links if multilingual plugin is active diff --git a/plugins/serendipity_plugin_categories/serendipity_plugin_categories.php b/plugins/serendipity_plugin_categories/serendipity_plugin_categories.php index 69fa0dcc..80167d5d 100644 --- a/plugins/serendipity_plugin_categories/serendipity_plugin_categories.php +++ b/plugins/serendipity_plugin_categories/serendipity_plugin_categories.php @@ -15,7 +15,7 @@ class serendipity_plugin_categories extends serendipity_plugin $propbag->add('description', CATEGORY_PLUGIN_DESC); $propbag->add('stackable', true); $propbag->add('author', 'Serendipity Team'); - $propbag->add('version', '2.05.2'); + $propbag->add('version', '2.05.3'); $propbag->add('configuration', array('title', 'authorid', 'parent_base', 'hide_parent', 'image', 'sort_order', 'sort_method', 'allow_select', 'hide_parallel', 'show_count', 'show_all', 'smarty')); $propbag->add('groups', array('FRONTEND_VIEWS')); } @@ -255,6 +255,9 @@ class serendipity_plugin_categories extends serendipity_plugin } } + // strip language tags if multilingual plugin is active + serendipity_plugin_api::hook_event('multilingual_strip_langs',$cat['category_name']); + $categories[$cid]['feedCategoryURL'] = serendipity_feedCategoryURL($cat, 'serendipityHTTPPath'); $categories[$cid]['categoryURL'] = serendipity_categoryURL($cat, 'serendipityHTTPPath'); $categories[$cid]['paddingPx'] = $cat['depth']*6; diff --git a/plugins/serendipity_plugin_recententries/ChangeLog b/plugins/serendipity_plugin_recententries/ChangeLog new file mode 100644 index 00000000..3f279bc8 --- /dev/null +++ b/plugins/serendipity_plugin_recententries/ChangeLog @@ -0,0 +1,4 @@ +2.7 + * using the sql condition set aquired by event_hook::'frontend_fetchentries' + to get the multilingual data set + * $this->title (= title in backend) set to plugin name diff --git a/plugins/serendipity_plugin_recententries/serendipity_plugin_recententries.php b/plugins/serendipity_plugin_recententries/serendipity_plugin_recententries.php index eada5e92..63aec499 100644 --- a/plugins/serendipity_plugin_recententries/serendipity_plugin_recententries.php +++ b/plugins/serendipity_plugin_recententries/serendipity_plugin_recententries.php @@ -15,13 +15,11 @@ class serendipity_plugin_recententries extends serendipity_plugin function introspect(&$propbag) { - $this->title = $this->get_config('title', $this->title); - $propbag->add('name', PLUGIN_RECENTENTRIES_TITLE); $propbag->add('description', PLUGIN_RECENTENTRIES_BLAHBLAH); $propbag->add('stackable', true); $propbag->add('author', 'Christian Machmeier, Christian Brabandt, Judebert, Don Chambers'); - $propbag->add('version', '2.6'); + $propbag->add('version', '2.7'); $propbag->add('requirements', array( 'serendipity' => '1.6', 'smarty' => '2.6.7', @@ -212,16 +210,16 @@ class serendipity_plugin_recententries extends serendipity_plugin $sql_condition['joins'] = ' LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'entrycat AS ec ON id = ec.entryid ' . $sql_condition['joins']; } + // get 'hide untranslated entries' option from multilingual plugin via SQL + serendipity_plugin_api::hook_event('frontend_fetchentries', $sql_condition, array('noSticky' => true)); + $sql_condition['addkey'] = rtrim($sql_condition['addkey'],",\n") . "\n"; + $entries_query = "SELECT DISTINCT id, title, timestamp, - epm.value AS multilingual_title + {$sql_condition['addkey']} FROM {$serendipity['dbPrefix']}entries AS e {$sql_condition['joins']} - - LEFT OUTER JOIN {$serendipity['dbPrefix']}entryproperties AS epm - ON (epm.entryid = e.id AND epm.property = 'multilingual_title_" . $serendipity['lang'] . "') - WHERE isdraft = 'false' {$sql_condition['and']} $sql_order $sql_number"; diff --git a/plugins/serendipity_plugin_superuser/serendipity_plugin_superuser.php b/plugins/serendipity_plugin_superuser/serendipity_plugin_superuser.php index 3d748bc8..af6327ea 100644 --- a/plugins/serendipity_plugin_superuser/serendipity_plugin_superuser.php +++ b/plugins/serendipity_plugin_superuser/serendipity_plugin_superuser.php @@ -14,7 +14,7 @@ class serendipity_plugin_superuser extends serendipity_plugin $propbag->add('description', ALLOWS_YOU_BLAHBLAH); $propbag->add('stackable', false); $propbag->add('author', 'Serendipity Team'); - $propbag->add('version', '1.1'); + $propbag->add('version', '1.1.1'); $propbag->add('configuration', array('https')); $propbag->add('groups', array('FRONTEND_FEATURES')); } @@ -46,7 +46,8 @@ class serendipity_plugin_superuser extends serendipity_plugin $base = $serendipity['serendipityHTTPPath']; } - $link = $base . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] .'?/' : '') . PATH_ADMIN; + //$link = $base . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] .'?/' : '') . PATH_ADMIN; + $link = $base . 'serendipity_admin.php'; $text = (($_SESSION['serendipityAuthedUser'] === true) ? SUPERUSER_OPEN_ADMIN : SUPERUSER_OPEN_LOGIN); echo ''. $text .''; }