viewgit/inc/functions.php:22 Function utf8_encode() is deprecated [8192]
diff --git a/src/configs/GroupWikiTool.php b/src/configs/GroupWikiTool.php index 7e102cb05..cf783bf04 100644 --- a/src/configs/GroupWikiTool.php +++ b/src/configs/GroupWikiTool.php @@ -122,11 +122,15 @@ switch ($argv[1]) { echo $usage; exit(); } - list(,, $type, $group_name, $locale_tag, $wiki_path,) = $argv; + if (empty($argv[6])) { + $argv[6] = ""; + } + list(,, $type, $group_name, $locale_tag, $wiki_path, + $from_base_url) = $argv; if ($type != "dokuwiki") { echo "Only importing from Dokuwiki's currently supported!\n"; } - importWiki($type, $group_name, $locale_tag, $wiki_path); + importWiki($type, $group_name, $locale_tag, $wiki_path, $from_base_url); break; case "path": if (empty($argv[4])) { @@ -179,7 +183,8 @@ switch ($argv[1]) { /** * */ -function importWiki($type, $group_name, $locale_tag, $wiki_path) +function importWiki($type, $group_name, $locale_tag, $wiki_path, + $from_base_url= "") { if ($type != 'dokuwiki') { echo "$type is an unknown wiki type\n"; @@ -207,18 +212,23 @@ function importWiki($type, $group_name, $locale_tag, $wiki_path) ["/(\A|\s)\_\_([$class_or_id]+)\_\_/su", '$1<u>$2<u>'], ["/(\A|\n)\s*\-/su", "$1#"], ["/(\A|\n)\s*\*/u", "$1*"], - ["/\[([^\|]+)\s+\|([^\]]+)\]/su", "[$1|$2]"], + ["/\[(\s*[^\|]+)\s+\|([^\]]+)\]/su", "[$1|$2]"], ["/\[([^\|]+)\|\s+([^\]]+)\]/su", "[$1|$2]"], - ["/\{\{\:?docs\:([^\|]+)\|([^\}\{]+)\}\}/su", - '((resource:$1|$2))'], - ["/\/\/$/u", "<br>\n"], + ["/\{\{\s*\:?([a-zA-z]*)(\:)([^\|]+)\|([^\}\{]+)\}\}/su", + '((resource-link:media:$3|$1|$4))'], + ['/\/\/$/', "<br>\n"], + ['/(\{|\[)\s+/', "$1"], + ['/\s+(\}|\])/', "$1"], + ['/(\A|\n)\s(\{|\[)/s', "$1$2"], + ['/(\A|\n)(\*+)\s+/s', "$1$2"], + ['/(\A|\n)(\#+)\s+/s', "$1$2"], ]; $internal_to_yioops = [ - ["/ZZH1ZZ\s*([$class_or_id]+)\s*ZZH1ZZ/su", '=$1='], - ["/ZZH2ZZ\s*([$class_or_id]+)\s*ZZH2ZZ/su", '==$1=='], - ["/ZZH3ZZ\s*([$class_or_id]+)\s*ZZH3ZZ/su", '===$1==='], - ["/ZZH4ZZ\s*([$class_or_id]+)\s*ZZH4ZZ/su", '====$1===='], - ["/ZZH5ZZ\s*([$class_or_id]+)\s*ZZH5ZZ/su", '=====$1====='], + ["/ZZH1ZZ\s*([$class_or_id]+)\s*ZZH1ZZ\s*/su", '\n=$1=\n'], + ["/ZZH2ZZ\s*([$class_or_id]+)\s*ZZH2ZZ\s*/su", '\n==$1==\n'], + ["/ZZH3ZZ\s*([$class_or_id]+)\s*ZZH3ZZ\s*/su", '\n===$1===\n'], + ["/ZZH4ZZ\s*([$class_or_id]+)\s*ZZH4ZZ\s*/su", '\n====$1====\n'], + ["/ZZH5ZZ\s*([$class_or_id]+)\s*ZZH5ZZ\s*/su", '\n=====$1=====\n'], ]; $doku_matches = []; $doku_replaces = []; @@ -231,33 +241,75 @@ function importWiki($type, $group_name, $locale_tag, $wiki_path) list($internal_matches[], $internal_replaces[]) = $internal_to_yioop; } $documents = glob("$wiki_path/attic/*.txt.gz"); - $has_main_page = false; - foreach ($documents as $pre_doc) { - if (preg_match('/\/Main\.([^\/\.]+)\.txt\.gz$/', $pre_doc)) { - $has_main_page = true; - break; - } - } + importWikiMedia(C\ROOT_ID, $group_id, $locale_tag, $wiki_path); + $first_start = true; + $old_original_page_name = ""; + $meta_info = []; foreach ($documents as $pre_doc) { $document = gzdecode(file_get_contents($pre_doc)); $document = preg_replace($doku_matches, $doku_replaces, $document); $document = preg_replace($internal_matches, $internal_replaces, $document); + if (!empty($from_base_url)) { + $quoted_url = preg_quote($from_base_url); + $document = preg_replace( + "@\[\[$quoted_url([^\:\|\]]+)id=([^\|\]]+)@", "[[$2", + $document); + $document = preg_replace("@\[\[$quoted_url([^\:\|\]]+)fetch\.php\?". + "media\=([a-zA-Z]+)\:([^\:\|\]]+)\:([^\|\]]+)\|([^\]]+)\]\]@", + '((resource-link:media:$4|$2/$3|$5))', + $document); + } $document = str_replace('\\n',"\n", $document); - $document = str_replace('\\\'',"'", $document); + $document = str_replace("'''","'''", $document); + $document = str_replace("''","''", $document); if (preg_match('/\/([^\/]+)\.([^\/\.]+)\.txt\.gz$/', $pre_doc, $matches)) { - list(, $page_name, $timestamp) = $matches; - if ($page_name == 'start' && !$has_main_page) { + list(, $original_page_name, $timestamp) = $matches; + if ($original_page_name != $old_original_page_name) { + $meta_path = "$wiki_path/meta/$original_page_name.changes"; + if (file_exists($meta_path)) { + $pre_meta_info = file($meta_path); + foreach ($pre_meta_info as $pre_meta_item) { + list($meta_timestamp, $meta_edit_reason) = + explode("\t", $pre_meta_item, 2); + $meta_edit_reason = " Dokuwiki import " . + preg_replace("/\s+/", " ", trim($meta_edit_reason)); + $meta_info[trim($meta_timestamp)] = $meta_edit_reason; + } + } + $old_original_page_name = $original_page_name; + } + $page_name = preg_replace('/^Main(\d*)$/', "DokuWikiMain$1", + $original_page_name); + $page_name = str_replace(" ", "_", $page_name); + if ($page_name == 'start') { $page_name = 'Main'; + if ($first_start) { + $first_start = false; + /* Main page is created by CreateDB with a too new timestamp + as compared to some doku wiki pages might be improting + */ + $page_id = $group_model->getPageId($group_id, $page_name, + $locale_tag); + if (intval($page_id) > 0) { + $db = $group_model->db; + $db->execute("DELETE FROM GROUP_PAGE + WHERE ID=$page_id"); + $db->execute("DELETE FROM GROUP_PAGE_HISTORY + WHERE PAGE_ID=$page_id"); + } + } } + $edit_reason = (empty($meta_info[$timestamp])) ? + "[Wiki Import on " . time(). " ]" : $meta_info[$timestamp]; $timestamp = intval($timestamp); if (!empty($timestamp) && !empty($page_name)) { echo "Inserting $page_name revision from ". date("Y-m-d H:i:s", $timestamp) ."\n!"; $group_model->setPageName(C\ROOT_ID, $group_id, $page_name, $document, - $locale_tag, "[Wiki Import on " . time(). " ]", + $locale_tag, $edit_reason, L\tl('social_component_page_created', $page_name), L\tl('social_component_page_discuss_here'), pubdate: $timestamp); @@ -268,3 +320,41 @@ function importWiki($type, $group_name, $locale_tag, $wiki_path) } } } +/** + * + */ +function importWikiMedia($user_id, $group_id, $locale_tag, $wiki_path, + $sub_path = "") +{ + $base_prefix = "$wiki_path/media/"; + $media_prefix = "$base_prefix$sub_path/"; + $media_paths = glob("$media_prefix*"); + $len_prefix = strlen($media_prefix); + $group_model = new GroupModel(); + if (!($page_id = $group_model->getPageId($group_id, "media", + $locale_tag))) { + $media_page = L\WikiParser::makeWikiPageHead( + ['page_type' => 'media_list']) . L\WikiParser::END_HEAD_VARS . + "media"; + $page_id = $group_model->setPageName($user_id, $group_id, "media", + $media_page, $locale_tag, "create", + L\tl('social_component_page_created', $media_page), + L\tl('social_component_page_discuss_here')); + } + foreach ($media_paths as $media_path) { + if (is_dir($media_path)) { + $sub_subpath = substr($media_path, strlen($base_prefix)); + $folders = $group_model->getGroupPageResourcesFolders($group_id, + $page_id, $sub_subpath, true); + echo "Importing $sub_subpath\n"; + importWikiMedia($user_id, $group_id, $locale_tag, $wiki_path, + $sub_subpath); + } else { + $file_name = substr($media_path, $len_prefix); + $mime_type = L\mimeType($file_name, true); + $data = file_get_contents($media_path); + $group_model->copyFileToGroupPageResource($media_path, $file_name, + $mime_type, $group_id, $page_id, $sub_path, $data); + } + } +} diff --git a/src/configs/TokenTool.php b/src/configs/TokenTool.php index b2eafaec5..bb3eb9c3e 100644 --- a/src/configs/TokenTool.php +++ b/src/configs/TokenTool.php @@ -960,7 +960,7 @@ function translateLocale($locale_tag, $with_wiki_pages = 0, $batch_size = 20, } //\r\n line endings $group_page = preg_replace('/\r/u', '', $group_page); - $parsed_page = $controller->parsePageHeadVars($group_page, + $parsed_page = WikiParser::parsePageHeadVars($group_page, true); if (empty($parsed_page[0])) { $parsed_page[0] = []; @@ -1087,7 +1087,7 @@ function wikiHeaderPageToString($wiki_header, $wiki_page_data) } if (!empty($wiki_page_data) || (!empty($wiki_header['page_type']) && $wiki_header['page_type'] != 'standard')) { - $page = $head_string . "END_HEAD_VARS" . $wiki_page_data; + $page = $head_string . L\WikiParser::END_HEAD_VARS . $wiki_page_data; } return $page; } diff --git a/src/controllers/Controller.php b/src/controllers/Controller.php index 0c3572666..7c36d05d4 100755 --- a/src/controllers/Controller.php +++ b/src/controllers/Controller.php @@ -1063,53 +1063,7 @@ abstract class Controller public function parsePageHeadVarsView($view, $page_name, $page_data) { list($view->head_objects[$page_name], $view->page_objects[$page_name])= - $this->parsePageHeadVars($page_data, true); - } - /** - * Used to parse head meta variables out of a data string provided either - * from a wiki page or a static page. Meta data is stored in lines - * before the first occurrence of END_HEAD_VARS. Head variables - * are name=value pairs. An example of head - * variable might be: - * title = This web page's title - * Anything after a semi-colon on a line in the head section is treated as - * a comment - * - * @param string $page_data this is the actual content of a wiki or - * static page - * @param bool whether to output just an array of head variables or - * if output a pair [head vars, page body] - * @return array the associative array of head variables or pair - * [head vars, page body] - */ - public function parsePageHeadVars($page_data, $with_body = false) - { - $page_parts = explode("END_HEAD_VARS", $page_data); - $head_object = []; - if (count($page_parts) > 1) { - $head_lines = preg_split("/\n\n/", array_shift($page_parts)); - $page_data = implode("END_HEAD_VARS", $page_parts); - foreach ($head_lines as $line) { - $semi_pos = (strpos($line, ";")) ? strpos($line, ";"): - strlen($line); - $line = substr($line, 0, $semi_pos); - $line_parts = explode("=", $line); - if (count($line_parts) == 2) { - $key = trim(urldecode($line_parts[0])); - $value = urldecode(trim($line_parts[1])); - if ($key == 'page_alias') { - $value = str_replace(" ", "_", $value); - } - $head_object[$key] = $value; - } - } - } else { - $page_data = $page_parts[0]; - } - if ($with_body) { - return [$head_object, $page_data]; - } - return $head_object; + L\WikiParser::parsePageHeadVars($page_data, true); } /** * If external source advertisements are present in the output of this diff --git a/src/controllers/SearchController.php b/src/controllers/SearchController.php index 3403e4401..809e6ab89 100755 --- a/src/controllers/SearchController.php +++ b/src/controllers/SearchController.php @@ -38,6 +38,7 @@ use seekquarry\yioop\library\FetchUrl; use seekquarry\yioop\library\FileCache; use seekquarry\yioop\library\PhraseParser; use seekquarry\yioop\library\UrlParser; +use seekquarry\yioop\library\WikiParser; /** * Controller used to handle search requests to SeekQuarry @@ -1387,7 +1388,7 @@ EOD; $data['SEARCH_CALLOUT'] = ""; if (!empty($callout_info)) { list( , $callout) = - $this->parsePageHeadVars( + WikiParser::parsePageHeadVars( $callout_info['PAGE'], true); $data['SEARCH_CALLOUT'] = $callout; } diff --git a/src/controllers/StaticController.php b/src/controllers/StaticController.php index c149c7bc8..79446e6f1 100644 --- a/src/controllers/StaticController.php +++ b/src/controllers/StaticController.php @@ -123,7 +123,7 @@ class StaticController extends Controller $page = "404"; $page_string = $this->getPage($page); } - $page_parts = explode("END_HEAD_VARS", $page_string); + $page_parts = explode(L\WikiParser::END_HEAD_VARS, $page_string); $data['PAGE'] = $page_parts[1] ?? $page_parts[0]; if (!isset($data["INCLUDE_SCRIPTS"])) { $data["INCLUDE_SCRIPTS"] = []; @@ -215,7 +215,7 @@ EOD; } if (isset($page_header['PAGE'])) { $header_parts = - explode("END_HEAD_VARS", $page_header['PAGE']); + explode(L\WikiParser::END_HEAD_VARS, $page_header['PAGE']); } $page_header['PAGE'] = $page_header['PAGE'] ?? ""; $data["PAGE_HEADER"] = (isset($header_parts[1])) ? @@ -230,7 +230,7 @@ EOD; } if (isset($page_footer['PAGE'])) { $footer_parts = - explode("END_HEAD_VARS", $page_footer['PAGE']); + explode(L\WikiParser::END_HEAD_VARS, $page_footer['PAGE']); } $page_footer['PAGE'] = $page_footer['PAGE'] ?? ""; $data['PAGE_FOOTER'] = (isset($footer_parts[1])) ? diff --git a/src/controllers/components/CrawlComponent.php b/src/controllers/components/CrawlComponent.php index ab418eed6..343368d57 100644 --- a/src/controllers/components/CrawlComponent.php +++ b/src/controllers/components/CrawlComponent.php @@ -39,6 +39,7 @@ use seekquarry\yioop\library\FetchUrl; use seekquarry\yioop\library\PageRuleParser; use seekquarry\yioop\library\PhraseParser; use seekquarry\yioop\library\UrlParser; +use seekquarry\yioop\library\WikiParser; use seekquarry\yioop\library\media_jobs as M; use seekquarry\yioop\library\processors as P; use seekquarry\yioop\library\processors\PageProcessor; @@ -2334,7 +2335,7 @@ class CrawlComponent extends Component implements CrawlConstants $_REQUEST["ID"] = $kwiki["ID"]; $_REQUEST["QUERY"] = $query; list( , $kwiki['PAGE']) = - $parent->parsePageHeadVars( + WikiParser::parsePageHeadVars( $kwiki['PAGE'], true); $_REQUEST["KWIKI_PAGE"] = $kwiki['PAGE']; return $parent->redirectWithMessage( @@ -2428,7 +2429,7 @@ class CrawlComponent extends Component implements CrawlConstants } $_REQUEST["KWIKI_PAGE"] = $kwiki_page; if (!empty($kwiki_page)) { - $kwiki_page = $head_string . "END_HEAD_VARS" . + $kwiki_page = $head_string . WikiParser::END_HEAD_VARS . $kwiki_page; } $_REQUEST["ID"] = $verticals_model->setPageName(C\ROOT_ID, diff --git a/src/controllers/components/SocialComponent.php b/src/controllers/components/SocialComponent.php index 675ae96b0..b9c2ec264 100644 --- a/src/controllers/components/SocialComponent.php +++ b/src/controllers/components/SocialComponent.php @@ -3289,7 +3289,7 @@ class SocialComponent extends Component implements CrawlConstants "admin" : "group"; $base_url = C\SHORT_BASE_URL; list($data, $sub_path, $additional_substitutions, $clean_array, - $strings_array, $page_defaults) = $this->initCommonWikiArrays( + $strings_array) = $this->initCommonWikiArrays( $controller_name, $base_url); $group_model = $parent->model("group"); if (isset($_SESSION['USER_ID'])) { @@ -3423,7 +3423,7 @@ class SocialComponent extends Component implements CrawlConstants $page = isset($page) ? $page : null; $edit_reason = isset($edit_reason) ? $edit_reason: null; $this->editWiki($data, $user_id, $group_id, $group, - $page_id, $page_name, $page, $page_defaults, $sub_path, + $page_id, $page_name, $page, $sub_path, $edit_reason, $missing_fields, $read_address, $additional_substitutions); break; @@ -3780,7 +3780,7 @@ class SocialComponent extends Component implements CrawlConstants $this->initializeReadMode($data, $user_id, $group_id, $sub_path); } else if (in_array($data['MODE'], ['edit', 'source'])) { - foreach ($page_defaults as $key => $default) { + foreach (WikiParser::PAGE_DEFAULTS as $key => $default) { $data[$key] = $default; if (isset($data["HEAD"][$key])) { $data[$key] = $data["HEAD"][$key]; @@ -3857,7 +3857,7 @@ class SocialComponent extends Component implements CrawlConstants $template_info = $group_model-> getPageInfoByName($group_id, $template_name, $data['CURRENT_LOCALE_TAG'], "read"); - list( ,$tmp_page) = $parent->parsePageHeadVars( + list(, $tmp_page) = WikiParser::parsePageHeadVars( $template_info['PAGE'], true); $tmp_page = preg_replace("/{{text\|(.+?)\|(.+?)}}/", "<input type='text' class='narrow-field'" . @@ -4034,7 +4034,7 @@ class SocialComponent extends Component implements CrawlConstants $data['CURRENT_LOCALE_TAG'], $data["MODE"]); if (isset($page_header['PAGE'])) { $header_parts = - explode("END_HEAD_VARS", $page_header['PAGE']); + explode(WikiParser::END_HEAD_VARS, $page_header['PAGE']); } $data["PAGE_HEADER"] = (isset($header_parts[1])) ? $header_parts[1] : ($page_header['PAGE'] ?? ""); @@ -4062,7 +4062,7 @@ class SocialComponent extends Component implements CrawlConstants $data["MODE"]); if (isset($page_footer['PAGE'])) { $footer_parts = - explode("END_HEAD_VARS", $page_footer['PAGE']); + explode(WikiParser::END_HEAD_VARS, $page_footer['PAGE']); } $data['PAGE_FOOTER'] = (isset($footer_parts[1])) ? $footer_parts[1] : ($page_footer['PAGE'] ?? ""); @@ -4139,7 +4139,7 @@ EOD; $template_info = $group_model-> getPageInfoByName($group_id, $template_name, $data['CURRENT_LOCALE_TAG'], "read"); - list( ,$tmp_page) = $parent->parsePageHeadVars( + list( ,$tmp_page) = WikiParser::parsePageHeadVars( $template_info['PAGE'], true); $tmp_page = preg_replace("/{{(area|text)\|(.+?)\|(.+?)}}/", "{{field|$2}}", $tmp_page); @@ -4459,8 +4459,6 @@ EOD; * @param int $page_id if of wiki page being edited * @param string $page_name string name of wiki page being edited * @param string $page cleaned wiki page that came from $_REQUEST, if any - * @param array $page_defaults associative array system-wide defaults - * for page settings of any wiki page * @param string $sub_path sub resource folder being edited of wiki page, if * any * @param string $edit_reason reason for performing update on wiki page @@ -4473,7 +4471,7 @@ EOD; * substitutions to make in going from wiki page to html */ private function editWiki(&$data, $user_id, $group_id, $group, $page_id, - $page_name, $page, $page_defaults, $sub_path, $edit_reason, + $page_name, $page, $sub_path, $edit_reason, $missing_fields, $read_address, $additional_substitutions) { if (empty($data["CAN_EDIT"])) { @@ -4561,7 +4559,7 @@ EOD; $data['PAGE_NAME'] = $page_name; $data['RESOURCE_NAME'] = $file_name; } else { - list($head_object, $page_data) = $parent->parsePageHeadVars( + list($head_object, $page_data) = WikiParser::parsePageHeadVars( $page_info['PAGE'] ?? "", true); $is_currently_template = (!empty($head_object["page_type"]) && $head_object["page_type"][0] == 't'); @@ -4588,7 +4586,7 @@ EOD; $page_types = array_keys($data['page_types']); $page_borders = array_keys($data['page_borders']); $set_path = false; - foreach ($page_defaults as $key => $default) { + foreach (WikiParser::PAGE_DEFAULTS as $key => $default) { $head_vars[$key] = (isset($head_object[$key])) ? $head_object[$key] : $default; if (isset($_REQUEST[$key])) { @@ -4626,8 +4624,8 @@ EOD; ['name', 'size', 'modified'])) { if (isset($page_info['PAGE'])) { if (!isset($page)) { - $page_parts = - explode("END_HEAD_VARS", + $page_parts = explode( + WikiParser::END_HEAD_VARS, $page_info['PAGE']); $page = isset($page_parts[1]) ? $page_parts[1] : $page_parts[0]; @@ -4688,17 +4686,13 @@ EOD; isset($_REQUEST['update_description']); } } - $head_string = ""; - foreach ($page_defaults as $key => $default) { - $head_string .= urlencode($key) . "=" . - urlencode($head_vars[$key]) . "\n\n"; - } + $head_string = WikiParser::makeWikiPageHead($head_vars); if (is_array($page)) { //template case $page = base64_encode(serialize($page)); } if (!empty($page) || (!empty($head_vars['page_type']) && $head_vars['page_type'] != 'standard')) { - $page = $head_string . "END_HEAD_VARS" . $page; + $page = $head_string . WikiParser::END_HEAD_VARS . $page; } $page_info = (empty($page_info)) ? [] : $page_info; $page_info['ID'] = $group_model->setPageName($user_id, @@ -4950,7 +4944,7 @@ EOD; $data['PAGE_NAME'] = htmlentities($page_info['PAGE_NAME'] ?? ""); $page_info = $group_model->getPageInfoByName($group_id, $page_info['PAGE_NAME'] ?? "", $data['CURRENT_LOCALE_TAG'], 'edit'); - $data['HEAD'] = $parent->parsePageHeadVars($page_info['PAGE'] ?? ""); + $data['HEAD'] = WikiParser::parsePageHeadVars($page_info['PAGE'] ?? ""); $resources_info = $group_model->getGroupPageResourceUrls( $group_id, $page_id, $sub_path); $data['ORIGINAL_URL_PREFIX'] = $resources_info['url_prefix']; @@ -5040,7 +5034,7 @@ EOD; $page_info['PAGE_NAME'] ?? "", $data['CURRENT_LOCALE_TAG'], 'edit'); $data['RESOURCES_INFO'] = $group_model->getGroupPageResourceUrls( $group_id, $page_id, $sub_path); - $data['HEAD'] = $parent->parsePageHeadVars($page_info['PAGE'] ?? ""); + $data['HEAD'] = WikiParser::parsePageHeadVars($page_info['PAGE'] ?? ""); $this->initUserResourcePreferences($data); $resources = $data['RESOURCES_INFO']['resources'] ?? ""; $num_resources = (is_array($resources)) ? count($resources) : 0; @@ -5363,25 +5357,6 @@ EOD; "edit_reason" => C\SHORT_TITLE_LEN, "filter" => C\SHORT_TITLE_LEN, "resource_filter" => C\SHORT_TITLE_LEN]; - $page_defaults = [ - 'alternative_path' => '', - 'author' => '', - 'default_sort' => 'aname', - 'description' => '', - 'page_alias' => '', - 'page_border' => 'solid', - 'page_header' => '', - 'page_footer' => '', - 'page_theme' => '', - 'page_type' => 'standard', - 'properties' => '', - 'robots' => '', - 'share_expires' => C\FOREVER, - 'title' => '', - 'toc' => true, - 'url_shortener' => '', - 'update_description' => false - ]; /* Check if back params need to be set. Set them if required. the back params are usually sent when the wiki action is initiated from within an open help article. @@ -5405,7 +5380,7 @@ EOD; $data['BACK_URL'] = http_build_query($back_params_cleaned); } return [$data, $sub_path, $additional_substitutions, $clean_array, - $strings_array, $page_defaults]; + $strings_array]; } /** * Used to create Javascript used to toggle a wiki page's settings control diff --git a/src/library/VersionManager.php b/src/library/VersionManager.php index 808acebd5..1b3fc1f98 100644 --- a/src/library/VersionManager.php +++ b/src/library/VersionManager.php @@ -281,7 +281,7 @@ class VersionManager * carrying out the operation * @return int success code */ - public function headPutContents($file, $data, $lock = true) + public function headPutContents($file, $data, $lock = true, $timestamp = 0) { if (empty($this->managed_folder)) { return self::PUT_CONTENTS_FAILED; @@ -303,7 +303,7 @@ class VersionManager } return self::PUT_CONTENTS_FAILED; } - $this->createVersion($file, "", 0, false); + $this->createVersion($file, "", $timestamp, false); if ($lock) { unlink($lock_file); } diff --git a/src/library/WikiParser.php b/src/library/WikiParser.php index 5c3dda05f..72c8b41f9 100644 --- a/src/library/WikiParser.php +++ b/src/library/WikiParser.php @@ -43,12 +43,39 @@ require_once __DIR__."/../configs/Config.php"; */ class WikiParser implements CrawlConstants { + /** + * String used to separate the head variables of a Yioop wiki page from + * the page contents. + */ + const END_HEAD_VARS = "END_HEAD_VARS"; /** * Escape string to try to prevent incorrect nesting of div for some of the * substitutions; - * @var string */ - public $esc=",[}"; + const ESC=",[}"; + /** + * Wiki page header field used for Yioop wiki pages and the default + * values (field => value pairs). + */ + const PAGE_DEFAULTS = [ + 'alternative_path' => '', + 'author' => '', + 'default_sort' => 'aname', + 'description' => '', + 'page_alias' => '', + 'page_border' => 'solid', + 'page_header' => '', + 'page_footer' => '', + 'page_theme' => '', + 'page_type' => 'standard', + 'properties' => '', + 'robots' => '', + 'share_expires' => C\FOREVER, + 'title' => '', + 'toc' => true, + 'url_shortener' => '', + 'update_description' => false + ]; /** * Whether the parser should be configured only to do minimal substitutions * or all available (minimal might be used for posts in discussion groups) @@ -104,7 +131,7 @@ class WikiParser implements CrawlConstants public function __construct($base_address = "", $add_substitutions = [], $minimal = false) { - $esc = $this->esc; + $esc = self::ESC; $not_braces = '(?:[^\}]|[^\}]\})*'; $not_paragraph = '(?:\A|[^\n]|[^\n]\n)'; $class_or_id = '0-9a-zA-Z\_\-\s'; @@ -445,7 +472,7 @@ class WikiParser implements CrawlConstants $head_vars = []; $draw_toc = true; if ($parse_head_vars && !$this->minimal) { - $document_parts = explode("END_HEAD_VARS", $document); + $document_parts = explode(self::END_HEAD_VARS, $document); if (count($document_parts) > 1) { $head = $document_parts[0]; $document = $document_parts[1]; @@ -525,7 +552,7 @@ class WikiParser implements CrawlConstants "/<nowiki>(.+?)<\/nowiki>/s", C\NS_LIB . "base64DecodeCallback", $document); if ($head != "" && $parse_head_vars) { - $document = $head . "END_HEAD_VARS" . $document; + $document = $head . self::END_HEAD_VARS . $document; } if (!$handle_big_files && strlen($document) > 0.9 * C\MAX_GROUP_PAGE_LEN) { @@ -587,7 +614,7 @@ class WikiParser implements CrawlConstants */ public function cleanLinksAndParagraphs($document) { - $esc = $this->esc; + $esc = self::ESC; $document = preg_replace_callback("/((href=)\"([^\"]+)\")/", C\NS_LIB . "fixLinksCallback", $document); $document = preg_replace_callback( @@ -747,19 +774,6 @@ class WikiParser implements CrawlConstants $ref_data['title'] = "<a href=\"{$ref_data['url']}\">". "{$ref_data['title']}</a>"; } - if (isset($ref_data['quote'])) { - $references .= '"'.$ref_data['quote'].'". '; - } - if (isset($ref_data['author'])) { - $references .= $ref_data['author'].". "; - } - if (isset($ref_data['title'])) { - $references .= '"'.$ref_data['title'].'". '; - } - if (isset($ref_data['accessdate']) && - !isset($ref_data['archivedate'])) { - $references .= '('.$ref_data['accessdate'].') '; - } if (isset($ref_data['archivedate'])) { if (isset($ref_data['archiveurl'])) { $ref_data['archivedate'] = "<a href=\"". @@ -768,45 +782,24 @@ class WikiParser implements CrawlConstants } $references .= '('.$ref_data['archivedate'].') '; } - if (isset($ref_data['journal'])) { - $references .= "<i>{$ref_data['journal']}</i> "; - } - if (isset($ref_data['location'])) { - $references .= $ref_data['location'].". "; - } - if (isset($ref_data['publisher'])) { - $references .= $ref_data['publisher'].". "; - } - if (isset($ref_data['doi'])) { - $references .= "doi:".$ref_data['doi'].". "; - } - if (isset($ref_data['isbn'])) { - $references .= "ISBN:".$ref_data['isbn'].". "; - } - if (isset($ref_data['jstor'])) { - $references .= "JSTOR:".$ref_data['jstor'].". "; - } - if (isset($ref_data['oclc'])) { - $references .= "OCLC:".$ref_data['oclc'].". "; - } - if (isset($ref_data['volume'])) { - $references .= "<b>".$ref_data['volume']. - "</b> "; - } - if (isset($ref_data['issue'])) { - $references .= "#".$ref_data['issue'].". "; - } - if (isset($ref_data['date'])) { - $references .= $ref_data['date'].". "; - } - if (isset($ref_data['year'])) { - $references .= $ref_data['year'].". "; - } - if (isset($ref_data['page'])) { - $references .= "p.".$ref_data['page'].". "; + if (isset($ref_data['accessdate']) && + !isset($ref_data['archivedate'])) { + $references .= '('.$ref_data['accessdate'].') '; } - if (isset($ref_data['pages'])) { - $references .= "pp.".$ref_data['pages'].". "; + foreach ([ + "quote" => ['"', '". '], "author" => ['', '. '], + "title" => ['"', '". '], "journal" => ['<i>', '</i> '], + "location" => ['', '. '], "publisher" => ['', '. '], + "doi" => ['doi:', '. '], "isbn" => ['ISBN:', '. '], + "jstor" => ['JSTOR:', '. '], "oclc" => ['OCLC:', '. '], + "volume" => ['<b>', '</b>'], "issue" => ['#', '. '], + "date" => ['', '. '], "year" => ['', '. '], + "page" => ['p.', '. '], "pages" => ['pp.', '. '], + ] as $field => $tags) { + if (isset($ref_data[$field])) { + $references .= $tags[0] . $ref_data[$field] . + $tags[1]; + } } } $references .="</div>\n"; @@ -891,6 +884,64 @@ class WikiParser implements CrawlConstants $links = array_unique($links); return $links; } + /** + * + */ + public static function makeWikiPageHead($head_vars = []) + { + $head_string = ""; + foreach (self::PAGE_DEFAULTS as $key => $default) { + $head_string .= urlencode($key) . "=" . + urlencode($head_vars[$key] ?? $default) . "\n\n"; + } + return $head_string; + } + /** + * Used to parse head meta variables out of a data string provided either + * from a wiki page or a static page. Meta data is stored in lines + * before the first occurrence of END_HEAD_VARS. Head variables + * are name=value pairs. An example of head + * variable might be: + * title = This web page's title + * Anything after a semi-colon on a line in the head section is treated as + * a comment + * + * @param string $page_data this is the actual content of a wiki or + * static page + * @param bool whether to output just an array of head variables or + * if output a pair [head vars, page body] + * @return array the associative array of head variables or pair + * [head vars, page body] + */ + public static function parsePageHeadVars($page_data, $with_body = false) + { + $page_parts = explode(self::END_HEAD_VARS, $page_data); + $head_object = []; + if (count($page_parts) > 1) { + $head_lines = preg_split("/\n\n/", array_shift($page_parts)); + $page_data = implode(self::END_HEAD_VARS, $page_parts); + foreach ($head_lines as $line) { + $semi_pos = (strpos($line, ";")) ? strpos($line, ";"): + strlen($line); + $line = substr($line, 0, $semi_pos); + $line_parts = explode("=", $line); + if (count($line_parts) == 2) { + $key = trim(urldecode($line_parts[0])); + $value = urldecode(trim($line_parts[1])); + if ($key == 'page_alias') { + $value = str_replace(" ", "_", $value); + } + $head_object[$key] = $value; + } + } + } else { + $page_data = $page_parts[0]; + } + if ($with_body) { + return [$head_object, $page_data]; + } + return $head_object; + } } /** * Callback used by a preg_replace_callback in nextPage to make a table diff --git a/src/models/GroupModel.php b/src/models/GroupModel.php index 0422ec51a..1b0063a26 100644 --- a/src/models/GroupModel.php +++ b/src/models/GroupModel.php @@ -1831,6 +1831,7 @@ class GroupModel extends Model implements MediaConstants $db = $this->db; $pubdate = ($pubdate == -1) ? time() : $pubdate; $parser = new WikiParser($base_address, $additional_substitutions); + $end_head = WikiParser::END_HEAD_VARS; if ($add_relationship_data) { $links_relationships = $parser->fetchLinks($page); } @@ -1841,6 +1842,9 @@ class GroupModel extends Model implements MediaConstants if (strstr($page, '{{submit|') !== false) { $is_form = true; } + if (!str_contains($page, $end_head)) { + $page = WikiParser::makeWikiPageHead() . $end_head . $page; + } $parsed_page = $parser->parse($page); if ($is_form && strstr($page, '<form ') !== false) { return null; @@ -1851,14 +1855,13 @@ class GroupModel extends Model implements MediaConstants $parsed_page = $this->insertResourcesParsePage($group_id, $page_id, $locale_tag, $parsed_page); if ($is_form) { - $end_head = "END_HEAD_VARS"; $parsed_page = str_replace($end_head, $end_head . "\n<form method='post' >\n<input type='hidden' name='" . C\CSRF_TOKEN . "' value='[{just-token}]' >" . "<input type='hidden' name='CSV_FORM_HASH' ". "value='[{form-hash}]' >", $parsed_page); $parsed_page .= "\n</form>\n"; - $page_body = explode("END_HEAD_VARS", $parsed_page, 2)[1]; + $page_body = explode($end_head, $parsed_page, 2)[1]; $parsed_page = preg_replace("/\[{form\-hash}\]/", "[{form-hash". L\crawlHash($page_body) . "}]", $parsed_page); @@ -3867,7 +3870,8 @@ EOD; * (only used in case run non-empty) */ public function copyFileToGroupPageResource($tmp_name, $file_name, - $mime_type, $group_id, $page_id, $sub_path = "", $data = "") + $mime_type, $group_id, $page_id, $sub_path = "", $data = "", + $timestamp = 0) { $folders = $this->getGroupPageResourcesFolders($group_id, $page_id, $sub_path, true); @@ -3881,10 +3885,10 @@ EOD; return false; } $file_size = filesize("$folder/$file_name"); - $vcs->createVersion("$folder/$file_name"); + $vcs->createVersion("$folder/$file_name", "", $timestamp); } else { $file_size = strlen($data); - $vcs->headPutContents("$folder/$file_name", $data); + $vcs->headPutContents("$folder/$file_name", $data, $timestamp); } $this->makeThumbStripExif($file_name, $folder, $thumb_folder, $mime_type); @@ -4100,7 +4104,8 @@ EOD; if (!($clip_page_id = $this->getPageId($clip_group_id, C\CLIPBOARD_PAGE_NAME, C\DEFAULT_LOCALE) ) ) { $clip_page_id = $this->setPageName($user_id, $clip_group_id, - C\CLIPBOARD_PAGE_NAME, "page_type=media_list\n\nEND_HEAD_VARS" . + C\CLIPBOARD_PAGE_NAME, "page_type=media_list\n\n" . + WikiParser::END_HEAD_VARS . C\CLIPBOARD_PAGE_NAME, C\DEFAULT_LOCALE, "create", "", ""); if (!$clip_page_id) { return false; @@ -4714,12 +4719,12 @@ EOD; $result = $db->execute($sql, $params); $i = 0; if ($result) { - $separator_len = strlen("END_HEAD_VARS"); + $separator_len = strlen(WikiParser::END_HEAD_VARS); $stretch = ($_SERVER["MOBILE"]) ? 5 : 9; $max_title_len = $stretch * C\NAME_TRUNCATE_LEN; while ($pages[$i] = $db->fetchArray($result)) { $head_pos = strpos($pages[$i]['DESCRIPTION'], - "END_HEAD_VARS"); + WikiParser::END_HEAD_VARS); if ($head_pos) { $head = substr($pages[$i]['DESCRIPTION'], 0, $head_pos); if (preg_match('/page_type\=(.*)/', $head, $matches)) {