home.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. /**
  3. * Copyright 2021, 2024 5 Mode
  4. *
  5. * This file is part of SnipSwap.
  6. *
  7. * SnipSwap is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * SnipSwap is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with SnipSwap. If not, see <https://www.gnu.org/licenses/>.
  19. *
  20. * home.php
  21. *
  22. * Page Home.
  23. *
  24. * @author Daniele Bonini <my25mb@aol.com>
  25. * @copyrights (c) 2016, 2024, 5 Mode
  26. */
  27. use fivemode\fivemode\LinkUtil;
  28. define('PAGE_TITLE', "SwapSnippet - Home");
  29. function echo_label(string $label) {
  30. if (mb_strlen($label) > 25) {
  31. echo(left($label, 25) . "...");
  32. } else {
  33. echo($label);
  34. }
  35. }
  36. $q = substr(filter_input1(INPUT_GET, "q", FILTER_SANITIZE_QM)??"", 0, 100);
  37. $splash = filter_input(INPUT_GET, "splash")??"";
  38. $splash = strip_tags($splash);
  39. $curLocale = APP_LOCALE;
  40. ?>
  41. <script>
  42. <?PHP if ($splash === "1"):?>
  43. firstaccess = 1;
  44. <?PHP else: ?>
  45. firstaccess = 0;
  46. <?PHP endif ?>
  47. </script>
  48. <?php require APP_SCRIPT_PATH . "/header.php";?>
  49. <div id="linkContainer" cat="<?PHP echo($catMaskedPath);?>" ondragover="onDragOver(event);" ondrop="onDrop(this, event);">
  50. <?php
  51. //echo($q."=q***");
  52. //echo($catMaskedPath."=cat***");
  53. $allLinks = LinkUtil::getLinkList(PHP_STR, "*");
  54. $iLinkjs = 1;
  55. $myCubeInitjs= "";
  56. foreach($allLinks as $ainallLink) {
  57. $newFormalName = $ainallLink['name'];
  58. $myCubeInitjs .= "cubes[" . $iLinkjs . "-1] = new myCube( 'Snip#". $iLinkjs . "', '" . $newFormalName . "', '" . APP_HOST . "');\n";
  59. $myCubeInitjs .= "cubes[" . $iLinkjs . "-1].start();\n";
  60. $iLinkjs++;
  61. }
  62. $myCubeInitjs .= "totcubes=" . count($allLinks) . ";\n";
  63. $aLinks = LinkUtil::getLinkList($q, $catMaskedPath);
  64. $iLink = 0;
  65. foreach($aLinks as $aLink) {
  66. $order = 1;
  67. foreach ($allLinks as $ainallLink) {
  68. if ($ainallLink['name'] === $aLink['name']) {
  69. break;
  70. }
  71. $order++;
  72. }
  73. $serverName = $_SERVER['SERVER_NAME'];
  74. $relPath = "/#" . $aLink['title'];
  75. ?>
  76. <div id="<?php echo($aLink['title']);?>" class="link-div" title="<?php echo($aLink['desc']); ?>" order="<?PHP echo($order);?>" onclick="selCube(this);openDetail()" draggable="true" ondragstart="onDragStart(this, event);" onmouseover="onMouseOver();">
  77. <div class="link-title"><?php echo($aLink['title']); ?><div style="width:25px; float:right;" title="It's a beauty!"><a href="#" onclick="event.stopPropagation();selCube($(this).parent().parent().parent());storeBeauty('imgheart<?php echo($aLink['title']);?>');"><img id="imgheart<?php echo($aLink['title']);?>" src="/res/<?PHP echo(($aLink['beauty']==="0")?"un":"");?>heart.png" style="height:23px;"></a></div></div>
  78. <a href="#"><img class="link-img" src="/res/code.png" alt="<?php echo($aLink['title']); ?>"></a><br>
  79. <br>
  80. &nbsp;<a class="link-link" href="http://<?php echo(str_replace(PHP_TILDE, PHP_SLASH, $aLink['link']));?>"><?php echo_label(str_replace(PHP_TILDE, PHP_SLASH, $aLink['label']));?></a><br>
  81. <div style="position:relative;top:-25px;left:-2px;text-align:right;padding-right:1.5px;">
  82. <a href="https://www.facebook.com/sharer/sharer.php?u=http://<?PHP echo("{$serverName}{$relPath}");?>&t=" onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600');return false;" target="_blank" title="Share on Facebook"><img src="/res/fb.png"></a>
  83. <a href="https://twitter.com/share?url=http://<?PHP echo("{$serverName}{$relPath}");?>&text=" onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600');return false;" target="_blank" title="Share on Twitter"><img src="/res/twitter.png"></a>
  84. <a href="whatsapp://send?text=http://<?PHP echo("{$serverName}{$relPath}");?>" data-action="share/whatsapp/share" onClick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600');return false;" target="_blank" title="Share on whatsapp"><img src="/res/whatsapp.png"></a>
  85. </div>
  86. </div>
  87. <?php
  88. $iLink++;
  89. } ?>
  90. <?php
  91. if (Empty($aLinks)) {
  92. echo("<div class=\"no-link\" style=\"width:250px; float:left; padding: 10px;\">no link found</div>");
  93. }
  94. ?>
  95. </div>
  96. <div>
  97. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  98. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  99. </div>
  100. <?PHP echo("<script>$myCubeInitjs</script>"); ?>
  101. <button id="modalButton1" type="button" class="btn btn-primary" style="display:none;" data-toggle="modal" data-target="#modal1">Button #1</button>
  102. <div class="modal" tabindex="-1" role="dialog" id="modal1">
  103. <div class="modal-dialog modal-lg my-modal-dialog" role="document">
  104. <div class="modal-content my-modal-content">
  105. <img src="/res/code.png" style="width:98%; vertical-align:top; opacity:0.2"></a>
  106. <div style="position:absolute; top:10px; padding:50px;">
  107. <table style="width:100%">
  108. <tr>
  109. <td class="snip-detail-cell">Title:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-title" name="txtTitle" type="text" value="" onkeyup="storeData(this)" readonly></td>
  110. </tr>
  111. <tr>
  112. <td class="snip-detail-cell">Description:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-desc" name="txtDesc" type="text" value="" onkeyup="storeData(this)" readonly></td>
  113. </tr>
  114. <tr>
  115. <td class="snip-detail-cell">Code:&nbsp;</td><td width="700px"><textarea class="snip-detail-field snip-code" id="snip-detail-code" name="txtCode" style="max-width:750px;height:350px;max-height:350px;" onkeyup="storeData(this)" readonly></textarea></td>
  116. </tr>
  117. <tr>
  118. <td class="snip-detail-cell">Tags:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-tags" name="txtTags" type="text" value="" onkeyup="storeData(this)" readonly></td>
  119. </tr>
  120. <tr>
  121. <td class="snip-detail-cell">Label (link):&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-label" name="txtLabel" type="text" value="" onkeyup="storeData(this)" readonly></td>
  122. </tr>
  123. <tr>
  124. <td class="snip-detail-cell">Link:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-link" name="txtLink" type="text" value="" onkeyup="storeData(this)" readonly></td>
  125. </tr>
  126. <tr>
  127. <td class="snip-detail-cell">Email:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-email" name="txtEmail" type="text" value="" onkeyup="storeData(this)" readonly></td>
  128. </tr>
  129. <tr>
  130. <td class="snip-detail-cell">Cats:&nbsp;</td><td width="700px" style="padding-top:8px;font-weight:900;"><input class="snip-detail-field" id="snip-detail-cats" name="txtCats" type="text" value="" onkeyup="storeData(this)" readonly><br><span style="font-size:10px;border-top:8px solid transparent;">space separated snip categories, "~" for subcategories.</span></td>
  131. </tr>
  132. <tr style="display: none;">
  133. <td class="snip-detail-cell">Guid:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-guid" name="txtGuid" type="text" value="" readonly></td>
  134. </tr>
  135. <tr>
  136. <td class="snip-detail-cell">Password:&nbsp;</td><td width="700px"><input class="snip-detail-field" id="snip-detail-password" name="txtPassword" type="text" value="" onkeyup="checkPwd(this)"></td>
  137. </tr>
  138. </table>
  139. <input type="hidden" id="comp-pwd" value="">
  140. </div>
  141. </div>
  142. <div class="modal-toolbox" style="float:left;">
  143. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  144. </div>
  145. </div>
  146. </div>
  147. <script>
  148. /*
  149. * Interaction code
  150. */
  151. var oldtthis; // Old cube
  152. var lineOldVal = ""; // Old value for a detail line
  153. var lineNewVal = ""; // New value for a detail line
  154. var dataChanged = false;
  155. /*
  156. * Select the given cube
  157. *
  158. * @param <interfaceEl> selected cube
  159. * @returns void
  160. */
  161. function selCube(tthis) {
  162. _selCube(tthis);
  163. }
  164. function checkPwd(tthis) {
  165. if (encryptSha2($(tthis).val()) === $("#comp-pwd").val()) {
  166. $("#snip-detail-title").prop("readonly", false);
  167. $("#snip-detail-desc").prop("readonly", false);
  168. $("#snip-detail-code").prop("readonly", false);
  169. $("#snip-detail-tags").prop("readonly", false);
  170. $("#snip-detail-label").prop("readonly", false);
  171. $("#snip-detail-link").prop("readonly", false);
  172. $("#snip-detail-email").prop("readonly", false);
  173. $("#snip-detail-cats").prop("readonly", false);
  174. }
  175. }
  176. /*
  177. * Get the data for the given detail / face
  178. *
  179. * @param string xmlStr, the current cube xml data
  180. * @param string detail, the requested detail
  181. * @returns string, the detail data
  182. */
  183. function getDetailData(xmlStr, detail) {
  184. var ret = "";
  185. var re;
  186. detail = detail.toLowerCase();
  187. xmlStr = xmlStr.replace('<?xml version="1.0" encoding="UTF-8"?>',"");
  188. xmlStr = xmlStr.replace('<details>',"");
  189. xmlStr = xmlStr.replace('</details>',"");
  190. xmlStr = xmlStr.replaceAll('\n',"|||999");
  191. xmlStr = xmlStr.replaceAll(String.fromCharCode(9), "");
  192. xmlStr = xmlStr.replaceAll(String.fromCharCode(10), "|||999");
  193. xmlStr = xmlStr.replaceAll(String.fromCharCode(13), "|||999");
  194. xmlStr = xmlStr.replaceAll(" ", "");
  195. xmlStr = xmlStr.replaceAll(" ", "");
  196. xmlStr = escape(xmlStr);
  197. //xmlStr = xmlStr.replaceAll('\n',"|99");
  198. //xmlStr = xmlStr.replaceAll(String.fromCharCode(10), "|99");
  199. //xmlStr = xmlStr.replaceAll(String.fromCharCode(13), "|99");
  200. xmlStr = xmlStr.replaceAll("%0A", "");
  201. xmlStr = xmlStr.replaceAll("%20%20%20%20%20", "");
  202. xmlStr = xmlStr.replaceAll("%20%20%20%20%", "");
  203. xmlStr = xmlStr.replaceAll("%20%20%", "");
  204. //xmlStr = unescape(xmlStr);
  205. //alert("xmlStr="+xmlStr);
  206. switch (detail) {
  207. case "snippet":
  208. re = new RegExp("detail%20face%3D%22snippet%22.+/cats", "igsu");
  209. break;
  210. case "contacts":
  211. re = new RegExp("detail%20face%3D%22contacts%22.+/email", "igsu");
  212. break;
  213. case "other info":
  214. re = new RegExp("detail%20face%3D%22other%20info%22.+/guid", "igsu");
  215. break;
  216. case "password":
  217. re = new RegExp("detail%20face%3D%22password%22.+/password", "igsu");
  218. break;
  219. }
  220. s = re.exec(xmlStr);
  221. if (!s || s.length===0) {
  222. //ret = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Error! #1";
  223. alert("Error#1");
  224. return ret;
  225. }
  226. xmlStr = s[0];
  227. xmlStr = "<"+xmlStr+"></detail>";
  228. xmlStr = unescape(xmlStr);
  229. //alert(xmlStr);
  230. const parser = new DOMParser();
  231. const doc = parser.parseFromString(xmlStr, "text/xml");
  232. x = doc.getElementsByTagName("detail");
  233. if (x.length===0) {
  234. //ret = "Error! #2";
  235. alert("Error#2");
  236. return ret;
  237. }
  238. //ret += "<div style='padding:10px;'>";
  239. for (i = 0; i < x[0].childNodes.length; i++) {
  240. if (x[0].childNodes[i].nodeType === 1) {
  241. if (x[0].childNodes[i].nodeName === "code") {
  242. document.getElementById("snip-detail-" + x[0].childNodes[i].nodeName).innerHTML = htmlEncode(x[0].childNodes[i].textContent);
  243. } else if (x[0].childNodes[i].nodeName === "password") {
  244. document.getElementById("comp-pwd").value = htmlEncode(x[0].childNodes[i].textContent);
  245. } else if (x[0].childNodes[i].nodeName === "beauty") {
  246. // none
  247. } else {
  248. //alert(x[0].childNodes[i].nodeName);
  249. document.getElementById("snip-detail-" + x[0].childNodes[i].nodeName).value = x[0].childNodes[i].textContent;
  250. }
  251. }
  252. }
  253. //if ((detail==="pictures") || (detail==="menu")) {
  254. // ret += "<div style='padding-left:80px;clear:both;'><br>you can use eg. Goolge Drive or Microsoft OneDrive to host your pictures.</div>"
  255. //}
  256. //ret += "</div>";
  257. return ret;
  258. }
  259. /*
  260. * Store in the cube object the new data of the text control
  261. *
  262. * @param {InterfaceEl} tthis, the text control under editing
  263. * @returns void
  264. */
  265. function storeData(tthis) {
  266. lineNewVal = $(tthis).val();
  267. //alert(lineNewVal);
  268. nodeName = tthis.id;
  269. nodeName = nodeName.replace("snip-detail-","");
  270. //alert(nodeName);
  271. xmlStr = curcube.getxml();
  272. //$("#log").html($("#log").html() + "old=" + "/(\<" + nodeName + "\>).*(\<\/" + nodeName + "\>)/gs" + "\n");
  273. //$("#log").html($("#log").html() + "new=" + lineNewVal + "\n");
  274. //alert("<" + nodeName + ">" + lineNewVal + "</" + nodeName + ">");
  275. //re = "/(\<" + nodeName + "\>).*(\<\/" + nodeName + "\>)/gs";
  276. switch (nodeName) {
  277. case "title":
  278. re = /(\<title>).*(\<\/title>)/gs;
  279. break;
  280. case "desc":
  281. re = /(\<desc>).*(\<\/desc>)/gs;
  282. break;
  283. case "code":
  284. re = /(\<code>\<\!\[CDATA\[).*(\]\]\>\<\/code>)/gs;
  285. break;
  286. case "tags":
  287. re = /(\<tags>).*(\<\/tags>)/gs;
  288. break;
  289. case "cats":
  290. re = /(\<cats>).*(\<\/cats>)/gs;
  291. break;
  292. case "label":
  293. re = /(\<label>).*(\<\/label>)/gs;
  294. break;
  295. case "link":
  296. re = /(\<link>).*(\<\/link>)/gs;
  297. break;
  298. case "email":
  299. re = /(\<email>).*(\<\/email>)/gs;
  300. break;
  301. }
  302. xmlStr = xmlStr.replace(re, "$1" + lineNewVal + "$2");
  303. //xmlStr = xmlStr.replace("<" + nodeName + ">" + lineOldVal + "</" + nodeName + ">", "<" + nodeName + ">" + lineNewVal + "</" + nodeName + ">");
  304. //alert(xmlStr);
  305. curcube.xml = xmlStr;
  306. dataChanged = true;
  307. }
  308. function storeBeauty(beautyImageId) {
  309. var xmlStr = curcube.getxml();
  310. var beautyNewVal = "1";
  311. re = /(\<beauty>).*(\<\/beauty>)/gs;
  312. xmlStr = xmlStr.replace(re, "$1" + beautyNewVal + "$2");
  313. curcube.xml = xmlStr;
  314. $("#"+beautyImageId).attr("src","/res/heart.png");
  315. dataChanged = true;
  316. }
  317. function _saveData() {
  318. if (dataChanged) {
  319. curcube.savedata();
  320. dataChanged = false;
  321. }
  322. }
  323. setInterval("_saveData()", 1500);
  324. /*
  325. * Display the given data detail
  326. *
  327. * @param <interfaceEl> selected cube
  328. * @returns void
  329. */
  330. function openDetail() {
  331. //alert(curcube.getxml());
  332. myhtml = getDetailData(curcube.getxml(), "snippet") + getDetailData(curcube.getxml(), "contacts") + getDetailData(curcube.getxml(), "other info") + getDetailData(curcube.getxml(), "password");
  333. $('#modalButton1').click();
  334. }
  335. </script>
  336. <?php require APP_SCRIPT_PATH . "/footer.php";?>