• R/O
  • HTTP
  • SSH
  • HTTPS

pukiwiki: Commit


Commit MetaInfo

Revision90000da7db1c275000c80ed4f9c57368928f7bdc (tree)
Time2019-01-12 00:49:49
Authorumorigu <umorigu@gmai...>
Commiterumorigu

Log Message

BugTrack/2484 AutoTicketLink for JIRA

Change Summary

Incremental Difference

--- a/lib/func.php
+++ b/lib/func.php
@@ -2,7 +2,7 @@
22 // PukiWiki - Yet another WikiWikiWeb clone.
33 // func.php
44 // Copyright
5-// 2002-2018 PukiWiki Development Team
5+// 2002-2019 PukiWiki Development Team
66 // 2001-2002 Originally written by yu-ji
77 // License: GPL v2 or (at your option) any later version
88 //
@@ -1048,6 +1048,21 @@ function htmlsc($string = '', $flags = ENT_COMPAT, $charset = CONTENT_CHARSET)
10481048 }
10491049
10501050 /**
1051+ * Get JSON string with htmlspecialchars().
1052+ */
1053+function htmlsc_json($obj)
1054+{
1055+ // json_encode: PHP 5.2+
1056+ // JSON_UNESCAPED_UNICODE: PHP 5.4+
1057+ // JSON_UNESCAPED_SLASHES: PHP 5.4+
1058+ if (defined('JSON_UNESCAPED_UNICODE')) {
1059+ return htmlsc(json_encode($obj,
1060+ JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
1061+ }
1062+ return '';
1063+}
1064+
1065+/**
10511066 * Get redirect page name on Page Redirect Rules
10521067 *
10531068 * This function returns exactly false if it doesn't need redirection.
--- a/lib/html.php
+++ b/lib/html.php
@@ -226,6 +226,7 @@ function get_html_scripting_data($page, $in_editing)
226226 global $ticket_link_sites, $plugin;
227227 global $external_link_cushion_page, $external_link_cushion;
228228 global $topicpath_title;
229+ global $ticket_jira_default_site;
229230 if (!isset($ticket_link_sites) || !is_array($ticket_link_sites)) {
230231 return '';
231232 }
@@ -277,6 +278,22 @@ EOS;
277278 $ticketlink_data = <<<EOS
278279 <input type="hidden" class="ticketlink-def" value="$h_ticket_link_sites" />
279280 EOS;
281+ // AutoTicketLink - JIRA
282+ $ticket_jira_projects = get_ticketlink_jira_projects();
283+ $ticketlink_jira_data = '';
284+ if (count($ticket_jira_projects) > 0) {
285+ $h_ticket_jira_projects = htmlsc_json($ticket_jira_projects);
286+ $ticketlink_jira_data = <<<EOS
287+<input type="hidden" class="ticketlink-jira-def" value="$h_ticket_jira_projects" />
288+EOS;
289+ }
290+ $ticketlink_jira_default_data = '';
291+ if (isset($ticket_jira_default_site) && is_array($ticket_jira_default_site)) {
292+ $h_ticket_jira_default_site = htmlsc_json($ticket_jira_default_site);
293+ $ticketlink_jira_default_data = <<<EOS
294+<input type="hidden" class="ticketlink-jira-default-def" value="$h_ticket_jira_default_site" />
295+EOS;
296+ }
280297 // External link cushion page
281298 $external_link_cushion_data = '';
282299 if ($external_link_cushion_page) {
@@ -303,6 +320,8 @@ $plugin_prop
303320 $page_name_data
304321 $page_edit_data
305322 $ticketlink_data
323+$ticketlink_jira_data
324+$ticketlink_jira_default_data
306325 $external_link_cushion_data
307326 $topicpath_data
308327 </div>
--- a/lib/make_link.php
+++ b/lib/make_link.php
@@ -2,7 +2,7 @@
22 // PukiWiki - Yet another WikiWikiWeb clone.
33 // make_link.php
44 // Copyright
5-// 2003-2018 PukiWiki Development Team
5+// 2003-2019 PukiWiki Development Team
66 // 2001-2002 Originally written by yu-ji
77 // License: GPL v2 or (at your option) any later version
88 //
@@ -927,3 +927,68 @@ function get_interwiki_url($name, $param)
927927
928928 return $url;
929929 }
930+
931+function get_autoticketlink_def_page()
932+{
933+ return 'AutoTicketLinkName';
934+}
935+
936+/**
937+ * Get AutoTicketLink - JIRA projects from AutoTiketLinkName page
938+ */
939+function get_ticketlink_jira_projects()
940+{
941+ $autoticketlink_def_page = get_autoticketlink_def_page();
942+ $active_jira_base_url = null;
943+ $jira_projects = array();
944+ foreach (get_source($autoticketlink_def_page) as $line) {
945+ if (substr($line, 0, 1) !== '-') {
946+ $active_jira_base_url = null;
947+ continue;
948+ }
949+ $m = null;
950+ if (preg_match('/^-\s*(jira)\s+(https?:\/\/[!~*\'();\/?:\@&=+\$,%#\w.-]+)\s*$/', $line, $m)) {
951+ $active_jira_base_url = $m[2];
952+ } else if (preg_match('/^--\s*([A-Z][A-Z0-9]+)(\s+(.+?))?\s*$/', $line, $m)) {
953+ if ($active_jira_base_url) {
954+ $project_key = $m[1];
955+ $title = $m[2];
956+ array_push($jira_projects, array(
957+ 'key' => $m[1],
958+ 'title' => $title,
959+ 'base_url' => $active_jira_base_url,
960+ ));
961+ }
962+ } else {
963+ $active_jira_base_url = null;
964+ }
965+ }
966+ return $jira_projects;
967+}
968+
969+function init_autoticketlink_def_page()
970+{
971+ $autoticketlink_def_page = get_autoticketlink_def_page();
972+ if (is_page($autoticketlink_def_page)) {
973+ return;
974+ }
975+ $body = <<<'EOS'
976+#freeze
977+* AutoTicketLink definition [#def]
978+
979+Reference: https://pukiwiki.osdn.jp/?AutoTicketLink
980+
981+ - jira https://site1.example.com/jira/browse/
982+ -- AAA Project title $1
983+ -- BBB Project title $1
984+ - jira https://site2.example.com/jira/browse/
985+ -- PROJECTA Site2 $1
986+
987+ (Default definition) pukiwiki.ini.php
988+ $ticket_jira_default_site = array(
989+ 'title' => 'My JIRA - $1',
990+ 'base_url' => 'https://issues.example.com/jira/browse/',
991+ );
992+EOS;
993+ page_write($autoticketlink_def_page, $body);
994+}
--- a/plugin/edit.inc.php
+++ b/plugin/edit.inc.php
@@ -1,7 +1,7 @@
11 <?php
22 // PukiWiki - Yet another WikiWikiWeb clone.
33 // edit.inc.php
4-// Copyright 2001-2018 PukiWiki Development Team
4+// Copyright 2001-2019 PukiWiki Development Team
55 // License: GPL v2 or (at your option) any later version
66 //
77 // Edit plugin (cmd=edit)
@@ -279,4 +279,6 @@ function plugin_edit_setup_initial_pages()
279279 if (exist_plugin('rename') && function_exists('plugin_rename_setup_initial_pages')) {
280280 plugin_rename_setup_initial_pages();
281281 }
282+ // AutoTicketLinkName page
283+ init_autoticketlink_def_page();
282284 }
--- a/pukiwiki.ini.php
+++ b/pukiwiki.ini.php
@@ -2,7 +2,7 @@
22 // PukiWiki - Yet another WikiWikiWeb clone
33 // pukiwiki.ini.php
44 // Copyright
5-// 2002-2016 PukiWiki Development Team
5+// 2002-2019 PukiWiki Development Team
66 // 2001-2002 Originally written by yu-ji
77 // License: GPL v2 or (at your option) any later version
88 //
@@ -314,6 +314,13 @@ $ticket_link_sites = array(
314314 ),
315315 */
316316 );
317+// AutoTicketLink - JIRA Default site
318+/*
319+$ticket_jira_default_site = array(
320+ 'title' => 'My JIRA - $1',
321+ 'base_url' => 'https://issues.example.com/jira/browse/',
322+);
323+//*/
317324
318325 /////////////////////////////////////////////////
319326 // Show External Link Cushion Page
--- a/skin/main.js
+++ b/skin/main.js
@@ -1,6 +1,6 @@
11 // PukiWiki - Yet another WikiWikiWeb clone.
22 // main.js
3-// Copyright 2017 PukiWiki Development Team
3+// Copyright 2017-2019 PukiWiki Development Team
44 // License: GPL v2 or (at your option) any later version
55 //
66 // PukiWiki JavaScript client script
@@ -106,11 +106,13 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function(
106106 }
107107 // AutoTicketLink
108108 function autoTicketLink() {
109- var headReText = '([\\s\\b]|^)';
109+ var headReText = '([\\s\\b:\\[]|^)';
110110 var tailReText = '\\b';
111111 var ignoreTags = ['A', 'INPUT', 'TEXTAREA', 'BUTTON',
112112 'SCRIPT', 'FRAME', 'IFRAME'];
113113 var ticketSiteList = [];
114+ var jiraProjects = null;
115+ var jiraDefaultInfo = null;
114116 function regexEscape(key) {
115117 return key.replace(/[-.]/g, function (m) {
116118 return '\\' + m;
@@ -137,6 +139,17 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function(
137139 site.re = new RegExp(headReText + reText + tailReText);
138140 }
139141 }
142+ function getJiraSite() {
143+ var reText = '()([A-Z][A-Z0-9]{1,20}-\\d{1,10})';
144+ var site = {
145+ title: 'Builtin JIRA',
146+ type: '_jira_',
147+ key: '_jira_',
148+ reText: reText,
149+ re: new RegExp(headReText + reText + tailReText)
150+ };
151+ return site;
152+ }
140153 function getSiteListFromBody() {
141154 var defRoot = document.querySelector('#pukiwiki-site-properties .ticketlink-def');
142155 if (defRoot && defRoot.value) {
@@ -146,22 +159,86 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function(
146159 }
147160 return [];
148161 }
162+ function getJiraProjectsFromBody() {
163+ var defRoot = document.querySelector('#pukiwiki-site-properties .ticketlink-jira-def');
164+ if (defRoot && defRoot.value) {
165+ try {
166+ return JSON.parse(defRoot.value); // List
167+ } catch (e) {
168+ return null;
169+ }
170+ }
171+ return null;
172+ }
173+ function getJiraDefaultInfoFromBody() {
174+ var defRoot = document.querySelector('#pukiwiki-site-properties .ticketlink-jira-default-def');
175+ if (defRoot && defRoot.value) {
176+ try {
177+ return JSON.parse(defRoot.value); // object
178+ } catch (e) {
179+ return null;
180+ }
181+ }
182+ return null;
183+ }
149184 function getSiteList() {
150185 return ticketSiteList;
151186 }
187+ function getJiraProjectList() {
188+ return jiraProjects;
189+ }
190+ function getDefaultJira() {
191+ return jiraDefaultInfo;
192+ }
152193 function ticketToLink(keyText) {
153194 var siteList = getSiteList();
154195 for (var i = 0; i < siteList.length; i++) {
155196 var site = siteList[i];
156197 var m = keyText.match(site.re);
157198 if (m) {
158- var title = site.title;
159199 var ticketKey = m[3];
160- if (title) {
161- title = title.replace(/\$1/g, ticketKey);
200+ var title = ticketKey;
201+ var ticketUrl;
202+ if (site.type === '_jira_') {
203+ // JIRA issue
204+ var projects = getJiraProjectList();
205+ var hyphen = keyText.indexOf('-');
206+ if (hyphen > 0) {
207+ var projectKey = keyText.substr(0, hyphen);
208+ if (projects) {
209+ for (var j = 0; j < projects.length; j++) {
210+ var p = projects[j];
211+ if (p.key === projectKey) {
212+ if (p.title) {
213+ title = p.title.replace(/\$1/g, ticketKey);
214+ }
215+ ticketUrl = p.base_url + ticketKey;
216+ break;
217+ }
218+ }
219+ }
220+ if (!ticketUrl) {
221+ var defaultJira = getDefaultJira();
222+ if (defaultJira) {
223+ if (defaultJira.title) {
224+ title = defaultJira.title.replace(/\$1/g, ticketKey);
225+ }
226+ ticketUrl = defaultJira.base_url + ticketKey;
227+ }
228+ }
229+ }
230+ if (!ticketUrl) {
231+ return null;
232+ }
233+ } else {
234+ // Explicit TicketLink
235+ if (site.title) {
236+ title = site.title.replace(/\$1/g, ticketKey);
237+ }
238+ ticketUrl = site.base_url + ticketKey;
162239 }
163240 return {
164- url: site.base_url + m[3],
241+ url: ticketUrl,
165242 title: title
166243 };
167244 }
@@ -195,12 +272,17 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function(
195272 if (m.index > 0 || m[1].length > 0) {
196273 f.appendChild(document.createTextNode(text.substr(0, m.index) + m[1]));
197274 }
198- var a = document.createElement('a');
199- a.textContent = m[2];
200- var linkInfo = ticketToLink(a.textContent);
201- a.href = linkInfo.url;
202- a.title = linkInfo.title;
203- f.appendChild(a);
275+ var linkKey = m[2];
276+ var linkInfo = ticketToLink(linkKey);
277+ if (linkInfo) {
278+ var a = document.createElement('a');
279+ a.textContent = linkKey;
280+ a.href = linkInfo.url;
281+ a.title = linkInfo.title;
282+ f.appendChild(a);
283+ } else {
284+ f.appendChild(document.createTextNode(m[2]));
285+ }
204286 text = text.substr(m.index + m[0].length);
205287 }
206288 if (f) {
@@ -230,6 +312,11 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function(
230312 return;
231313 }
232314 ticketSiteList = getSiteListFromBody();
315+ jiraProjects = getJiraProjectsFromBody();
316+ jiraDefaultInfo = getJiraDefaultInfoFromBody();
317+ if (jiraDefaultInfo || (jiraProjects && jiraProjects.length > 0)) {
318+ ticketSiteList.push(getJiraSite());
319+ }
233320 var target = document.getElementById('body');
234321 walkElement(target);
235322 }
Show on old repository browser