1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552: 553: 554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660: 661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672: 673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687: 688: 689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707: 708: 709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719: 720: 721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734: 735: 736: 737: 738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756: 757: 758: 759: 760: 761: 762: 763: 764: 765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779: 780: 781: 782: 783: 784: 785: 786: 787: 788: 789: 790: 791: 792: 793: 794: 795: 796: 797: 798: 799: 800: 801: 802: 803: 804: 805: 806: 807: 808: 809: 810: 811: 812: 813: 814: 815: 816: 817: 818: 819: 820: 821: 822: 823: 824: 825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846: 847: 848: 849: 850: 851: 852: 853: 854: 855: 856: 857: 858: 859: 860: 861: 862: 863: 864: 865: 866: 867: 868: 869: 870: 871: 872: 873: 874: 875: 876: 877: 878: 879: 880: 881: 882: 883: 884: 885: 886: 887: 888: 889: 890: 891: 892: 893: 894: 895: 896: 897: 898: 899: 900: 901: 902: 903: 904: 905: 906: 907: 908: 909: 910: 911: 912: 913: 914: 915: 916: 917: 918: 919: 920: 921: 922: 923: 924: 925: 926: 927: 928: 929: 930: 931: 932: 933: 934: 935: 936: 937: 938: 939: 940: 941: 942: 943: 944: 945: 946: 947: 948: 949: 950: 951: 952: 953: 954: 955: 956: 957: 958: 959: 960: 961: 962: 963: 964: 965: 966: 967: 968: 969: 970: 971: 972: 973: 974: 975: 976: 977: 978: 979: 980: 981: 982: 983: 984: 985: 986: 987: 988: 989: 990: 991: 992: 993: 994: 995: 996: 997: 998: 999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023: 1024: 1025: 1026: 1027: 1028: 1029: 1030: 1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040: 1041: 1042: 1043: 1044: 1045: 1046: 1047: 1048: 1049: 1050: 1051: 1052: 1053: 1054: 1055: 1056: 1057: 1058: 1059: 1060: 1061: 1062: 1063: 1064: 1065: 1066: 1067: 1068: 1069: 1070: 1071: 1072: 1073: 1074: 1075: 1076: 1077: 1078: 1079: 1080: 1081: 1082: 1083: 1084: 1085: 1086: 1087: 1088: 1089: 1090: 1091: 1092: 1093: 1094: 1095: 1096: 1097: 1098: 1099: 1100: 1101: 1102: 1103: 1104: 1105: 1106: 1107: 1108: 1109: 1110: 1111: 1112: 1113: 1114: 1115: 1116: 1117: 1118: 1119: 1120: 1121: 1122: 1123: 1124: 1125: 1126: 1127: 1128: 1129: 1130: 1131: 1132: 1133: 1134: 1135: 1136: 1137: 1138: 1139: 1140: 1141: 1142: 1143: 1144: 1145: 1146: 1147: 1148: 1149: 1150: 1151: 1152: 1153: 1154: 1155: 1156: 1157: 1158: 1159: 1160: 1161: 1162: 1163: 1164: 1165: 1166: 1167: 1168: 1169: 1170: 1171: 1172: 1173: 1174: 1175: 1176: 1177: 1178: 1179: 1180: 1181: 1182: 1183: 1184: 1185: 1186: 1187: 1188: 1189: 1190: 1191: 1192: 1193: 1194: 1195: 1196: 1197: 1198: 1199: 1200: 1201: 1202: 1203: 1204: 1205: 1206: 1207: 1208: 1209: 1210: 1211: 1212: 1213: 1214: 1215: 1216: 1217: 1218: 1219: 1220: 1221: 1222: 1223: 1224: 1225: 1226: 1227: 1228: 1229: 1230: 1231: 1232: 1233: 1234: 1235: 1236: 1237: 1238: 1239: 1240: 1241: 1242: 1243: 1244: 1245: 1246: 1247: 1248: 1249: 1250: 1251: 1252: 1253: 1254: 1255: 1256: 1257: 1258: 1259: 1260: 1261: 1262: 1263: 1264: 1265: 1266: 1267: 1268: 1269: 1270: 1271: 1272: 1273: 1274: 1275: 1276: 1277: 1278: 1279: 1280: 1281: 1282: 1283: 1284: 1285: 1286: 1287: 1288: 1289: 1290: 1291: 1292: 1293: 1294: 1295: 1296: 1297: 1298: 1299: 1300: 1301: 1302: 1303: 1304: 1305: 1306: 1307: 1308: 1309: 1310: 1311: 1312: 1313: 1314: 1315: 1316: 1317: 1318: 1319: 1320: 1321: 1322: 1323: 1324: 1325: 1326: 1327: 1328: 1329: 1330: 1331: 1332: 1333: 1334: 1335: 1336: 1337: 1338: 1339: 1340: 1341: 1342: 1343: 1344: 1345: 1346: 1347: 1348: 1349: 1350: 1351: 1352: 1353: 1354: 1355: 1356: 1357: 1358: 1359: 1360: 1361: 1362: 1363: 1364: 1365: 1366: 1367: 1368: 1369: 1370: 1371: 1372: 1373: 1374: 1375: 1376: 1377: 1378: 1379: 1380: 1381: 1382: 1383: 1384: 1385: 1386: 1387: 1388: 1389: 1390: 1391: 1392: 1393: 1394: 1395: 1396: 1397: 1398: 1399: 1400: 1401: 1402: 1403: 1404: 1405: 1406: 1407: 1408: 1409: 1410: 1411: 1412: 1413: 1414: 1415: 1416: 1417: 1418: 1419: 1420: 1421: 1422: 1423: 1424: 1425: 1426: 1427: 1428: 1429: 1430: 1431: 1432: 1433: 1434: 1435: 1436: 1437: 1438: 1439: 1440: 1441: 1442: 1443: 1444: 1445: 1446: 1447: 1448: 1449: 1450: 1451: 1452: 1453: 1454: 1455: 1456: 1457: 1458: 1459: 1460: 1461: 1462: 1463: 1464: 1465: 1466: 1467: 1468: 1469: 1470: 1471: 1472: 1473: 1474: 1475: 1476: 1477: 1478: 1479: 1480: 1481: 1482: 1483: 1484: 1485: 1486: 1487: 1488: 1489: 1490: 1491: 1492: 1493: 1494: 1495: 1496: 1497: 1498: 1499: 1500: 1501: 1502: 1503: 1504: 1505: 1506: 1507: 1508: 1509: 1510: 1511: 1512: 1513: 1514: 1515: 1516: 1517: 1518: 1519: 1520: 1521: 1522: 1523: 1524: 1525: 1526: 1527: 1528: 1529: 1530: 1531: 1532: 1533: 1534: 1535: 1536: 1537: 1538: 1539: 1540: 1541: 1542: 1543: 1544: 1545: 1546: 1547: 1548: 1549: 1550: 1551: 1552: 1553: 1554: 1555: 1556: 1557: 1558: 1559: 1560: 1561: 1562: 1563: 1564: 1565: 1566: 1567: 1568: 1569: 1570: 1571: 1572: 1573: 1574: 1575: 1576: 1577: 1578: 1579: 1580: 1581: 1582: 1583: 1584: 1585: 1586: 1587: 1588: 1589: 1590: 1591: 1592: 1593: 1594: 1595: 1596: 1597: 1598: 1599: 1600: 1601: 1602: 1603: 1604: 1605: 1606: 1607: 1608: 1609: 1610: 1611: 1612: 1613: 1614: 1615: 1616: 1617: 1618: 1619: 1620: 1621: 1622: 1623: 1624: 1625: 1626: 1627: 1628: 1629: 1630: 1631: 1632: 1633: 1634: 1635: 1636: 1637: 1638: 1639: 1640: 1641: 1642: 1643: 1644: 1645: 1646: 1647: 1648: 1649: 1650: 1651: 1652: 1653: 1654: 1655: 1656: 1657: 1658: 1659: 1660: 1661: 1662: 1663: 1664: 1665: 1666: 1667: 1668: 1669: 1670: 1671: 1672: 1673: 1674: 1675: 1676: 1677: 1678: 1679: 1680: 1681: 1682: 1683: 1684: 1685: 1686: 1687: 1688: 1689: 1690: 1691: 1692: 1693: 1694: 1695: 1696: 1697: 1698: 1699: 1700: 1701: 1702: 1703: 1704: 1705: 1706: 1707: 1708: 1709: 1710: 1711: 1712: 1713: 1714: 1715: 1716: 1717: 1718: 1719: 1720: 1721: 1722: 1723: 1724: 1725: 1726: 1727: 1728: 1729: 1730: 1731: 1732: 1733: 1734: 1735: 1736: 1737: 1738: 1739: 1740: 1741: 1742: 1743: 1744: 1745: 1746: 1747: 1748: 1749: 1750: 1751: 1752: 1753: 1754: 1755: 1756: 1757: 1758: 1759: 1760: 1761: 1762: 1763: 1764: 1765: 1766: 1767: 1768: 1769: 1770: 1771: 1772: 1773: 1774: 1775: 1776: 1777: 1778: 1779: 1780: 1781: 1782: 1783: 1784: 1785: 1786: 1787: 1788: 1789: 1790: 1791: 1792: 1793: 1794: 1795: 1796: 1797: 1798: 1799: 1800: 1801: 1802: 1803: 1804: 1805: 1806: 1807: 1808: 1809: 1810: 1811: 1812: 1813: 1814: 1815: 1816: 1817: 1818: 1819: 1820: 1821: 1822: 1823: 1824: 1825: 1826: 1827: 1828: 1829: 1830: 1831: 1832: 1833: 1834: 1835: 1836: 1837: 1838: 1839: 1840: 1841: 1842: 1843: 1844: 1845: 1846: 1847: 1848: 1849: 1850: 1851: 1852: 1853: 1854: 1855: 1856: 1857: 1858: 1859: 1860: 1861: 1862: 1863: 1864: 1865: 1866: 1867: 1868: 1869: 1870: 1871: 1872: 1873: 1874: 1875: 1876: 1877: 1878: 1879: 1880: 1881: 1882: 1883: 1884: 1885: 1886: 1887: 1888: 1889: 1890: 1891: 1892: 1893: 1894: 1895: 1896: 1897: 1898: 1899: 1900: 1901: 1902: 1903: 1904: 1905: 1906: 1907: 1908: 1909: 1910: 1911: 1912: 1913: 1914: 1915: 1916: 1917: 1918: 1919: 1920: 1921: 1922: 1923: 1924: 1925: 1926: 1927: 1928: 1929: 1930: 1931: 1932: 1933: 1934: 1935: 1936: 1937: 1938: 1939: 1940: 1941: 1942: 1943: 1944: 1945: 1946: 1947: 1948: 1949: 1950: 1951: 1952: 1953: 1954: 1955: 1956: 1957: 1958: 1959: 1960: 1961: 1962: 1963: 1964: 1965: 1966: 1967: 1968: 1969: 1970: 1971: 1972: 1973: 1974: 1975: 1976: 1977: 1978: 1979: 1980: 1981: 1982: 1983: 1984: 1985: 1986: 1987: 1988: 1989: 1990: 1991: 1992: 1993: 1994: 1995: 1996: 1997: 1998: 1999: 2000: 2001: 2002: 2003: 2004: 2005: 2006: 2007: 2008: 2009: 2010: 2011: 2012: 2013: 2014: 2015: 2016: 2017: 2018: 2019: 2020: 2021: 2022: 2023: 2024: 2025: 2026: 2027: 2028: 2029: 2030: 2031: 2032: 2033: 2034: 2035: 2036: 2037: 2038: 2039: 2040: 2041: 2042: 2043: 2044: 2045: 2046: 2047: 2048: 2049: 2050: 2051: 2052: 2053: 2054: 2055: 2056: 2057: 2058: 2059: 2060: 2061: 2062: 2063: 2064: 2065: 2066: 2067: 2068: 2069: 2070: 2071: 2072: 2073: 2074: 2075: 2076: 2077: 2078: 2079: 2080: 2081: 2082: 2083: 2084: 2085: 2086: 2087: 2088: 2089: 2090: 2091: 2092: 2093: 2094: 2095: 2096: 2097: 2098: 2099: 2100: 2101: 2102: 2103: 2104: 2105: 2106: 2107: 2108: 2109: 2110: 2111: 2112: 2113: 2114: 2115: 2116: 2117: 2118: 2119: 2120: 2121: 2122: 2123: 2124: 2125: 2126: 2127: 2128: 2129: 2130: 2131: 2132: 2133: 2134: 2135: 2136: 2137: 2138: 2139: 2140: 2141: 2142: 2143: 2144: 2145: 2146: 2147: 2148: 2149: 2150: 2151: 2152: 2153: 2154: 2155: 2156: 2157: 2158: 2159: 2160: 2161: 2162: 2163: 2164: 2165: 2166: 2167: 2168: 2169: 2170: 2171: 2172: 2173: 2174: 2175: 2176: 2177: 2178: 2179: 2180: 2181: 2182: 2183: 2184: 2185: 2186: 2187: 2188: 2189: 2190: 2191: 2192: 2193: 2194: 2195: 2196: 2197: 2198: 2199: 2200: 2201: 2202: 2203: 2204: 2205: 2206: 2207: 2208: 2209: 2210: 2211: 2212: 2213: 2214: 2215: 2216: 2217: 2218: 2219: 2220: 2221: 2222: 2223: 2224: 2225: 2226: 2227: 2228: 2229: 2230: 2231: 2232: 2233: 2234: 2235: 2236: 2237: 2238: 2239: 2240: 2241: 2242: 2243: 2244: 2245: 2246: 2247: 2248: 2249: 2250: 2251: 2252: 2253: 2254: 2255: 2256: 2257: 2258: 2259: 2260: 2261: 2262: 2263: 2264: 2265: 2266: 2267: 2268: 2269: 2270: 2271: 2272: 2273: 2274: 2275: 2276: 2277: 2278: 2279: 2280: 2281: 2282: 2283: 2284: 2285: 2286: 2287: 2288: 2289: 2290: 2291: 2292: 2293: 2294: 2295: 2296: 2297: 2298: 2299: 2300: 2301: 2302: 2303: 2304: 2305: 2306: 2307: 2308: 2309: 2310: 2311: 2312: 2313: 2314: 2315: 2316: 2317: 2318: 2319: 2320: 2321: 2322: 2323: 2324: 2325: 2326: 2327: 2328: 2329: 2330: 2331: 2332: 2333: 2334: 2335: 2336: 2337: 2338: 2339: 2340: 2341: 2342: 2343: 2344: 2345: 2346: 2347: 2348: 2349: 2350: 2351: 2352: 2353: 2354: 2355: 2356: 2357: 2358: 2359: 2360: 2361: 2362: 2363: 2364: 2365: 2366: 2367: 2368: 2369: 2370: 2371: 2372: 2373: 2374: 2375: 2376: 2377: 2378: 2379: 2380: 2381: 2382: 2383: 2384: 2385: 2386: 2387: 2388: 2389: 2390: 2391: 2392: 2393: 2394: 2395: 2396: 2397: 2398: 2399: 2400: 2401: 2402: 2403: 2404: 2405: 2406: 2407: 2408: 2409: 2410: 2411: 2412: 2413: 2414: 2415: 2416: 2417: 2418: 2419: 2420: 2421: 2422: 2423: 2424: 2425: 2426: 2427: 2428: 2429: 2430: 2431: 2432: 2433: 2434: 2435: 2436: 2437: 2438: 2439: 2440: 2441: 2442: 2443: 2444: 2445: 2446: 2447: 2448: 2449: 2450: 2451: 2452: 2453: 2454: 2455: 2456: 2457: 2458: 2459: 2460: 2461: 2462: 2463: 2464: 2465: 2466: 2467: 2468: 2469: 2470: 2471: 2472: 2473: 2474: 2475: 2476: 2477: 2478: 2479: 2480: 2481:
<?php
if (!defined('SMF'))
die('No direct access...');
function bbc_to_html($text, $compat_mode = false)
{
global $modSettings;
if (!$compat_mode)
return $text;
$text = strtr($text, array("\r" => '', "\n" => '<br>'));
foreach (array('code', 'php', 'nobbc') as $code)
{
if (strpos($text, '[' . $code) !== false)
{
$parts = preg_split('~(\[/' . $code . '\]|\[' . $code . '(?:=[^\]]+)?\])~i', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0, $n = count($parts); $i < $n; $i++)
{
if ($i % 4 == 2)
$parts[$i] = strtr($parts[$i], array('[' => '[', ']' => ']', "'" => "'"));
}
$text = implode('', $parts);
}
}
$allowed_tags = array('b', 'u', 'i', 's', 'hr', 'list', 'li', 'font', 'size', 'color', 'img', 'left', 'center', 'right', 'url', 'email', 'ftp', 'sub', 'sup');
$text = parse_bbc($text, true, '', $allowed_tags);
$text = strtr($text, array('<br><div' => '<div', "\n" => '', "\r" => ''));
$working_html = array(
'~<del>(.+?)</del>~i' => '<strike>$1</strike>',
'~<span\sclass="bbc_u">(.+?)</span>~i' => '<u>$1</u>',
'~<span\sstyle="color:\s*([#\d\w]+);" class="bbc_color">(.+?)</span>~i' => '<font color="$1">$2</font>',
'~<span\sstyle="font-family:\s*([#\d\w\s]+);" class="bbc_font">(.+?)</span>~i' => '<font face="$1">$2</font>',
'~<div\sstyle="text-align:\s*(left|right);">(.+?)</div>~i' => '<p align="$1">$2</p>',
);
$text = preg_replace(array_keys($working_html), array_values($working_html), $text);
$i = 1;
$text = preg_replace_callback('~(?:\s| )?<(img\ssrc="' . preg_quote($modSettings['smileys_url'], '~') . '/[^<>]+?/([^<>]+?)"\s*)[^<>]*?class="smiley">~',
function($m) use (&$i)
{
return '<' . stripslashes($m[1]) . 'alt="" title="" onresizestart="return false;" id="smiley_' . $i++ . '_' . $m[2] . '" style="padding: 0 3px 0 3px;">';
}, $text);
return $text;
}
function html_to_bbc($text)
{
global $modSettings, $smcFunc, $scripturl, $context;
$text = preg_replace("~\s*[\r\n]+\s*~", ' ', $text);
$text = preg_replace('~</p>\s*?<p~i', '</p><br><p', $text);
$text = preg_replace('~</p>\s*(?!<)~i', '</p><br>', $text);
if (isBrowser('webkit'))
$text = preg_replace(array('~<div(?:\s(?:[^<>]*?))?' . '>~i', '</div>'), array('<br>', ''), $text);
$text = preg_replace('~<br\s?/?' . '>$~i', '', $text);
if (strpos($text, '[code') !== false)
{
$text = preg_replace('~<br\s?/?' . '>~i', '#smf_br_spec_grudge_cool!#', $text);
$parts = preg_split('~(\[/code\]|\[code(?:=[^\]]+)?\])~i', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0, $n = count($parts); $i < $n; $i++)
{
if ($i % 4 == 2)
$parts[$i] = strip_tags($parts[$i]);
}
$text = strtr(implode('', $parts), array('#smf_br_spec_grudge_cool!#' => '<br>'));
}
$text = preg_replace('~<script[^>]*[^/]?' . '>.*?</script>~i', '', $text);
$text = preg_replace('~<style[^>]*[^/]?' . '>.*?</style>~i', '', $text);
$text = preg_replace('~\\<\\!--.*?-->~i', '', $text);
$text = preg_replace('~\\<\\!\\[CDATA\\[.*?\\]\\]\\>~i', '', $text);
preg_match_all('~<img\b[^>]+alt="([^"]+)"[^>]+class="smiley"[^>]*>(?:\s)?~i', $text, $matches);
if (!empty($matches[0]))
{
$request = $smcFunc['db_query']('', '
SELECT code
FROM {db_prefix}smileys
ORDER BY LENGTH(code) DESC',
array()
);
$smiley_codes = $smcFunc['db_fetch_all']($request);
$smcFunc['db_free_result']($request);
foreach ($matches[1] as $k => $possible_code)
{
$possible_code = un_htmlspecialchars($possible_code);
if (in_array($possible_code, $smiley_codes))
$matches[1][$k] = '-[]-smf_smily_start#|#' . $possible_code . '-[]-smf_smily_end#|#';
else
$matches[1][$k] = $matches[0][$k];
}
$text = str_replace($matches[0], $matches[1], $text);
$text = str_replace(array('-[]-smf_smily_end#|#-[]-smf_smily_start#|#', '-[]-smf_smily_end#|#', '-[]-smf_smily_start#|#'), ' ', $text);
}
if (connection_aborted() && $context['server']['is_apache'])
@apache_reset_timeout();
$parts = preg_split('~(<[A-Za-z]+\s*[^<>]*?style="?[^<>"]+"?[^<>]*?(?:/?)>|</[A-Za-z]+>)~', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
$replacement = '';
$stack = array();
foreach ($parts as $part)
{
if (preg_match('~(<([A-Za-z]+)\s*[^<>]*?)style="?([^<>"]+)"?([^<>]*?(/?)>)~', $part, $matches) === 1)
{
if ($matches[5] === '/')
continue;
else
{
$styles = explode(';', strtr($matches[3], array('"' => '')));
$curElement = $matches[2];
$precedingStyle = $matches[1];
$afterStyle = $matches[4];
$curCloseTags = '';
$extra_attr = '';
foreach ($styles as $type_value_pair)
{
$clean_type_value_pair = strtolower(strtr(trim($type_value_pair), '=', ':'));
if (strpos($clean_type_value_pair, ':') === false)
continue;
list ($style_type, $style_value) = explode(':', $type_value_pair);
$style_value = trim($style_value);
switch (trim($style_type))
{
case 'font-weight':
if ($style_value === 'bold')
{
$curCloseTags .= '[/b]';
$replacement .= '[b]';
}
break;
case 'text-decoration':
if ($style_value == 'underline')
{
$curCloseTags .= '[/u]';
$replacement .= '[u]';
}
elseif ($style_value == 'line-through')
{
$curCloseTags .= '[/s]';
$replacement .= '[s]';
}
break;
case 'text-align':
if ($style_value == 'left')
{
$curCloseTags .= '[/left]';
$replacement .= '[left]';
}
elseif ($style_value == 'center')
{
$curCloseTags .= '[/center]';
$replacement .= '[center]';
}
elseif ($style_value == 'right')
{
$curCloseTags .= '[/right]';
$replacement .= '[right]';
}
break;
case 'font-style':
if ($style_value == 'italic')
{
$curCloseTags .= '[/i]';
$replacement .= '[i]';
}
break;
case 'color':
$curCloseTags .= '[/color]';
$replacement .= '[color=' . $style_value . ']';
break;
case 'font-size':
if (preg_match('~(\d)+\.\d+(p[xt])~i', $style_value, $dec_matches) === 1)
$style_value = $dec_matches[1] . $dec_matches[2];
$curCloseTags .= '[/size]';
$replacement .= '[size=' . $style_value . ']';
break;
case 'font-family':
if (strpos($style_value, ',') !== false)
$style_value = substr($style_value, 0, strpos($style_value, ','));
$curCloseTags .= '[/font]';
$replacement .= '[font=' . strtr($style_value, array("'" => '')) . ']';
break;
case 'width':
case 'height':
if (preg_match('~[1-9]\d*~i', $style_value, $dimension) === 1)
$extra_attr .= ' ' . $style_type . '="' . $dimension[0] . '"';
break;
case 'list-style-type':
if (preg_match('~none|disc|circle|square|decimal|decimal-leading-zero|lower-roman|upper-roman|lower-alpha|upper-alpha|lower-greek|lower-latin|upper-latin|hebrew|armenian|georgian|cjk-ideographic|hiragana|katakana|hiragana-iroha|katakana-iroha~i', $style_value, $listType) === 1)
$extra_attr .= ' listtype="' . $listType[0] . '"';
break;
}
}
if (in_array($matches[2], array('a', 'font', 'td')))
{
$replacement .= $precedingStyle . $afterStyle;
$curCloseTags = '</' . $matches[2] . '>' . $curCloseTags;
}
if (!empty($curCloseTags))
array_push($stack, array(
'element' => strtolower($curElement),
'closeTags' => $curCloseTags
)
);
elseif (!empty($extra_attr))
$replacement .= $precedingStyle . $extra_attr . $afterStyle;
}
}
elseif (preg_match('~</([A-Za-z]+)>~', $part, $matches) === 1)
{
if (!empty($stack) && strtolower($matches[1]) === $stack[count($stack) - 1]['element'])
{
$byebyeTag = array_pop($stack);
$replacement .= $byebyeTag['closeTags'];
}
else
$replacement .= $part;
}
else
$replacement .= $part;
}
$text = $replacement;
if (connection_aborted() && $context['server']['is_apache'])
@apache_reset_timeout();
while (preg_match('~<([A-Za-z]+)\s+[^<>]*?(align="*(left|center|right)"*)[^<>]*?(/?)>~i', $text, $matches) === 1)
{
$start_pos = strpos($text, $matches[0]);
if ($start_pos === false)
break;
if ($matches[4] != '/' && strpos($text, '</' . $matches[1] . '>', $start_pos) !== false)
{
$end_pos = strpos($text, '</' . $matches[1] . '>', $start_pos);
$tag = substr($text, $start_pos, strlen($matches[0]));
$content = substr($text, $start_pos + strlen($matches[0]), $end_pos - $start_pos - strlen($matches[0]));
$tag = str_replace($matches[2], '', $tag);
$text = substr($text, 0, $start_pos) . $tag . '[' . $matches[3] . ']' . $content . '[/' . $matches[3] . ']' . substr($text, $end_pos);
}
else
{
$text = substr($text, 0, $start_pos) . substr($text, $start_pos + strlen($matches[0]));
}
}
while (preg_match('~<font\s+([^<>]*)>~i', $text, $matches) === 1)
{
$start_pos = strpos($text, $matches[0]);
$end_pos = false;
if ($start_pos === false)
break;
$lower_text = strtolower($text);
$start_pos_test = $start_pos + 4;
$start_font_tag_stack = 0;
while ($start_pos_test < strlen($text))
{
$next_start_pos = strpos($lower_text, '<font', $start_pos_test);
$next_end_pos = strpos($lower_text, '</font>', $start_pos_test);
if ($next_start_pos !== false && $next_start_pos < $next_end_pos)
{
$start_font_tag_stack++;
$start_pos_test = $next_start_pos + 4;
}
elseif ($start_font_tag_stack)
{
$start_font_tag_stack--;
$start_pos_test = $next_end_pos + 4;
}
else
{
$end_pos = $next_end_pos;
break;
}
}
if ($end_pos === false)
break;
$attribs = fetchTagAttributes($matches[1]);
$tags = array();
$sizes_equivalence = array(1 => '8pt', '10pt', '12pt', '14pt', '18pt', '24pt', '36pt');
foreach ($attribs as $s => $v)
{
if ($s == 'size')
{
$v = (int) trim($v);
$v = empty($v) ? 1 : $v;
$tags[] = array('[size=' . $sizes_equivalence[$v] . ']', '[/size]');
}
elseif ($s == 'face')
$tags[] = array('[font=' . trim(strtolower($v)) . ']', '[/font]');
elseif ($s == 'color')
$tags[] = array('[color=' . trim(strtolower($v)) . ']', '[/color]');
}
$before = $after = '';
foreach ($tags as $tag)
{
$before .= $tag[0];
if (isset($tag[1]))
$after = $tag[1] . $after;
}
$content = substr($text, $start_pos + strlen($matches[0]), $end_pos - $start_pos - strlen($matches[0]));
$text = substr($text, 0, $start_pos) . $before . $content . $after . substr($text, $end_pos + 7);
}
if (connection_aborted() && $context['server']['is_apache'])
@apache_reset_timeout();
if (count($parts = preg_split('~<(/?)(li|ol|ul)([^>]*)>~i', $text, null, PREG_SPLIT_DELIM_CAPTURE)) > 1)
{
$inList = false;
$listDepth = 0;
$listTypeMapping = array(
'1' => 'decimal',
'A' => 'upper-alpha',
'a' => 'lower-alpha',
'I' => 'upper-roman',
'i' => 'lower-roman',
'disc' => 'disc',
'square' => 'square',
'circle' => 'circle',
);
for ($i = 0, $numParts = count($parts) - 1; $i < $numParts; $i += 4)
{
$tag = strtolower($parts[$i + 2]);
$isOpeningTag = $parts[$i + 1] === '';
if ($isOpeningTag)
{
switch ($tag)
{
case 'ol':
case 'ul':
if ($inList)
{
array_splice($parts, $i, 0, array(
'',
'',
str_repeat("\t", $listDepth) . '[li]',
'',
));
$numParts = count($parts) - 1;
$inList = false;
}
else
{
$inList = true;
if ($tag === 'ol')
$listType = 'decimal';
elseif (preg_match('~type="?(' . implode('|', array_keys($listTypeMapping)) . ')"?~', $parts[$i + 3], $match) === 1)
$listType = $listTypeMapping[$match[1]];
else
$listType = null;
$listDepth++;
$parts[$i + 2] = '[list' . ($listType === null ? '' : ' type=' . $listType) . ']' . "\n";
$parts[$i + 3] = '';
}
break;
case 'li':
if ($inList)
{
$parts[$i + 2] = str_repeat("\t", $listDepth) . '[li]';
$parts[$i + 3] = '';
$inList = false;
}
else
{
if ($listDepth > 0)
{
$parts[$i + 2] = '[/li]' . "\n" . str_repeat("\t", $listDepth) . '[li]';
$parts[$i + 3] = '';
}
else
{
$listDepth++;
$parts[$i + 2] = '[list]' . "\n\t" . '[li]';
$parts[$i + 3] = '';
}
}
break;
}
}
else
{
switch ($tag)
{
case 'ol':
case 'ul':
if ($inList)
{
$inList = false;
$listDepth--;
$parts[$i + 1] = '';
$parts[$i + 2] = str_repeat("\t", $listDepth) . '[/list]';
$parts[$i + 3] = '';
}
else
{
if ($listDepth > 0)
{
array_splice($parts, $i + 1, 0, array(
'',
'[/li]' . "\n",
'',
'',
));
$numParts = count($parts) - 1;
$inList = true;
}
else
{
$parts[$i + 1] = '';
$parts[$i + 2] = '';
$parts[$i + 3] = '';
}
}
break;
case 'li':
if ($inList)
{
$parts[$i + 1] = '';
$parts[$i + 2] = '';
$parts[$i + 3] = '';
}
else
{
$parts[$i] = preg_replace('~\s*<br\s*' . '/?' . '>\s*$~', '', $parts[$i]);
$parts[$i + 1] = '';
$parts[$i + 2] = '[/li]' . "\n";
$parts[$i + 3] = '';
$inList = true;
}
break;
}
}
if ($inList && trim(preg_replace('~\s*<br\s*' . '/?' . '>\s*~', '', $parts[$i + 4])) !== '')
{
array_splice($parts, $i + 4, 0, array(
'',
'',
'li',
'',
));
$numParts = count($parts) - 1;
}
}
$text = implode('', $parts);
if ($inList)
{
$listDepth--;
$text .= str_repeat("\t", $listDepth) . '[/list]';
}
for ($i = $listDepth; $i > 0; $i--)
$text .= '[/li]' . "\n" . str_repeat("\t", $i - 1) . '[/list]';
}
while (preg_match('~<img\s+([^<>]*)/*>~i', $text, $matches) === 1)
{
$start_pos = strpos($text, $matches[0]);
if ($start_pos === false)
break;
$end_pos = $start_pos + strlen($matches[0]);
$params = '';
$src = '';
$attrs = fetchTagAttributes($matches[1]);
foreach ($attrs as $attrib => $value)
{
if (in_array($attrib, array('width', 'height')))
$params .= ' ' . $attrib . '=' . (int) $value;
elseif ($attrib == 'alt' && trim($value) != '')
$params .= ' alt=' . trim($value);
elseif ($attrib == 'src')
$src = trim($value);
}
$tag = '';
if (!empty($src))
{
if (preg_match('~^https?://~i', $src) === 0 && is_array($parsedURL = parse_url($scripturl)) && isset($parsedURL['host']))
{
$baseURL = (isset($parsedURL['scheme']) ? $parsedURL['scheme'] : 'http') . '://' . $parsedURL['host'] . (empty($parsedURL['port']) ? '' : ':' . $parsedURL['port']);
if (substr($src, 0, 1) === '/')
$src = $baseURL . $src;
else
$src = $baseURL . (empty($parsedURL['path']) ? '/' : preg_replace('~/(?:index\\.php)?$~', '', $parsedURL['path'])) . '/' . $src;
}
$tag = '[img' . $params . ']' . $src . '[/img]';
}
$text = substr($text, 0, $start_pos) . $tag . substr($text, $end_pos);
}
$tags = array(
'~<b(\s(.)*?)*?' . '>~i' => function()
{
return '[b]';
},
'~</b>~i' => function()
{
return '[/b]';
},
'~<i(\s(.)*?)*?' . '>~i' => function()
{
return '[i]';
},
'~</i>~i' => function()
{
return '[/i]';
},
'~<u(\s(.)*?)*?' . '>~i' => function()
{
return '[u]';
},
'~</u>~i' => function()
{
return '[/u]';
},
'~<strong(\s(.)*?)*?' . '>~i' => function()
{
return '[b]';
},
'~</strong>~i' => function()
{
return '[/b]';
},
'~<em(\s(.)*?)*?' . '>~i' => function()
{
return '[i]';
},
'~</em>~i' => function()
{
return '[i]';
},
'~<s(\s(.)*?)*?' . '>~i' => function()
{
return "[s]";
},
'~</s>~i' => function()
{
return "[/s]";
},
'~<strike(\s(.)*?)*?' . '>~i' => function()
{
return '[s]';
},
'~</strike>~i' => function()
{
return '[/s]';
},
'~<del(\s(.)*?)*?' . '>~i' => function()
{
return '[s]';
},
'~</del>~i' => function()
{
return '[/s]';
},
'~<center(\s(.)*?)*?' . '>~i' => function()
{
return '[center]';
},
'~</center>~i' => function()
{
return '[/center]';
},
'~<pre(\s(.)*?)*?' . '>~i' => function()
{
return '[pre]';
},
'~</pre>~i' => function()
{
return '[/pre]';
},
'~<sub(\s(.)*?)*?' . '>~i' => function()
{
return '[sub]';
},
'~</sub>~i' => function()
{
return '[/sub]';
},
'~<sup(\s(.)*?)*?' . '>~i' => function()
{
return '[sup]';
},
'~</sup>~i' => function()
{
return '[/sup]';
},
'~<tt(\s(.)*?)*?' . '>~i' => function()
{
return '[tt]';
},
'~</tt>~i' => function()
{
return '[/tt]';
},
'~<table(\s(.)*?)*?' . '>~i' => function()
{
return '[table]';
},
'~</table>~i' => function()
{
return '[/table]';
},
'~<tr(\s(.)*?)*?' . '>~i' => function()
{
return '[tr]';
},
'~</tr>~i' => function()
{
return '[/tr]';
},
'~<(td|th)\s[^<>]*?colspan="?(\d{1,2})"?.*?' . '>~i' => function($matches)
{
return str_repeat('[td][/td]', $matches[2] - 1) . '[td]';
},
'~<(td|th)(\s(.)*?)*?' . '>~i' => function()
{
return '[td]';
},
'~</(td|th)>~i' => function()
{
return '[/td]';
},
'~<br(?:\s[^<>]*?)?' . '>~i' => function()
{
return "\n";
},
'~<hr[^<>]*>(\n)?~i' => function($matches)
{
return "[hr]\n" . $matches[0];
},
'~(\n)?\\[hr\\]~i' => function()
{
return "\n[hr]";
},
'~^\n\\[hr\\]~i' => function()
{
return "[hr]";
},
'~<blockquote(\s(.)*?)*?' . '>~i' => function()
{
return "<blockquote>";
},
'~</blockquote>~i' => function()
{
return "</blockquote>";
},
'~<ins(\s(.)*?)*?' . '>~i' => function()
{
return "<ins>";
},
'~</ins>~i' => function()
{
return "</ins>";
},
);
foreach ($tags as $tag => $replace)
$text = preg_replace_callback($tag, $replace, $text);
if (connection_aborted() && $context['server']['is_apache'])
@apache_reset_timeout();
while (preg_match('~<a\s+([^<>]*)>([^<>]*)</a>~i', $text, $matches) === 1)
{
$start_pos = strpos($text, $matches[0]);
if ($start_pos === false)
break;
$end_pos = $start_pos + strlen($matches[0]);
$tag_type = 'url';
$href = '';
$attrs = fetchTagAttributes($matches[1]);
foreach ($attrs as $attrib => $value)
{
if ($attrib == 'href')
{
$href = trim($value);
if (preg_match('~^ftps?://~', $href) === 1)
$tag_type = 'ftp';
elseif (substr($href, 0, 7) == 'mailto:')
{
$tag_type = 'email';
$href = substr($href, 7);
}
elseif (preg_match('~^https?://~i', $href) === 0 && is_array($parsedURL = parse_url($scripturl)) && isset($parsedURL['host']))
{
$baseURL = (isset($parsedURL['scheme']) ? $parsedURL['scheme'] : 'http') . '://' . $parsedURL['host'] . (empty($parsedURL['port']) ? '' : ':' . $parsedURL['port']);
if (substr($href, 0, 1) === '/')
$href = $baseURL . $href;
else
$href = $baseURL . (empty($parsedURL['path']) ? '/' : preg_replace('~/(?:index\\.php)?$~', '', $parsedURL['path'])) . '/' . $href;
}
}
if ($attrib == 'target' && $tag_type == 'url')
{
if (trim($value) == '_blank')
$tag_type == 'iurl';
}
}
$tag = '';
if ($href != '')
{
if ($matches[2] == $href)
$tag = '[' . $tag_type . ']' . $href . '[/' . $tag_type . ']';
else
$tag = '[' . $tag_type . '=' . $href . ']' . $matches[2] . '[/' . $tag_type . ']';
}
$text = substr($text, 0, $start_pos) . $tag . substr($text, $end_pos);
}
$text = strip_tags($text);
$text = preg_replace('~\[[bisu]\]\s*\[/[bisu]\]~', '', $text);
$text = preg_replace('~&~i', '&#38;', $text);
$text = legalise_bbc($text);
return $text;
}
function fetchTagAttributes($text)
{
$attribs = array();
$key = $value = '';
$tag_state = 0;
for ($i = 0; $i < strlen($text); $i++)
{
if ($text[$i] == '=')
{
if ($tag_state == 0)
$tag_state = 1;
elseif ($tag_state == 2)
$value .= '=';
}
elseif ($text[$i] == ' ')
{
if ($tag_state == 2)
$value .= ' ';
elseif ($tag_state == 1)
{
$attribs[$key] = $value;
$key = $value = '';
$tag_state = 0;
}
}
elseif ($text[$i] == '"')
{
if ($tag_state == 1)
$tag_state = 2;
else
$tag_state = 1;
}
else
{
if ($tag_state == 0)
$key .= $text[$i];
else
$value .= $text[$i];
}
}
if ($key != '' && $value != '')
$attribs[$key] = $value;
return $attribs;
}
function legalise_bbc($text)
{
global $modSettings;
if (strlen($text) < 3)
return $text;
$disabled = empty($modSettings['disabledBBC']) ? array() : array_flip(explode(',', strtolower($modSettings['disabledBBC'])));
$all_tags = parse_bbc(false);
$valid_tags = array();
$self_closing_tags = array();
foreach ($all_tags as $tag)
{
if (!isset($disabled[$tag['tag']]))
$valid_tags[$tag['tag']] = !empty($tag['block_level']);
if (isset($tag['type']) && $tag['type'] == 'closed')
$self_closing_tags[] = $tag['tag'];
}
$align_tags = array('left', 'center', 'right', 'pre');
$align_tags = array_intersect($align_tags, array_keys($valid_tags));
if (!empty($align_tags) && count($matches = preg_split('~(\\[/?(?:' . implode('|', $align_tags) . ')\\])~', $text, -1, PREG_SPLIT_DELIM_CAPTURE)) > 1)
{
$isTag = false;
$insideTag = null;
foreach ($matches as $i => $match)
{
if ($isTag)
{
$isClosingTag = substr($match, 1, 1) === '/';
$tagName = substr($match, $isClosingTag ? 2 : 1, -1);
if ($isClosingTag && $insideTag === $tagName)
$insideTag = null;
elseif (!$isClosingTag && $insideTag === null)
$insideTag = $tagName;
else
unset($matches[$i]);
}
$isTag = !$isTag;
}
if ($insideTag !== null)
$matches[] = '[/' . $insideTag . ']';
$text = implode('', $matches);
}
$backToBackPattern = '~\\[(' . implode('|', array_diff(array_keys($valid_tags), array('td', 'anchor'))) . ')[^<>\\[\\]]*\\]\s*\\[/\\1\\]~';
$lastlen = 0;
while (strlen($text) !== $lastlen)
$lastlen = strlen($text = preg_replace($backToBackPattern, '', $text));
uksort($valid_tags, function($a, $b)
{
return strlen($a) < strlen($b) ? 1 : -1;
});
$competing_tags = array(
'color',
'size',
);
if (count($parts = preg_split(sprintf('~(\\[)(/?)(%1$s)((?:[\\s=][^\\]\\[]*)?\\])~', implode('|', array_keys($valid_tags))), $text, -1, PREG_SPLIT_DELIM_CAPTURE)) > 1)
{
$inCode = false;
$inNoBbc = false;
$inlineElements = array();
$blockElements = array();
$competingElements = array();
for ($i = 0, $n = count($parts) - 1; $i < $n; $i += 5)
{
$tag = $parts[$i + 3];
$isOpeningTag = $parts[$i + 2] === '';
$isClosingTag = $parts[$i + 2] === '/';
$isBlockLevelTag = isset($valid_tags[$tag]) && $valid_tags[$tag] && !in_array($tag, $self_closing_tags);
$isCompetingTag = in_array($tag, $competing_tags);
if ($tag === '')
continue;
elseif ($tag === 'code')
{
if ($inCode && $isClosingTag)
{
$inCode = false;
if (!empty($inlineElements))
$parts[$i + 4] .= '[' . implode('][', array_keys($inlineElements)) . ']';
}
elseif (!$inCode && !$inNoBbc && $isOpeningTag)
{
if (!empty($inlineElements))
{
$parts[$i] .= '[/' . implode('][/', array_reverse($inlineElements)) . ']';
}
$inCode = true;
}
continue;
}
elseif ($tag === 'nobbc')
{
if ($inNoBbc && $isClosingTag)
{
$inNoBbc = false;
if (!empty($inlineElements))
$parts[$i + 4] .= '[' . implode('][', array_keys($inlineElements)) . ']';
}
elseif (!$inNoBbc && !$inCode && $isOpeningTag)
{
if (!empty($inlineElements))
{
$parts[$i] .= '[/' . implode('][/', array_reverse($inlineElements)) . ']';
}
$inNoBbc = true;
}
continue;
}
elseif ($inCode || $inNoBbc)
continue;
if ($isOpeningTag)
{
$elementContent = $parts[$i + 3] . substr($parts[$i + 4], 0, -1);
if ($isBlockLevelTag)
{
if (!empty($inlineElements))
{
$parts[$i] .= '[/' . implode('][/', array_reverse($inlineElements)) . ']';
$parts[$i + 5] = '[' . implode('][', array_keys($inlineElements)) . ']' . $parts[$i + 5];
}
$blockElements[] = $tag;
}
elseif (!in_array($tag, $self_closing_tags))
{
if (isset($inlineElements[$elementContent]))
{
$parts[$i + 1] = $parts[$i + 2] = $parts[$i + 3] = $parts[$i + 4] = '';
$curLevel = 1;
for ($j = $i + 5, $m = count($parts) - 1; $j < $m; $j += 5)
{
if ($parts[$j + 3] === $tag)
{
if ($parts[$j + 2] === '')
$curLevel++;
else
{
$curLevel--;
if ($curLevel === 0)
{
$parts[$j + 1] = $parts[$j + 2] = $parts[$j + 3] = $parts[$j + 4] = '';
break;
}
}
}
}
}
else
{
if ($isCompetingTag)
{
if (!isset($competingElements[$tag]))
$competingElements[$tag] = array();
$competingElements[$tag][] = $parts[$i + 4];
if (count($competingElements[$tag]) > 1)
$parts[$i] .= '[/' . $tag . ']';
}
$inlineElements[$elementContent] = $tag;
}
}
}
else
{
if ($isBlockLevelTag)
{
if (!empty($blockElements))
{
$addClosingTags = array();
while ($element = array_pop($blockElements))
{
if ($element === $tag)
break;
$addClosingTags[] = $element['type'];
}
if (!empty($addClosingTags))
$parts[$i + 1] = '[/' . implode('][/', array_reverse($addClosingTags)) . ']' . $parts[$i + 1];
if (!is_string($element) || $element !== $tag)
{
$parts[$i + 1] = substr($parts[$i + 1], 0, -1);
$parts[$i + 2] = $parts[$i + 3] = $parts[$i + 4] = '';
continue;
}
}
else
{
$parts[$i + 1] = $parts[$i + 2] = $parts[$i + 3] = $parts[$i + 4] = '';
continue;
}
if (!empty($inlineElements))
{
$parts[$i] .= '[/' . implode('][/', array_reverse($inlineElements)) . ']';
$parts[$i + 5] = '[' . implode('][', array_keys($inlineElements)) . ']' . $parts[$i + 5];
}
}
else
{
if (in_array($tag, $inlineElements))
{
foreach (array_reverse($inlineElements, true) as $tagContentToBeClosed => $tagToBeClosed)
{
unset($inlineElements[$tagContentToBeClosed]);
if ($tagToBeClosed === $tag)
break;
else
$parts[$i] .= '[/' . $tagToBeClosed . ']';
}
if ($isCompetingTag && !empty($competingElements[$tag]))
{
array_pop($competingElements[$tag]);
if (count($competingElements[$tag]) > 0)
$parts[$i + 5] = '[' . $tag . $competingElements[$tag][count($competingElements[$tag]) - 1] . $parts[$i + 5];
}
}
else
$parts[$i + 1] = $parts[$i + 2] = $parts[$i + 3] = $parts[$i + 4] = '';
}
}
}
if ($inCode)
$parts[$i] .= '[/code]';
elseif ($inNoBbc)
$parts[$i] .= '[/nobbc]';
elseif (!empty($inlineElements))
$parts[$i] .= '[/' . implode('][/', array_reverse($inlineElements)) . ']';
if (!empty($blockElements))
$parts[$i] .= '[/' . implode('][/', array_reverse($blockElements)) . ']';
$text = implode('', $parts);
}
$lastlen = 0;
while (strlen($text) !== $lastlen)
$lastlen = strlen($text = preg_replace($backToBackPattern, '', $text));
return $text;
}
function loadLocale()
{
global $context, $txt, $editortxt, $modSettings;
loadLanguage('Editor');
$context['template_layers'] = array();
@ob_end_clean();
if (!empty($modSettings['enableCompressedOutput']))
@ob_start('ob_gzhandler');
else
@ob_start();
if (empty($txt['lang_locale']))
die();
$file_data = '(function ($) {
\'use strict\';
$.sceditor.locale[' . JavaScriptEscape($txt['lang_locale']) . '] = {';
foreach ($editortxt as $key => $val)
$file_data .= '
' . JavaScriptEscape($key) . ': ' . JavaScriptEscape($val) . ',';
$file_data .= '
dateFormat: "day.month.year"
}
})(jQuery);';
header('content-type: text/javascript');
echo $file_data;
obExit(false);
}
function getMessageIcons($board_id)
{
global $modSettings, $txt, $settings, $smcFunc;
if (empty($modSettings['messageIcons_enable']))
{
loadLanguage('Post');
$icons = array(
array('value' => 'xx', 'name' => $txt['standard']),
array('value' => 'thumbup', 'name' => $txt['thumbs_up']),
array('value' => 'thumbdown', 'name' => $txt['thumbs_down']),
array('value' => 'exclamation', 'name' => $txt['exclamation_point']),
array('value' => 'question', 'name' => $txt['question_mark']),
array('value' => 'lamp', 'name' => $txt['lamp']),
array('value' => 'smiley', 'name' => $txt['icon_smiley']),
array('value' => 'angry', 'name' => $txt['icon_angry']),
array('value' => 'cheesy', 'name' => $txt['icon_cheesy']),
array('value' => 'grin', 'name' => $txt['icon_grin']),
array('value' => 'sad', 'name' => $txt['icon_sad']),
array('value' => 'wink', 'name' => $txt['icon_wink']),
array('value' => 'poll', 'name' => $txt['icon_poll']),
);
foreach ($icons as $k => $dummy)
{
$icons[$k]['url'] = $settings['images_url'] . '/post/' . $dummy['value'] . '.png';
$icons[$k]['is_last'] = false;
}
}
else
{
if (($temp = cache_get_data('posting_icons-' . $board_id, 480)) == null)
{
$request = $smcFunc['db_query']('', '
SELECT title, filename
FROM {db_prefix}message_icons
WHERE id_board IN (0, {int:board_id})
ORDER BY icon_order',
array(
'board_id' => $board_id,
)
);
$icon_data = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$icon_data[] = $row;
$smcFunc['db_free_result']($request);
$icons = array();
foreach ($icon_data as $icon)
{
$icons[$icon['filename']] = array(
'value' => $icon['filename'],
'name' => $icon['title'],
'url' => $settings[file_exists($settings['theme_dir'] . '/images/post/' . $icon['filename'] . '.png') ? 'images_url' : 'default_images_url'] . '/post/' . $icon['filename'] . '.png',
'is_last' => false,
);
}
cache_put_data('posting_icons-' . $board_id, $icons, 480);
}
else
$icons = $temp;
}
call_integration_hook('integrate_load_message_icons', array(&$icons));
return array_values($icons);
}
function create_control_richedit($editorOptions)
{
global $txt, $modSettings, $options, $smcFunc, $editortxt;
global $context, $settings, $user_info, $scripturl;
loadLanguage('Post');
loadLanguage('Editor');
loadLanguage('Drafts');
$context['richedit_buttons'] = array(
'save_draft' => array(
'type' => 'submit',
'value' => $txt['draft_save'],
'onclick' => !empty($context['drafts_pm_save']) ? 'submitThisOnce(this);' : (!empty($context['drafts_save']) ? 'return confirm(' . JavaScriptEscape($txt['draft_save_note']) . ') && submitThisOnce(this);' : ''),
'accessKey' => 'd',
'show' => !empty($context['drafts_pm_save']) || !empty($context['drafts_save'])
),
'id_pm_draft' => array(
'type' => 'hidden',
'value' => empty($context['id_pm_draft']) ? 0 : $context['id_pm_draft'],
'show' => !empty($context['drafts_pm_save'])
),
'id_draft' => array(
'type' => 'hidden',
'value' => empty($context['id_draft']) ? 0 : $context['id_draft'],
'show' => !empty($context['drafts_save'])
),
'spell_check' => array(
'type' => 'submit',
'value' => $txt['spell_check'],
'show' => !empty($context['show_spellchecking'])
),
'preview' => array(
'type' => 'submit',
'value' => $txt['preview'],
'accessKey' => 'p'
)
);
assert(isset($editorOptions['id']));
assert(isset($editorOptions['value']));
if (empty($context['controls']['richedit']))
{
$settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set'];
if (!empty($context['drafts_autosave']))
$context['drafts_autosave_frequency'] = empty($modSettings['drafts_autosave_frequency']) ? 60000 : $modSettings['drafts_autosave_frequency'] * 1000;
loadCSSFile('jquery.sceditor.css', array('force_current' => false, 'validate' => true), 'smf_jquery_sceditor');
loadTemplate('GenericControls');
loadJavaScriptFile('editor.js', array('minimize' => true), 'smf_editor');
loadJavaScriptFile('jquery.sceditor.bbcode.min.js', array(), 'smf_sceditor_bbcode');
loadJavaScriptFile('jquery.sceditor.smf.js', array('minimize' => true), 'smf_sceditor_smf');
addInlineJavaScript('
var smf_smileys_url = \'' . $settings['smileys_url'] . '\';
var bbc_quote_from = \'' . addcslashes($txt['quote_from'], "'") . '\';
var bbc_quote = \'' . addcslashes($txt['quote'], "'") . '\';
var bbc_search_on = \'' . addcslashes($txt['search_on'], "'") . '\';');
$context['shortcuts_text'] = $txt['shortcuts' . (!empty($context['drafts_save']) ? '_drafts' : '') . (stripos($_SERVER['HTTP_USER_AGENT'], 'Macintosh') !== false ? '_mac' : (isBrowser('is_firefox') ? '_firefox' : ''))];
$context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && (function_exists('pspell_new') || (function_exists('enchant_broker_init') && ($txt['lang_character_set'] == 'UTF-8' || function_exists('iconv'))));
if ($context['show_spellchecking'])
{
loadJavaScriptFile('spellcheck.js', array('minimize' => true), 'smf_spellcheck');
if (!isset($_REQUEST['xml']))
$context['insert_after_template'] .= '
<form name="spell_form" id="spell_form" method="post" accept-charset="' . $context['character_set'] . '" target="spellWindow" action="' . $scripturl . '?action=spellcheck">
<input type="hidden" name="spellstring" value="">
</form>';
}
}
$context['controls']['richedit'][$editorOptions['id']] = array(
'id' => $editorOptions['id'],
'value' => $editorOptions['value'],
'rich_value' => $editorOptions['value'],
'rich_active' => empty($modSettings['disable_wysiwyg']) && (!empty($options['wysiwyg_default']) || !empty($editorOptions['force_rich']) || !empty($_REQUEST[$editorOptions['id'] . '_mode'])),
'disable_smiley_box' => !empty($editorOptions['disable_smiley_box']),
'columns' => isset($editorOptions['columns']) ? $editorOptions['columns'] : 60,
'rows' => isset($editorOptions['rows']) ? $editorOptions['rows'] : 18,
'width' => isset($editorOptions['width']) ? $editorOptions['width'] : '70%',
'height' => isset($editorOptions['height']) ? $editorOptions['height'] : '175px',
'form' => isset($editorOptions['form']) ? $editorOptions['form'] : 'postmodify',
'bbc_level' => !empty($editorOptions['bbc_level']) ? $editorOptions['bbc_level'] : 'full',
'preview_type' => isset($editorOptions['preview_type']) ? (int) $editorOptions['preview_type'] : 1,
'labels' => !empty($editorOptions['labels']) ? $editorOptions['labels'] : array(),
'locale' => !empty($txt['lang_locale']) && substr($txt['lang_locale'], 0, 5) != 'en_US' ? $txt['lang_locale'] : '',
'required' => !empty($editorOptions['required']),
);
if (empty($context['bbc_tags']))
{
$context['bbc_tags'] = array();
$context['bbc_tags'][] = array(
array(
'code' => 'bold',
'description' => $editortxt['bold'],
),
array(
'code' => 'italic',
'description' => $editortxt['italic'],
),
array(
'code' => 'underline',
'description' => $editortxt['underline']
),
array(
'code' => 'strike',
'description' => $editortxt['strikethrough']
),
array(
'code' => 'superscript',
'description' => $editortxt['superscript']
),
array(
'code' => 'subscript',
'description' => $editortxt['subscript']
),
array(),
array(
'code' => 'pre',
'description' => $editortxt['preformatted_text']
),
array(
'code' => 'left',
'description' => $editortxt['align_left']
),
array(
'code' => 'center',
'description' => $editortxt['center']
),
array(
'code' => 'right',
'description' => $editortxt['align_right']
),
array(
'code' => 'justify',
'description' => $editortxt['justify']
),
array(),
array(
'code' => 'font',
'description' => $editortxt['font_name']
),
array(
'code' => 'size',
'description' => $editortxt['font_size']
),
array(
'code' => 'color',
'description' => $editortxt['font_color']
),
);
if (empty($modSettings['disable_wysiwyg']))
{
$context['bbc_tags'][count($context['bbc_tags']) - 1][] = array(
'code' => 'removeformat',
'description' => $editortxt['remove_formatting'],
);
}
$context['bbc_tags'][] = array(
array(
'code' => 'floatleft',
'description' => $editortxt['float_left']
),
array(
'code' => 'floatright',
'description' => $editortxt['float_right']
),
array(),
array(
'code' => 'youtube',
'description' => $editortxt['insert_youtube_video']
),
array(
'code' => 'image',
'description' => $editortxt['insert_image']
),
array(
'code' => 'link',
'description' => $editortxt['insert_link']
),
array(
'code' => 'email',
'description' => $editortxt['insert_email']
),
array(),
array(
'code' => 'table',
'description' => $editortxt['insert_table']
),
array(
'code' => 'code',
'description' => $editortxt['code']
),
array(
'code' => 'quote',
'description' => $editortxt['insert_quote']
),
array(),
array(
'code' => 'bulletlist',
'description' => $editortxt['bullet_list']
),
array(
'code' => 'orderedlist',
'description' => $editortxt['numbered_list']
),
array(
'code' => 'horizontalrule',
'description' => $editortxt['insert_horizontal_rule']
),
array(),
array(
'code' => 'maximize',
'description' => $editortxt['maximize']
),
);
if (empty($modSettings['disable_wysiwyg']))
{
$context['bbc_tags'][count($context['bbc_tags']) - 1][] = array(
'code' => 'source',
'description' => $editortxt['view_source'],
);
}
$editor_tag_map = array(
'b' => 'bold',
'i' => 'italic',
'u' => 'underline',
's' => 'strike',
'img' => 'image',
'url' => 'link',
'sup' => 'superscript',
'sub' => 'subscript',
'hr' => 'horizontalrule',
);
call_integration_hook('integrate_bbc_buttons', array(&$context['bbc_tags'], &$editor_tag_map));
$disabled_tags = array();
if (!empty($modSettings['disabledBBC']))
$disabled_tags = explode(',', $modSettings['disabledBBC']);
foreach ($disabled_tags as $tag)
{
$tag = trim($tag);
if ($tag === 'list')
{
$context['disabled_tags']['bulletlist'] = true;
$context['disabled_tags']['orderedlist'] = true;
}
foreach ($editor_tag_map as $thisTag => $tagNameBBC)
if ($tag === $thisTag)
$context['disabled_tags'][$tagNameBBC] = true;
$context['disabled_tags'][$tag] = true;
}
$bbcodes_styles = '';
$context['bbcodes_handlers'] = '';
$context['bbc_toolbar'] = array();
foreach ($context['bbc_tags'] as $row => $tagRow)
{
if (!isset($context['bbc_toolbar'][$row]))
$context['bbc_toolbar'][$row] = array();
$tagsRow = array();
foreach ($tagRow as $tag)
{
if ((!empty($tag['code'])) && empty($context['disabled_tags'][$tag['code']]))
{
$tagsRow[] = $tag['code'];
if (isset($tag['image']))
{
$bbcodes_styles .= '
.sceditor-button-' . $tag['code'] . ' div {
background: url(\'' . $settings['default_theme_url'] . '/images/bbc/' . $tag['image'] . '.png\');
}';
}
$context['bbcodes_handlers'] .= '
sceditor.command.set(' . JavaScriptEscape($tag['code']) . ', {
tooltip: ' . JavaScriptEscape(isset($tag['description']) ? $tag['description'] : $tag['code']);
if (isset($tag['before']))
{
$context['bbcodes_handlers'] .= ',
exec: function () {
this.insert(' . JavaScriptEscape($tag['before']) . (isset($tag['after']) ? ', ' . JavaScriptEscape($tag['after']) : '') . ');
},
txtExec: [' . JavaScriptEscape($tag['before']) . (isset($tag['after']) ? ', ' . JavaScriptEscape($tag['after']) : '') . ']';
}
$context['bbcodes_handlers'] .= '
});';
}
else
{
$context['bbc_toolbar'][$row][] = implode(',', $tagsRow);
$tagsRow = array();
}
}
if (!empty($tagsRow))
$context['bbc_toolbar'][$row][] = implode(',', $tagsRow);
}
if (!empty($bbcodes_styles))
addInlineCss($bbcodes_styles);
}
if (empty($context['smileys']) && empty($editorOptions['disable_smiley_box']))
{
$context['smileys'] = array(
'postform' => array(),
'popup' => array(),
);
if ($user_info['smiley_set'] != 'none')
{
$cache_time = empty($modSettings['smiley_enable']) ? 7200 : 480;
if (($temp = cache_get_data('posting_smileys_' . $user_info['smiley_set'], $cache_time)) == null)
{
$request = $smcFunc['db_query']('', '
SELECT s.code, f.filename, s.description, s.smiley_row, s.hidden
FROM {db_prefix}smileys AS s
JOIN {db_prefix}smiley_files AS f ON (s.id_smiley = f.id_smiley)
WHERE s.hidden IN (0, 2)
AND f.smiley_set = {string:smiley_set}' . (empty($modSettings['smiley_enable']) ? '
AND s.code IN ({array_string:default_codes})' : '') . '
ORDER BY s.smiley_row, s.smiley_order',
array(
'default_codes' => array('>:D', ':D', '::)', '>:(', ':))', ':)', ';)', ';D', ':(', ':o', '8)', ':P', '???', ':-[', ':-X', ':-*', ':\'(', ':-\\', '^-^', 'O0', 'C:-)', 'O:-)'),
'smiley_set' => $user_info['smiley_set'],
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
{
$row['description'] = !empty($txt['icon_' . strtolower($row['description'])]) ? $smcFunc['htmlspecialchars']($txt['icon_' . strtolower($row['description'])]) : $smcFunc['htmlspecialchars']($row['description']);
$context['smileys'][empty($row['hidden']) ? 'postform' : 'popup'][$row['smiley_row']]['smileys'][] = $row;
}
$smcFunc['db_free_result']($request);
foreach ($context['smileys'] as $section => $smileyRows)
{
foreach ($smileyRows as $rowIndex => $smileys)
$context['smileys'][$section][$rowIndex]['smileys'][count($smileys['smileys']) - 1]['isLast'] = true;
if (!empty($smileyRows))
$context['smileys'][$section][count($smileyRows) - 1]['isLast'] = true;
}
cache_put_data('posting_smileys_' . $user_info['smiley_set'], $context['smileys'], $cache_time);
}
else
$context['smileys'] = $temp;
}
}
$sce_options = array(
'width' => isset($editorOptions['width']) ? $editorOptions['width'] : '100%',
'height' => isset($editorOptions['height']) ? $editorOptions['height'] : '175px',
'style' => $settings[file_exists($settings['theme_dir'] . '/css/jquery.sceditor.default.css') ? 'theme_url' : 'default_theme_url'] . '/css/jquery.sceditor.default.css',
'emoticonsCompat' => true,
'colors' => 'black,maroon,brown,green,navy,grey,red,orange,teal,blue,white,hotpink,yellow,limegreen,purple',
'format' => 'bbcode',
'plugins' => '',
'bbcodeTrim' => true,
);
if (!empty($context['controls']['richedit'][$editorOptions['id']]['locale']))
$sce_options['locale'] = $context['controls']['richedit'][$editorOptions['id']]['locale'];
if (!empty($context['right_to_left']))
$sce_options['rtl'] = true;
if ($editorOptions['id'] != 'quickReply')
$sce_options['autofocus'] = true;
$sce_options['emoticons'] = array();
$sce_options['emoticonsDescriptions'] = array();
$sce_options['emoticonsEnabled'] = false;
if ((!empty($context['smileys']['postform']) || !empty($context['smileys']['popup'])) && !$context['controls']['richedit'][$editorOptions['id']]['disable_smiley_box'])
{
$sce_options['emoticonsEnabled'] = true;
$sce_options['emoticons']['dropdown'] = array();
$sce_options['emoticons']['popup'] = array();
$countLocations = count($context['smileys']);
foreach ($context['smileys'] as $location => $smileyRows)
{
$countLocations--;
unset($smiley_location);
if ($location == 'postform')
$smiley_location = &$sce_options['emoticons']['dropdown'];
elseif ($location == 'popup')
$smiley_location = &$sce_options['emoticons']['popup'];
$numRows = count($smileyRows);
$emptyPlaceholder = 0;
foreach ($smileyRows as $smileyRow)
{
foreach ($smileyRow['smileys'] as $smiley)
{
$smiley_location[$smiley['code']] = $settings['smileys_url'] . '/' . $smiley['filename'];
$sce_options['emoticonsDescriptions'][$smiley['code']] = $smiley['description'];
}
if (empty($smileyRow['isLast']) && $numRows != 1)
$smiley_location['-' . $emptyPlaceholder++] = '';
}
}
}
$sce_options['toolbar'] = '';
if (!empty($modSettings['enableBBC']))
{
$count_tags = count($context['bbc_tags']);
foreach ($context['bbc_toolbar'] as $i => $buttonRow)
{
$sce_options['toolbar'] .= implode('|', $buttonRow);
$count_tags--;
if (!empty($count_tags))
$sce_options['toolbar'] .= '||';
}
}
call_integration_hook('integrate_sceditor_options', array(&$sce_options));
$context['controls']['richedit'][$editorOptions['id']]['sce_options'] = $sce_options;
}
function create_control_verification(&$verificationOptions, $do_test = false)
{
global $modSettings, $smcFunc;
global $context, $user_info, $scripturl, $language;
if (empty($context['controls']['verification']))
{
loadTemplate('GenericControls');
if (!empty($verificationOptions['override_visual']) || (!empty($modSettings['visual_verification_type']) && !isset($verificationOptions['override_visual'])))
loadJavaScriptFile('captcha.js', array('minimize' => true), 'smf_captcha');
$context['use_graphic_library'] = in_array('gd', get_loaded_extensions());
$context['standard_captcha_range'] = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P', 'R'), range('T', 'Y'));
}
assert(isset($verificationOptions['id']));
$isNew = !isset($context['controls']['verification'][$verificationOptions['id']]);
if ($isNew)
$context['controls']['verification'][$verificationOptions['id']] = array(
'id' => $verificationOptions['id'],
'empty_field' => empty($verificationOptions['no_empty_field']),
'show_visual' => !empty($verificationOptions['override_visual']) || (!empty($modSettings['visual_verification_type']) && !isset($verificationOptions['override_visual'])),
'number_questions' => isset($verificationOptions['override_qs']) ? $verificationOptions['override_qs'] : (!empty($modSettings['qa_verification_number']) ? $modSettings['qa_verification_number'] : 0),
'max_errors' => isset($verificationOptions['max_errors']) ? $verificationOptions['max_errors'] : 3,
'image_href' => $scripturl . '?action=verificationcode;vid=' . $verificationOptions['id'] . ';rand=' . md5(mt_rand()),
'text_value' => '',
'questions' => array(),
'can_recaptcha' => !empty($modSettings['recaptcha_enabled']) && !empty($modSettings['recaptcha_site_key']) && !empty($modSettings['recaptcha_secret_key']),
);
$thisVerification = &$context['controls']['verification'][$verificationOptions['id']];
call_integration_hook('integrate_create_control_verification_pre', array(&$verificationOptions, $do_test));
if (empty($thisVerification['show_visual']) && empty($thisVerification['number_questions']) && empty($thisVerification['can_recaptcha']))
return false;
elseif (!$isNew && !$do_test)
return true;
if ($thisVerification['can_recaptcha'])
{
$thisVerification['recaptcha_site_key'] = preg_replace('/(0-9a-zA-Z_){40}/', '$1', $modSettings['recaptcha_site_key']);
$thisVerification['recaptcha_theme'] = preg_replace('/(light|dark)/', '$1', $modSettings['recaptcha_theme']);
}
if ($context['controls']['verification'][$verificationOptions['id']]['show_visual'])
$context['insert_after_template'] .= '
<script>
var verification' . $verificationOptions['id'] . 'Handle = new smfCaptcha("' . $thisVerification['image_href'] . '", "' . $verificationOptions['id'] . '", ' . ($context['use_graphic_library'] ? 1 : 0) . ');
</script>';
if (!empty($thisVerification['number_questions']) && empty($modSettings['question_id_cache']))
{
if (($modSettings['question_id_cache'] = cache_get_data('verificationQuestions', 300)) == null)
{
$request = $smcFunc['db_query']('', '
SELECT id_question, lngfile, question, answers
FROM {db_prefix}qanda',
array()
);
$modSettings['question_id_cache'] = array(
'questions' => array(),
'langs' => array(),
);
while ($row = $smcFunc['db_fetch_assoc']($request))
{
$id_question = $row['id_question'];
unset ($row['id_question']);
$row['answers'] = $smcFunc['json_decode']($row['answers'], true);
foreach ($row['answers'] as $k => $v)
$row['answers'][$k] = $smcFunc['strtolower']($v);
$modSettings['question_id_cache']['questions'][$id_question] = $row;
$modSettings['question_id_cache']['langs'][$row['lngfile']][] = $id_question;
}
$smcFunc['db_free_result']($request);
cache_put_data('verificationQuestions', $modSettings['question_id_cache'], 300);
}
}
if (!isset($_SESSION[$verificationOptions['id'] . '_vv']))
$_SESSION[$verificationOptions['id'] . '_vv'] = array();
if (!$do_test && (!empty($_SESSION[$verificationOptions['id'] . '_vv']['did_pass']) || empty($_SESSION[$verificationOptions['id'] . '_vv']['count']) || $_SESSION[$verificationOptions['id'] . '_vv']['count'] > 3) && empty($verificationOptions['dont_refresh']))
$force_refresh = true;
else
$force_refresh = false;
if (($thisVerification['show_visual'] && empty($_SESSION[$verificationOptions['id'] . '_vv']['code'])) || ($thisVerification['number_questions'] && empty($_SESSION[$verificationOptions['id'] . '_vv']['q'])))
$force_refresh = true;
$verification_errors = array();
if ($do_test)
{
if (!isset($_SESSION[$verificationOptions['id'] . '_vv']['count']))
fatal_lang_error('no_access', false);
if ($thisVerification['number_questions'] && (!isset($_SESSION[$verificationOptions['id'] . '_vv']['q']) || !isset($_REQUEST[$verificationOptions['id'] . '_vv']['q'])))
fatal_lang_error('no_access', false);
if ($thisVerification['empty_field'] && empty($_SESSION[$verificationOptions['id'] . '_vv']['empty_field']))
fatal_lang_error('no_access', false);
if ($thisVerification['empty_field'] && !empty($_SESSION[$verificationOptions['id'] . '_vv']['empty_field']) && !empty($_REQUEST[$_SESSION[$verificationOptions['id'] . '_vv']['empty_field']]))
$verification_errors[] = 'wrong_verification_answer';
if ($thisVerification['can_recaptcha'])
{
$reCaptcha = new \ReCaptcha\ReCaptcha($modSettings['recaptcha_secret_key'], new \ReCaptcha\RequestMethod\SocketPost());
if (isset($_POST['g-recaptcha-response']))
{
$resp = $reCaptcha->verify($_POST['g-recaptcha-response'], $user_info['ip']);
if (!$resp->isSuccess())
$verification_errors[] = 'wrong_verification_recaptcha';
}
else
$verification_errors[] = 'wrong_verification_code';
}
if ($thisVerification['show_visual'] && (empty($_REQUEST[$verificationOptions['id'] . '_vv']['code']) || empty($_SESSION[$verificationOptions['id'] . '_vv']['code']) || strtoupper($_REQUEST[$verificationOptions['id'] . '_vv']['code']) !== $_SESSION[$verificationOptions['id'] . '_vv']['code']))
$verification_errors[] = 'wrong_verification_code';
if ($thisVerification['number_questions'])
{
$incorrectQuestions = array();
foreach ($_SESSION[$verificationOptions['id'] . '_vv']['q'] as $q)
{
if (!isset($modSettings['question_id_cache']['questions'][$q]))
continue;
if (!isset($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) || trim($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) == '')
{
$incorrectQuestions[] = $q;
continue;
}
else
{
$given_answer = trim($smcFunc['htmlspecialchars'](strtolower($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q])));
if (!in_array($given_answer, $modSettings['question_id_cache']['questions'][$q]['answers']))
$incorrectQuestions[] = $q;
}
}
if (!empty($incorrectQuestions))
$verification_errors[] = 'wrong_verification_answer';
}
call_integration_hook('integrate_create_control_verification_test', array($thisVerification, &$verification_errors));
}
if (!empty($verification_errors))
{
if (empty($_SESSION[$verificationOptions['id'] . '_vv']['errors']))
$_SESSION[$verificationOptions['id'] . '_vv']['errors'] = 0;
elseif ($_SESSION[$verificationOptions['id'] . '_vv']['errors'] > $thisVerification['max_errors'])
$force_refresh = true;
$_SESSION[$verificationOptions['id'] . '_vv']['errors']++;
}
if ($force_refresh)
{
$_SESSION[$verificationOptions['id'] . '_vv']['count'] = 0;
$_SESSION[$verificationOptions['id'] . '_vv']['errors'] = 0;
$_SESSION[$verificationOptions['id'] . '_vv']['did_pass'] = false;
$_SESSION[$verificationOptions['id'] . '_vv']['q'] = array();
$_SESSION[$verificationOptions['id'] . '_vv']['code'] = '';
if ($thisVerification['empty_field'])
{
$terms = array('gadget', 'device', 'uid', 'gid', 'guid', 'uuid', 'unique', 'identifier');
$second_terms = array('hash', 'cipher', 'code', 'key', 'unlock', 'bit', 'value');
$start = mt_rand(0, 27);
$hash = substr(md5(time()), $start, 4);
$_SESSION[$verificationOptions['id'] . '_vv']['empty_field'] = $terms[array_rand($terms)] . '-' . $second_terms[array_rand($second_terms)] . '-' . $hash;
}
if ($thisVerification['show_visual'])
{
$character_range = !empty($verificationOptions['override_range']) ? $verificationOptions['override_range'] : $context['standard_captcha_range'];
for ($i = 0; $i < 6; $i++)
$_SESSION[$verificationOptions['id'] . '_vv']['code'] .= $character_range[array_rand($character_range)];
}
if ($thisVerification['number_questions'])
{
$possible_langs = array();
if (isset($_SESSION['language']))
$possible_langs[] = strtr($_SESSION['language'], array('-utf8' => ''));
if (!empty($user_info['language']))
$possible_langs[] = $user_info['language'];
$possible_langs[] = $language;
$questionIDs = array();
foreach ($possible_langs as $lang)
{
$lang = strtr($lang, array('-utf8' => ''));
if (isset($modSettings['question_id_cache']['langs'][$lang]))
{
$questionIDs = $modSettings['question_id_cache']['langs'][$lang];
shuffle($questionIDs);
$questionIDs = array_slice($questionIDs, 0, $thisVerification['number_questions']);
break;
}
}
}
call_integration_hook('integrate_create_control_verification_refresh', array($thisVerification));
}
else
{
$questionIDs = !empty($_SESSION[$verificationOptions['id'] . '_vv']['q']) ? $_SESSION[$verificationOptions['id'] . '_vv']['q'] : array();
$thisVerification['text_value'] = !empty($_REQUEST[$verificationOptions['id'] . '_vv']['code']) ? $smcFunc['htmlspecialchars']($_REQUEST[$verificationOptions['id'] . '_vv']['code']) : '';
}
if (!empty($_SESSION[$verificationOptions['id'] . '_vv']['empty_field']))
{
if (!isset($context['html_headers']))
$context['html_headers'] = '';
$context['html_headers'] .= '<style>.vv_special { display:none; }</style>';
}
if (!empty($questionIDs))
{
$_SESSION[$verificationOptions['id'] . '_vv']['q'] = array();
foreach ($questionIDs as $q)
{
$row = &$modSettings['question_id_cache']['questions'][$q];
$thisVerification['questions'][] = array(
'id' => $q,
'q' => parse_bbc($row['question']),
'is_error' => !empty($incorrectQuestions) && in_array($q, $incorrectQuestions),
'a' => isset($_REQUEST[$verificationOptions['id'] . '_vv'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) ? $smcFunc['htmlspecialchars']($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) : '',
);
$_SESSION[$verificationOptions['id'] . '_vv']['q'][] = $q;
}
}
$_SESSION[$verificationOptions['id'] . '_vv']['count'] = empty($_SESSION[$verificationOptions['id'] . '_vv']['count']) ? 1 : $_SESSION[$verificationOptions['id'] . '_vv']['count'] + 1;
call_integration_hook('integrate_create_control_verification_post', array(&$verification_errors, $do_test));
if (!empty($verification_errors))
return $verification_errors;
elseif ($do_test)
$_SESSION[$verificationOptions['id'] . '_vv']['did_pass'] = true;
return true;
}
function AutoSuggestHandler($checkRegistered = null)
{
global $smcFunc, $context;
$searchTypes = array(
'member' => 'Member',
'membergroups' => 'MemberGroups',
'versions' => 'SMFVersions',
);
call_integration_hook('integrate_autosuggest', array(&$searchTypes));
if ($checkRegistered != null)
return isset($searchTypes[$checkRegistered]) && function_exists('AutoSuggest_Search_' . $checkRegistered);
checkSession('get');
loadTemplate('Xml');
$context['search_param'] = isset($_REQUEST['search_param']) ? $smcFunc['json_decode'](base64_decode($_REQUEST['search_param']), true) : array();
if (isset($_REQUEST['suggest_type'], $_REQUEST['search']) && isset($searchTypes[$_REQUEST['suggest_type']]))
{
$function = 'AutoSuggest_Search_' . $searchTypes[$_REQUEST['suggest_type']];
$context['sub_template'] = 'generic_xml';
$context['xml_data'] = $function();
}
}
function AutoSuggest_Search_Member()
{
global $user_info, $smcFunc, $context;
$_REQUEST['search'] = trim($smcFunc['strtolower']($_REQUEST['search'])) . '*';
$_REQUEST['search'] = strtr($_REQUEST['search'], array('%' => '\%', '_' => '\_', '*' => '%', '?' => '_', '&' => '&'));
$request = $smcFunc['db_query']('', '
SELECT id_member, real_name
FROM {db_prefix}members
WHERE {raw:real_name} LIKE {string:search}' . (!empty($context['search_param']['buddies']) ? '
AND id_member IN ({array_int:buddy_list})' : '') . '
AND is_activated IN (1, 11)
LIMIT ' . ($smcFunc['strlen']($_REQUEST['search']) <= 2 ? '100' : '800'),
array(
'real_name' => $smcFunc['db_case_sensitive'] ? 'LOWER(real_name)' : 'real_name',
'buddy_list' => $user_info['buddies'],
'search' => $_REQUEST['search'],
)
);
$xml_data = array(
'items' => array(
'identifier' => 'item',
'children' => array(),
),
);
while ($row = $smcFunc['db_fetch_assoc']($request))
{
$row['real_name'] = strtr($row['real_name'], array('&' => '&', '<' => '<', '>' => '>', '"' => '"'));
$xml_data['items']['children'][] = array(
'attributes' => array(
'id' => $row['id_member'],
),
'value' => $row['real_name'],
);
}
$smcFunc['db_free_result']($request);
return $xml_data;
}
function AutoSuggest_Search_MemberGroups()
{
global $smcFunc;
$_REQUEST['search'] = trim($smcFunc['strtolower']($_REQUEST['search'])) . '*';
$_REQUEST['search'] = strtr($_REQUEST['search'], array('%' => '\%', '_' => '\_', '*' => '%', '?' => '_', '&' => '&'));
$request = $smcFunc['db_query']('', '
SELECT id_group, group_name
FROM {db_prefix}membergroups
WHERE {raw:group_name} LIKE {string:search}
AND min_posts = {int:min_posts}
AND id_group NOT IN ({array_int:invalid_groups})
AND hidden != {int:hidden}',
array(
'group_name' => $smcFunc['db_case_sensitive'] ? 'LOWER(group_name}' : 'group_name',
'min_posts' => -1,
'invalid_groups' => array(1, 3),
'hidden' => 2,
'search' => $_REQUEST['search'],
)
);
$xml_data = array(
'items' => array(
'identifier' => 'item',
'children' => array(),
),
);
while ($row = $smcFunc['db_fetch_assoc']($request))
{
$row['group_name'] = strtr($row['group_name'], array('&' => '&', '<' => '<', '>' => '>', '"' => '"'));
$xml_data['items']['children'][] = array(
'attributes' => array(
'id' => $row['id_group'],
),
'value' => $row['group_name'],
);
}
$smcFunc['db_free_result']($request);
return $xml_data;
}
function AutoSuggest_Search_SMFVersions()
{
global $smcFunc;
$xml_data = array(
'items' => array(
'identifier' => 'item',
'children' => array(),
),
);
$versions = array();
$request = $smcFunc['db_query']('', '
SELECT data
FROM {db_prefix}admin_info_files
WHERE filename = {string:latest_versions}
AND path = {string:path}',
array(
'latest_versions' => 'latest-versions.txt',
'path' => '/smf/',
)
);
if (($smcFunc['db_num_rows']($request) > 0) && ($row = $smcFunc['db_fetch_assoc']($request)) && !empty($row['data']))
{
$possible_versions = explode("\n", $row['data']);
foreach ($possible_versions as $ver)
{
$ver = trim($ver);
if (strpos($ver, 'SMF') === 0)
$versions[] = $ver;
}
}
$smcFunc['db_free_result']($request);
if (empty($versions))
$versions = array('SMF 2.0');
foreach ($versions as $id => $version)
if (strpos($version, strtoupper($_REQUEST['search'])) !== false)
$xml_data['items']['children'][] = array(
'attributes' => array(
'id' => $id,
),
'value' => $version,
);
return $xml_data;
}
?>