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: 2482: 2483: 2484: 2485: 2486: 2487: 2488: 2489: 2490: 2491: 2492: 2493: 2494: 2495: 2496: 2497: 2498: 2499: 2500: 2501: 2502: 2503: 2504: 2505: 2506: 2507: 2508: 2509: 2510: 2511: 2512: 2513: 2514: 2515: 2516: 2517: 2518: 2519: 2520: 2521: 2522: 2523: 2524: 2525: 2526: 2527: 2528: 2529: 2530: 2531: 2532: 2533: 2534: 2535: 2536: 2537: 2538: 2539: 2540: 2541: 2542: 2543: 2544: 2545: 2546: 2547: 2548: 2549: 2550: 2551: 2552: 2553: 2554: 2555: 2556: 2557: 2558: 2559: 2560: 2561: 2562: 2563: 2564: 2565: 2566: 2567: 2568: 2569: 2570: 2571: 2572: 2573: 2574: 2575: 2576: 2577: 2578: 2579: 2580: 2581: 2582: 2583: 2584: 2585: 2586: 2587: 2588: 2589: 2590: 2591: 2592: 2593: 2594: 2595: 2596: 2597: 2598: 2599: 2600: 2601: 2602: 2603: 2604: 2605: 2606: 2607: 2608: 2609: 2610: 2611: 2612: 2613: 2614: 2615: 2616: 2617: 2618: 2619: 2620: 2621: 2622: 2623: 2624: 2625: 2626: 2627: 2628: 2629: 2630: 2631: 2632: 2633: 2634: 2635: 2636: 2637: 2638: 2639: 2640: 2641: 2642: 2643: 2644: 2645: 2646: 2647: 2648: 2649: 2650: 2651: 2652: 2653: 2654: 2655: 2656: 2657: 2658: 2659: 2660: 2661: 2662: 2663: 2664: 2665: 2666: 2667: 2668: 2669: 2670: 2671: 2672: 2673: 2674: 2675: 2676: 2677: 2678: 2679: 2680: 2681: 2682: 2683: 2684: 2685: 2686: 2687: 2688: 2689: 2690: 2691: 2692: 2693: 2694: 2695: 2696: 2697: 2698: 2699: 2700: 2701: 2702: 2703: 2704: 2705: 2706: 2707: 2708: 2709: 2710: 2711: 2712: 2713: 2714: 2715: 2716: 2717: 2718: 2719: 2720: 2721: 2722: 2723: 2724: 2725: 2726: 2727: 2728: 2729: 2730: 2731: 2732: 2733: 2734: 2735: 2736: 2737: 2738: 2739: 2740: 2741: 2742: 2743: 2744: 2745: 2746: 2747: 2748: 2749: 2750: 2751: 2752: 2753: 2754: 2755: 2756: 2757: 2758: 2759: 2760: 2761: 2762: 2763: 2764: 2765: 2766: 2767: 2768: 2769: 2770: 2771: 2772: 2773: 2774: 2775: 2776: 2777: 2778: 2779: 2780: 2781: 2782: 2783: 2784: 2785: 2786: 2787: 2788: 2789: 2790: 2791: 2792: 2793: 2794: 2795: 2796: 2797: 2798: 2799: 2800: 2801: 2802: 2803: 2804: 2805: 2806: 2807: 2808: 2809: 2810: 2811: 2812: 2813: 2814: 2815: 2816: 2817: 2818: 2819: 2820: 2821: 2822: 2823: 2824: 2825: 2826: 2827: 2828: 2829: 2830: 2831: 2832: 2833: 2834: 2835: 2836: 2837: 2838: 2839: 2840: 2841: 2842: 2843: 2844: 2845: 2846: 2847: 2848: 2849: 2850: 2851: 2852: 2853: 2854: 2855: 2856: 2857: 2858: 2859: 2860: 2861: 2862: 2863: 2864: 2865: 2866: 2867: 2868: 2869: 2870: 2871: 2872: 2873: 2874: 2875: 2876: 2877: 2878: 2879: 2880: 2881: 2882: 2883: 2884: 2885: 2886: 2887: 2888: 2889: 2890: 2891: 2892: 2893: 2894: 2895: 2896: 2897: 2898: 2899: 2900: 2901: 2902: 2903: 2904: 2905: 2906: 2907: 2908: 2909: 2910: 2911: 2912: 2913: 2914: 2915: 2916: 2917: 2918: 2919: 2920: 2921: 2922: 2923: 2924: 2925: 2926: 2927: 2928: 2929: 2930: 2931: 2932: 2933: 2934: 2935: 2936: 2937: 2938: 2939: 2940: 2941: 2942: 2943: 2944: 2945: 2946: 2947: 2948: 2949: 2950: 2951: 2952: 2953: 2954: 2955: 2956: 2957: 2958: 2959: 2960: 2961: 2962: 2963: 2964: 2965: 2966: 2967: 2968: 2969: 2970: 2971: 2972: 2973: 2974: 2975: 2976: 2977: 2978: 2979: 2980: 2981: 2982: 2983: 2984: 2985: 2986: 2987: 2988: 2989: 2990: 2991: 2992: 2993: 2994: 2995: 2996: 2997: 2998: 2999: 3000: 3001: 3002: 3003: 3004: 3005: 3006: 3007: 3008: 3009: 3010: 3011: 3012: 3013: 3014: 3015: 3016: 3017: 3018: 3019: 3020: 3021: 3022: 3023: 3024: 3025: 3026: 3027: 3028: 3029: 3030: 3031: 3032: 3033: 3034: 3035: 3036: 3037: 3038: 3039: 3040: 3041: 3042: 3043: 3044: 3045: 3046: 3047: 3048: 3049: 3050: 3051: 3052: 3053: 3054: 3055: 3056: 3057: 3058: 3059: 3060: 3061: 3062: 3063: 3064: 3065: 3066: 3067: 3068: 3069: 3070: 3071: 3072: 3073: 3074: 3075: 3076: 3077: 3078: 3079: 3080: 3081: 3082: 3083: 3084: 3085: 3086: 3087: 3088: 3089: 3090: 3091: 3092: 3093: 3094: 3095: 3096: 3097: 3098: 3099: 3100: 3101: 3102: 3103: 3104: 3105: 3106: 3107: 3108: 3109: 3110: 3111: 3112: 3113: 3114: 3115: 3116: 3117: 3118: 3119: 3120: 3121: 3122: 3123: 3124: 3125: 3126: 3127: 3128: 3129: 3130: 3131: 3132: 3133: 3134: 3135: 3136: 3137: 3138: 3139: 3140: 3141: 3142: 3143: 3144: 3145: 3146: 3147: 3148: 3149: 3150: 3151: 3152: 3153: 3154: 3155: 3156: 3157: 3158: 3159: 3160: 3161: 3162: 3163: 3164: 3165: 3166: 3167: 3168: 3169: 3170: 3171: 3172: 3173: 3174: 3175: 3176: 3177: 3178: 3179: 3180: 3181: 3182: 3183: 3184: 3185: 3186: 3187: 3188: 3189: 3190: 3191: 3192: 3193: 3194: 3195: 3196: 3197: 3198: 3199: 3200: 3201: 3202: 3203: 3204: 3205: 3206: 3207: 3208: 3209: 3210: 3211: 3212: 3213: 3214: 3215: 3216: 3217: 3218: 3219: 3220: 3221: 3222: 3223: 3224: 3225: 3226: 3227: 3228: 3229: 3230: 3231: 3232: 3233: 3234: 3235: 3236: 3237: 3238: 3239: 3240: 3241: 3242: 3243: 3244: 3245: 3246: 3247: 3248: 3249: 3250: 3251: 3252: 3253: 3254: 3255: 3256: 3257: 3258: 3259: 3260: 3261: 3262: 3263: 3264: 3265: 3266: 3267: 3268: 3269: 3270: 3271: 3272: 3273: 3274: 3275: 3276: 3277: 3278: 3279: 3280: 3281: 3282: 3283: 3284: 3285: 3286: 3287: 3288: 3289: 3290: 3291: 3292: 3293: 3294: 3295: 3296: 3297: 3298: 3299: 3300: 3301: 3302: 3303: 3304: 3305: 3306: 3307: 3308: 3309: 3310: 3311: 3312: 3313: 3314: 3315: 3316: 3317: 3318: 3319: 3320: 3321: 3322: 3323: 3324: 3325: 3326: 3327: 3328: 3329: 3330: 3331: 3332: 3333: 3334: 3335: 3336: 3337: 3338: 3339: 3340: 3341: 3342: 3343: 3344: 3345: 3346: 3347: 3348: 3349: 3350: 3351: 3352: 3353: 3354: 3355: 3356: 3357: 3358: 3359: 3360: 3361: 3362: 3363: 3364: 3365: 3366: 3367: 3368: 3369: 3370: 3371: 3372: 3373: 3374: 3375: 3376: 3377: 3378: 3379: 3380: 3381: 3382: 3383: 3384: 3385: 3386: 3387: 3388: 3389: 3390: 3391: 3392: 3393: 3394: 3395: 3396: 3397: 3398: 3399: 3400: 3401: 3402: 3403: 3404: 3405: 3406: 3407: 3408: 3409: 3410: 3411: 3412: 3413: 3414: 3415: 3416: 3417: 3418: 3419: 3420: 3421: 3422: 3423: 3424: 3425: 3426: 3427: 3428: 3429: 3430: 3431: 3432: 3433: 3434: 3435: 3436: 3437: 3438: 3439: 3440: 3441: 3442: 3443: 3444: 3445: 3446: 3447: 3448: 3449: 3450: 3451: 3452: 3453: 3454: 3455: 3456: 3457: 3458: 3459: 3460: 3461: 3462: 3463: 3464: 3465: 3466: 3467: 3468: 3469: 3470: 3471: 3472: 3473: 3474: 3475: 3476: 3477: 3478: 3479: 3480: 3481: 3482: 3483: 3484: 3485: 3486: 3487: 3488: 3489: 3490: 3491: 3492: 3493: 3494: 3495: 3496: 3497: 3498: 3499: 3500: 3501: 3502: 3503: 3504: 3505: 3506: 3507: 3508: 3509: 3510: 3511: 3512: 3513: 3514: 3515: 3516: 3517: 3518: 3519: 3520: 3521: 3522: 3523: 3524: 3525: 3526: 3527: 3528: 3529: 3530: 3531: 3532: 3533: 3534: 3535: 3536: 3537: 3538: 3539: 3540: 3541: 3542: 3543: 3544: 3545: 3546: 3547: 3548: 3549: 3550: 3551: 3552: 3553: 3554: 3555: 3556: 3557: 3558: 3559: 3560: 3561: 3562: 3563: 3564: 3565: 3566: 3567: 3568: 3569: 3570: 3571: 3572: 3573: 3574: 3575: 3576: 3577: 3578: 3579: 3580: 3581: 3582: 3583: 3584: 3585: 3586: 3587: 3588: 3589: 3590: 3591: 3592: 3593: 3594: 3595: 3596: 3597: 3598: 3599: 3600: 3601: 3602: 3603: 3604: 3605: 3606: 3607: 3608: 3609: 3610: 3611: 3612: 3613: 3614: 3615: 3616: 3617: 3618: 3619: 3620: 3621: 3622: 3623: 3624: 3625: 3626: 3627: 3628: 3629: 3630: 3631: 3632: 3633: 3634: 3635: 3636: 3637: 3638: 3639: 3640: 3641: 3642: 3643: 3644: 3645: 3646: 3647: 3648: 3649: 3650: 3651: 3652: 3653: 3654: 3655: 3656: 3657: 3658: 3659: 3660: 3661: 3662: 3663: 3664: 3665: 3666: 3667: 3668: 3669: 3670: 3671: 3672: 3673: 3674: 3675: 3676: 3677: 3678: 3679: 3680: 3681: 3682: 3683: 3684: 3685: 3686: 3687: 3688: 3689: 3690: 3691: 3692: 3693: 3694: 3695: 3696: 3697: 3698: 3699: 3700: 3701: 3702: 3703: 3704: 3705: 3706: 3707: 3708: 3709: 3710: 3711: 3712: 3713: 3714: 3715: 3716: 3717: 3718: 3719: 3720: 3721: 3722: 3723: 3724: 3725: 3726: 3727: 3728: 3729: 3730: 3731: 3732: 3733: 3734: 3735: 3736: 3737: 3738: 3739: 3740: 3741: 3742: 3743: 3744: 3745: 3746: 3747: 3748: 3749: 3750: 3751: 3752: 3753: 3754: 3755: 3756: 3757: 3758: 3759: 3760: 3761: 3762: 3763: 3764: 3765: 3766: 3767: 3768: 3769: 3770: 3771: 3772: 3773: 3774: 3775: 3776: 3777: 3778: 3779: 3780: 3781: 3782: 3783: 3784: 3785: 3786: 3787: 3788: 3789: 3790: 3791: 3792: 3793: 3794: 3795: 3796: 3797: 3798: 3799: 3800: 3801: 3802: 3803: 3804: 3805: 3806: 3807: 3808: 3809: 3810: 3811: 3812: 3813: 3814: 3815: 3816: 3817: 3818: 3819: 3820: 3821: 3822: 3823: 3824: 3825: 3826: 3827: 3828: 3829: 3830: 3831: 3832: 3833: 3834: 3835: 3836: 3837: 3838: 3839: 3840: 3841: 3842: 3843: 3844: 3845: 3846: 3847: 3848: 3849: 3850: 3851: 3852: 3853: 3854: 3855: 3856: 3857: 3858: 3859: 3860: 3861: 3862: 3863: 3864: 3865: 3866: 3867: 3868: 3869: 3870: 3871: 3872: 3873: 3874: 3875: 3876: 3877: 3878: 3879: 3880: 3881: 3882: 3883: 3884: 3885: 3886: 3887: 3888: 3889: 3890: 3891: 3892: 3893: 3894: 3895: 3896: 3897: 3898: 3899: 3900: 3901: 3902: 3903: 3904: 3905: 3906: 3907: 3908: 3909: 3910: 3911: 3912: 3913: 3914: 3915: 3916: 3917: 3918: 3919: 3920: 3921: 3922: 3923: 3924: 3925: 3926: 3927: 3928: 3929: 3930: 3931: 3932: 3933: 3934: 3935: 3936: 3937: 3938: 3939: 3940: 3941: 3942: 3943: 3944: 3945: 3946: 3947: 3948: 3949: 3950: 3951: 3952: 3953: 3954: 3955: 3956: 3957: 3958: 3959: 3960: 3961: 3962: 3963: 3964: 3965: 3966: 3967: 3968: 3969: 3970: 3971: 3972: 3973: 3974: 3975: 3976: 3977: 3978: 3979: 3980: 3981: 3982: 3983: 3984: 3985: 3986: 3987: 3988: 3989: 3990: 3991: 3992: 3993: 3994: 3995: 3996: 3997: 3998: 3999: 4000: 4001: 4002: 4003: 4004: 4005: 4006: 4007: 4008: 4009: 4010: 4011: 4012: 4013: 4014: 4015: 4016: 4017: 4018: 4019: 4020: 4021: 4022: 4023: 4024: 4025: 4026: 4027: 4028: 4029: 4030: 4031: 4032: 4033: 4034: 4035: 4036: 4037: 4038: 4039: 4040: 4041: 4042: 4043: 4044: 4045: 4046: 4047: 4048: 4049: 4050: 4051: 4052: 4053: 4054: 4055: 4056: 4057: 4058: 4059: 4060: 4061: 4062: 4063: 4064: 4065: 4066: 4067: 4068: 4069: 4070: 4071: 4072: 4073: 4074: 4075: 4076: 4077: 4078: 4079: 4080: 4081: 4082: 4083: 4084: 4085: 4086: 4087: 4088: 4089: 4090: 4091: 4092: 4093: 4094: 4095: 4096: 4097: 4098: 4099: 4100: 4101: 4102: 4103: 4104: 4105: 4106: 4107: 4108: 4109: 4110: 4111: 4112: 4113: 4114: 4115: 4116: 4117: 4118: 4119: 4120: 4121: 4122: 4123: 4124: 4125: 4126: 4127: 4128: 4129: 4130: 4131: 4132: 4133: 4134: 4135: 4136: 4137: 4138: 4139: 4140: 4141: 4142: 4143: 4144: 4145: 4146: 4147: 4148: 4149: 4150: 4151: 4152: 4153: 4154: 4155: 4156: 4157: 4158: 4159: 4160: 4161: 4162: 4163: 4164: 4165: 4166: 4167: 4168: 4169: 4170: 4171: 4172: 4173: 4174: 4175: 4176: 4177: 4178: 4179: 4180: 4181: 4182: 4183: 4184: 4185: 4186: 4187: 4188: 4189: 4190: 4191: 4192: 4193: 4194: 4195: 4196: 4197: 4198: 4199: 4200: 4201: 4202: 4203: 4204: 4205: 4206: 4207: 4208: 4209: 4210: 4211: 4212: 4213: 4214: 4215: 4216: 4217: 4218: 4219: 4220: 4221: 4222: 4223: 4224: 4225: 4226: 4227: 4228: 4229: 4230: 4231: 4232: 4233: 4234: 4235: 4236: 4237: 4238: 4239: 4240: 4241: 4242: 4243: 4244: 4245: 4246: 4247: 4248: 4249: 4250: 4251: 4252: 4253: 4254: 4255: 4256: 4257: 4258: 4259: 4260: 4261: 4262: 4263: 4264: 4265: 4266: 4267: 4268: 4269: 4270: 4271: 4272: 4273: 4274: 4275: 4276: 4277: 4278: 4279: 4280: 4281: 4282: 4283: 4284: 4285: 4286: 4287: 4288: 4289: 4290: 4291: 4292: 4293: 4294: 4295: 4296: 4297: 4298: 4299: 4300: 4301: 4302: 4303: 4304: 4305: 4306: 4307: 4308: 4309: 4310: 4311: 4312: 4313: 4314: 4315: 4316: 4317: 4318: 4319: 4320: 4321: 4322: 4323: 4324: 4325: 4326: 4327: 4328: 4329: 4330: 4331: 4332: 4333: 4334: 4335: 4336: 4337: 4338: 4339: 4340: 4341: 4342: 4343: 4344: 4345: 4346: 4347: 4348: 4349: 4350: 4351: 4352: 4353: 4354: 4355: 4356: 4357: 4358: 4359: 4360: 4361: 4362: 4363: 4364: 4365: 4366: 4367: 4368: 4369: 4370: 4371: 4372: 4373: 4374: 4375: 4376: 4377: 4378: 4379: 4380: 4381: 4382: 4383: 4384: 4385: 4386: 4387: 4388: 4389: 4390: 4391: 4392: 4393: 4394: 4395: 4396: 4397: 4398: 4399: 4400: 4401: 4402: 4403: 4404: 4405: 4406: 4407: 4408: 4409: 4410: 4411: 4412: 4413: 4414: 4415: 4416: 4417: 4418: 4419: 4420: 4421: 4422: 4423: 4424: 4425: 4426: 4427: 4428: 4429: 4430: 4431: 4432: 4433: 4434: 4435: 4436: 4437: 4438: 4439: 4440: 4441: 4442: 4443: 4444: 4445: 4446: 4447: 4448: 4449: 4450: 4451: 4452: 4453: 4454: 4455: 4456: 4457: 4458: 4459: 4460: 4461: 4462: 4463: 4464: 4465: 4466: 4467: 4468: 4469: 4470: 4471: 4472: 4473: 4474: 4475: 4476: 4477: 4478: 4479: 4480: 4481: 4482: 4483: 4484: 4485: 4486: 4487: 4488: 4489: 4490: 4491: 4492: 4493: 4494: 4495: 4496: 4497: 4498: 4499: 4500: 4501: 4502: 4503: 4504: 4505: 4506: 4507: 4508: 4509: 4510: 4511: 4512: 4513: 4514: 4515: 4516: 4517: 4518: 4519: 4520: 4521: 4522: 4523: 4524: 4525: 4526: 4527: 4528: 4529: 4530: 4531: 4532: 4533: 4534: 4535: 4536: 4537: 4538: 4539: 4540: 4541: 4542: 4543: 4544: 4545: 4546: 4547: 4548: 4549: 4550: 4551: 4552: 4553: 4554: 4555: 4556: 4557: 4558: 4559: 4560: 4561: 4562: 4563: 4564: 4565: 4566: 4567: 4568: 4569: 4570: 4571: 4572: 4573: 4574: 4575: 4576: 4577: 4578: 4579: 4580: 4581: 4582: 4583: 4584: 4585: 4586: 4587: 4588: 4589: 4590: 4591: 4592: 4593: 4594: 4595: 4596: 4597: 4598: 4599: 4600: 4601: 4602: 4603: 4604: 4605: 4606: 4607: 4608: 4609: 4610: 4611: 4612: 4613: 4614: 4615: 4616: 4617: 4618: 4619: 4620: 4621: 4622: 4623: 4624: 4625: 4626: 4627: 4628: 4629: 4630: 4631: 4632: 4633: 4634: 4635: 4636: 4637: 4638: 4639: 4640: 4641: 4642: 4643: 4644: 4645: 4646: 4647: 4648: 4649: 4650: 4651: 4652: 4653: 4654: 4655: 4656: 4657: 4658: 4659: 4660: 4661: 4662: 4663: 4664: 4665: 4666: 4667: 4668: 4669: 4670: 4671: 4672: 4673: 4674: 4675: 4676: 4677: 4678: 4679: 4680: 4681: 4682: 4683: 4684: 4685: 4686: 4687: 4688: 4689: 4690: 4691: 4692: 4693: 4694: 4695: 4696: 4697: 4698: 4699: 4700: 4701: 4702: 4703: 4704: 4705: 4706: 4707: 4708: 4709: 4710: 4711: 4712: 4713: 4714: 4715: 4716: 4717: 4718: 4719: 4720: 4721: 4722: 4723: 4724: 4725: 4726: 4727: 4728: 4729: 4730: 4731: 4732: 4733: 4734: 4735: 4736: 4737: 4738: 4739: 4740: 4741: 4742: 4743: 4744: 4745: 4746: 4747: 4748: 4749: 4750: 4751: 4752: 4753: 4754: 4755: 4756: 4757: 4758: 4759: 4760: 4761: 4762: 4763: 4764: 4765: 4766: 4767: 4768: 4769: 4770: 4771: 4772: 4773: 4774: 4775: 4776: 4777: 4778: 4779: 4780: 4781: 4782: 4783: 4784: 4785: 4786: 4787: 4788: 4789: 4790: 4791: 4792: 4793: 4794: 4795: 4796: 4797: 4798: 4799: 4800: 4801: 4802: 4803: 4804: 4805: 4806: 4807: 4808: 4809: 4810: 4811: 4812: 4813: 4814: 4815: 4816: 4817: 4818: 4819: 4820: 4821: 4822: 4823: 4824: 4825: 4826: 4827: 4828: 4829: 4830: 4831: 4832: 4833: 4834: 4835: 4836: 4837: 4838: 4839: 4840: 4841: 4842: 4843: 4844: 4845: 4846: 4847: 4848: 4849: 4850: 4851: 4852: 4853: 4854: 4855: 4856: 4857: 4858: 4859: 4860: 4861: 4862: 4863: 4864: 4865: 4866: 4867: 4868: 4869: 4870: 4871: 4872: 4873: 4874: 4875: 4876: 4877: 4878: 4879: 4880: 4881: 4882: 4883: 4884: 4885: 4886: 4887: 4888: 4889: 4890: 4891: 4892: 4893: 4894: 4895: 4896: 4897: 4898: 4899: 4900: 4901: 4902: 4903: 4904: 4905: 4906: 4907: 4908: 4909: 4910: 4911: 4912: 4913: 4914: 4915: 4916: 4917: 4918: 4919: 4920: 4921: 4922: 4923: 4924: 4925: 4926: 4927: 4928: 4929: 4930: 4931: 4932: 4933: 4934: 4935: 4936: 4937: 4938: 4939: 4940: 4941: 4942: 4943: 4944: 4945: 4946: 4947: 4948: 4949: 4950: 4951: 4952: 4953: 4954: 4955: 4956: 4957: 4958: 4959: 4960: 4961: 4962: 4963: 4964: 4965: 4966: 4967: 4968: 4969: 4970: 4971: 4972: 4973: 4974: 4975: 4976: 4977: 4978: 4979: 4980: 4981: 4982: 4983: 4984: 4985: 4986: 4987: 4988: 4989: 4990: 4991: 4992: 4993: 4994: 4995: 4996: 4997: 4998: 4999: 5000: 5001: 5002: 5003: 5004: 5005: 5006: 5007: 5008: 5009: 5010: 5011: 5012: 5013: 5014: 5015: 5016: 5017: 5018: 5019: 5020: 5021: 5022: 5023: 5024: 5025: 5026: 5027: 5028: 5029:
<?php
define('SMF_VERSION', '2.1 RC2');
define('SMF_FULL_VERSION', 'SMF ' . SMF_VERSION);
define('SMF_SOFTWARE_YEAR', '2020');
define('SMF_LANG_VERSION', '2.1 RC2');
define('SMF_INSTALLING', 1);
define('JQUERY_VERSION', '3.4.1');
define('POSTGRE_TITLE', 'PostgreSQL');
define('MYSQL_TITLE', 'MySQL');
define('SMF_USER_AGENT', 'Mozilla/5.0 (' . php_uname('s') . ' ' . php_uname('m') . ') AppleWebKit/605.1.15 (KHTML, like Gecko) SMF/' . strtr(SMF_VERSION, ' ', '.'));
if (!defined('TIME_START'))
define('TIME_START', microtime(true));
$GLOBALS['required_php_version'] = '5.4.0';
$databases = array(
'mysql' => array(
'name' => 'MySQL',
'version' => '5.0.22',
'version_check' => 'global $db_connection; return min(mysqli_get_server_info($db_connection), mysqli_get_client_info());',
'utf8_support' => true,
'utf8_version' => '5.0.22',
'utf8_version_check' => 'global $db_connection; return mysqli_get_server_info($db_connection);',
'alter_support' => true,
),
'postgresql' => array(
'name' => 'PostgreSQL',
'version' => '9.4',
'version_check' => '$version = pg_version(); return $version[\'client\'];',
'always_has_db' => true,
),
);
$timeLimitThreshold = 3;
$upgrade_path = dirname(__FILE__);
$upgradeurl = $_SERVER['PHP_SELF'];
$disable_security = false;
$upcontext['inactive_timeout'] = 10;
global $txt;
$upcontext['steps'] = array(
0 => array(1, 'upgrade_step_login', 'WelcomeLogin', 2),
1 => array(2, 'upgrade_step_options', 'UpgradeOptions', 2),
2 => array(3, 'upgrade_step_backup', 'BackupDatabase', 10),
3 => array(4, 'upgrade_step_database', 'DatabaseChanges', 50),
4 => array(5, 'upgrade_step_convertjson', 'serialize_to_json', 10),
5 => array(6, 'upgrade_step_convertutf', 'ConvertUtf8', 20),
6 => array(7, 'upgrade_step_delete', 'DeleteUpgrade', 1),
);
$upcontext['database_step'] = 3;
@set_time_limit(600);
if (!ini_get('safe_mode'))
{
ini_set('mysql.connect_timeout', -1);
ini_set('default_socket_timeout', 900);
}
if (!empty($_SERVER['argv']) && php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']))
for ($i = 1; $i < $_SERVER['argc']; $i++)
{
if (preg_match('~^--path=(.+)$~', $_SERVER['argv'][$i], $match) != 0)
$upgrade_path = substr($match[1], -1) == '/' ? substr($match[1], 0, -1) : $match[1];
}
if (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']))
{
$command_line = true;
$disable_security = true;
}
else
$command_line = false;
foreach (array('upgrade-helper.php', 'Settings.php') as $required_file)
{
if (!file_exists($upgrade_path . '/' . $required_file))
die($required_file . ' was not found where it was expected: ' . $upgrade_path . '/' . $required_file . '! Make sure you have uploaded ALL files from the upgrade package to your forum\'s root directory. The upgrader cannot continue.');
require_once($upgrade_path . '/' . $required_file);
}
if (isset($language))
$language = str_ireplace('-utf8', '', basename($language, '.lng'));
if (isset($_SERVER['QUERY_STRING']) && preg_match('~\blang=(\w+)~', $_SERVER['QUERY_STRING'], $matches))
$upcontext['lang'] = $matches[1];
if (isset($upgradeData))
{
$upcontext['user'] = json_decode(base64_decode($upgradeData), true);
if (empty($upcontext['user']['started']) || $upcontext['user']['started'] < time() - 86400)
$upcontext['user']['started'] = time();
if (empty($upcontext['user']['updated']) || $upcontext['user']['updated'] < time() - 86400)
$upcontext['user']['updated'] = 0;
$upcontext['started'] = $upcontext['user']['started'];
$upcontext['updated'] = $upcontext['user']['updated'];
$is_debug = !empty($upcontext['user']['debug']) ? true : false;
$upcontext['skip_db_substeps'] = !empty($upcontext['user']['skip_db_substeps']);
}
if (empty($upcontext['updated']))
{
$upcontext['started'] = time();
$upcontext['updated'] = 0;
$upcontext['skip_db_substeps'] = false;
$upcontext['user'] = array(
'id' => 0,
'name' => 'Guest',
'pass' => 0,
'started' => $upcontext['started'],
'updated' => $upcontext['updated'],
);
}
load_lang_file();
loadEssentialData();
if (isset($_GET['ssi']))
{
require_once($sourcedir . '/Errors.php');
require_once($sourcedir . '/Logging.php');
require_once($sourcedir . '/Load.php');
require_once($sourcedir . '/Security.php');
require_once($sourcedir . '/Subs-Package.php');
if (!isset($smcFunc['json_encode']))
{
$smcFunc['json_encode'] = 'json_encode';
$smcFunc['json_decode'] = 'smf_json_decode';
}
loadUserSettings();
loadPermissions();
}
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/LogInOut.php');
require_once($sourcedir . '/Subs-Editor.php');
if (!isset($modSettings['smfVersion']))
$disable_security = true;
if (isset($modSettings['smfVersion']))
{
$request = $smcFunc['db_query']('', '
SELECT variable, value
FROM {db_prefix}themes
WHERE id_theme = {int:id_theme}
AND variable IN ({string:theme_url}, {string:theme_dir}, {string:images_url})',
array(
'id_theme' => 1,
'theme_url' => 'theme_url',
'theme_dir' => 'theme_dir',
'images_url' => 'images_url',
'db_error_skip' => true,
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
$modSettings[$row['variable']] = $row['value'];
$smcFunc['db_free_result']($request);
}
if (!isset($modSettings['theme_url']))
{
$modSettings['theme_dir'] = $boarddir . '/Themes/default';
$modSettings['theme_url'] = 'Themes/default';
$modSettings['images_url'] = 'Themes/default/images';
}
if (!isset($settings['default_theme_url']))
$settings['default_theme_url'] = $modSettings['theme_url'];
if (!isset($settings['default_theme_dir']))
$settings['default_theme_dir'] = $modSettings['theme_dir'];
if (!isset($modSettings['rand_seed']))
{
if (!function_exists('cache_put_data'))
require_once($sourcedir . '/Load.php');
smf_seed_generator();
}
if (httpsOn())
$settings['default_theme_url'] = strtr($settings['default_theme_url'], array('http://' => 'https://'));
$upcontext['is_large_forum'] = (empty($modSettings['smfVersion']) || $modSettings['smfVersion'] <= '1.1 RC1') && !empty($modSettings['totalMessages']) && $modSettings['totalMessages'] > 75000;
if (isset($_GET['data']))
{
global $is_debug;
$upcontext['upgrade_status'] = json_decode(base64_decode($_GET['data']), true);
$upcontext['current_step'] = $upcontext['upgrade_status']['curstep'];
$upcontext['language'] = $upcontext['upgrade_status']['lang'];
$upcontext['rid'] = $upcontext['upgrade_status']['rid'];
$support_js = $upcontext['upgrade_status']['js'];
if (empty($is_debug))
$is_debug = $upcontext['upgrade_status']['debug'];
}
else
{
$upcontext['current_step'] = 0;
$upcontext['rid'] = mt_rand(0, 5000);
$upcontext['upgrade_status'] = array(
'curstep' => 0,
'lang' => isset($upcontext['lang']) ? $upcontext['lang'] : basename($language, '.lng'),
'rid' => $upcontext['rid'],
'pass' => 0,
'debug' => 0,
'js' => 0,
);
$upcontext['language'] = $upcontext['upgrade_status']['lang'];
}
load_lang_file();
$upcontext['page_title'] = $txt['updating_smf_installation'];
if ($upcontext['current_step'] != 0 || !empty($upcontext['user']['step']))
checkLogin();
if ($command_line)
cmdStep0();
if (isset($_GET['xml']))
$upcontext['return_error'] = true;
$upcontext['overall_percent'] = 0;
foreach ($upcontext['steps'] as $num => $step)
{
if ($num >= $upcontext['current_step'])
{
$upcontext['step_weight'] = $step[3];
$upcontext['skip'] = false;
if ($num != 0 && !$disable_security && $upcontext['user']['pass'] != $upcontext['upgrade_status']['pass'])
{
$upcontext['steps'][0][2]();
break;
}
if (function_exists($step[2]) && $step[2]() === false)
break;
elseif (function_exists($step[2]))
{
unset($_GET['xml']);
unset($upcontext['custom_warning']);
$_GET['substep'] = 0;
$upcontext['current_step']++;
}
}
$upcontext['overall_percent'] += $step[3];
}
upgradeExit();
function upgradeExit($fallThrough = false)
{
global $upcontext, $upgradeurl, $sourcedir, $command_line, $is_debug, $txt;
if (!empty($upcontext['current_step']) && !empty($upcontext['user']['id']))
{
$upcontext['user']['step'] = $upcontext['current_step'];
$upcontext['user']['substep'] = $_GET['substep'];
$upcontext['user']['updated'] = time();
$upcontext['user']['skip_db_substeps'] = !empty($upcontext['skip_db_substeps']);
$upcontext['debug'] = $is_debug;
$upgradeData = base64_encode(json_encode($upcontext['user']));
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile(array('upgradeData' => $upgradeData));
updateDbLastError(0);
}
if (!empty($upcontext['step_progress']) && isset($upcontext['steps'][$upcontext['current_step']]))
{
$upcontext['step_progress'] = round($upcontext['step_progress'], 1);
$upcontext['overall_percent'] += $upcontext['step_progress'] * ($upcontext['steps'][$upcontext['current_step']][3] / 100);
}
$upcontext['overall_percent'] = (int) $upcontext['overall_percent'];
if (!$fallThrough)
{
if (!empty($command_line))
{
if (function_exists('debug_print_backtrace'))
debug_print_backtrace();
printf($txt['error_unexpected_template_call'], isset($upcontext['sub_template']) ? $upcontext['sub_template'] : '');
flush();
die();
}
if (!isset($_GET['xml']))
template_upgrade_above();
else
{
header('content-type: text/xml; charset=UTF-8');
$upcontext['get_data'] = array();
foreach ($_GET as $k => $v)
{
if (substr($k, 0, 3) != 'amp' && !in_array($k, array('xml', 'substep', 'lang', 'data', 'step', 'filecount')))
{
$upcontext['get_data'][$k] = $v;
}
}
template_xml_above();
}
if (isset($upcontext['sub_template']))
{
$upcontext['upgrade_status']['curstep'] = $upcontext['current_step'];
$upcontext['form_url'] = $upgradeurl . '?step=' . $upcontext['current_step'] . '&substep=' . $_GET['substep'] . '&data=' . base64_encode(json_encode($upcontext['upgrade_status']));
if (!empty($upcontext['query_string']))
$upcontext['form_url'] .= $upcontext['query_string'];
if (is_callable('template_' . $upcontext['sub_template']))
call_user_func('template_' . $upcontext['sub_template']);
else
die(sprintf($txt['error_invalid_template'], $upcontext['sub_template']));
}
if (!empty($upcontext['forced_error_message']))
echo $upcontext['forced_error_message'];
if (!isset($_GET['xml']))
template_upgrade_below();
else
template_xml_below();
}
if (!empty($command_line) && $is_debug)
{
$active = time() - $upcontext['started'];
$hours = floor($active / 3600);
$minutes = intval(($active / 60) % 60);
$seconds = intval($active % 60);
if ($hours > 0)
echo "\n" . '', sprintf($txt['upgrade_completed_time_hms'], $hours, $minutes, $seconds), '' . "\n";
elseif ($minutes > 0)
echo "\n" . '', sprintf($txt['upgrade_completed_time_ms'], $minutes, $seconds), '' . "\n";
elseif ($seconds > 0)
echo "\n" . '', sprintf($txt['upgrade_completed_time_s'], $seconds), '' . "\n";
}
die();
}
function load_lang_file()
{
global $txt, $upcontext, $language, $modSettings;
static $lang_dir = '', $detected_languages = array(), $loaded_langfile = '';
$temp = isset($modSettings['theme_dir']) ? $modSettings['theme_dir'] . '/languages' : dirname(__FILE__) . '/Themes/default/languages';
if ($lang_dir != $temp)
{
$lang_dir = $temp;
$detected_languages = array();
}
if (isset($upcontext['language']))
$_SESSION['upgrader_langfile'] = 'Install.' . $upcontext['language'] . '.php';
elseif (isset($upcontext['lang']))
$_SESSION['upgrader_langfile'] = 'Install.' . $upcontext['lang'] . '.php';
elseif (isset($language))
$_SESSION['upgrader_langfile'] = 'Install.' . $language . '.php';
if (isset($_SESSION['upgrader_langfile']) && $loaded_langfile == $lang_dir . '/' . $_SESSION['upgrader_langfile'])
return;
if (empty($detected_languages))
{
if (file_exists($lang_dir))
{
$dir = dir($lang_dir);
while ($entry = $dir->read())
{
if (strpos($entry, '-utf8') !== false)
continue;
if (substr($entry, 0, 8) == 'Install.' && substr($entry, -4) == '.php')
$detected_languages[$entry] = ucfirst(substr($entry, 8, strlen($entry) - 12));
}
$dir->close();
}
elseif (!isset($modSettings['theme_dir']))
{
$txt['error_db_connect_settings'] = 'Cannot connect to the database server.<br><br>Please check that the database info variables are correct in Settings.php.';
$txt['error_sourcefile_missing'] = 'Unable to find the Sources/%1$s file. Please make sure it was uploaded properly, and then try again.';
$txt['warning_lang_old'] = 'The language files for your selected language, %1$s, have not been updated to the latest version. Upgrade will continue with the forum default, %2$s.';
$txt['warning_lang_missing'] = 'The upgrader could not find the "Install" language file for your selected language, %1$s. Upgrade will continue with the forum default, %2$s.';
return;
}
}
if (empty($detected_languages))
{
$from = explode('/', $_SERVER['PHP_SELF']);
$to = explode('/', $lang_dir);
$relPath = $to;
foreach($from as $depth => $dir)
{
if ($dir === $to[$depth])
array_shift($relPath);
else
{
$remaining = count($from) - $depth;
if ($remaining > 1)
{
$padLength = (count($relPath) + $remaining - 1) * -1;
$relPath = array_pad($relPath, $padLength, '..');
break;
}
else
$relPath[0] = './' . $relPath[0];
}
}
$relPath = implode(DIRECTORY_SEPARATOR, $relPath);
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-cache');
echo '<!DOCTYPE html>
<html>
<head>
<title>SMF Upgrader: Error!</title>
<style>
body {
font-family: sans-serif;
max-width: 700px; }
h1 {
font-size: 14pt; }
.directory {
margin: 0.3em;
font-family: monospace;
font-weight: bold; }
</style>
</head>
<body>
<h1>A critical error has occurred.</h1>
<p>This upgrader was unable to find the upgrader\'s language file or files. They should be found under:</p>
<div class="directory">', $relPath, '</div>
<p>In some cases, FTP clients do not properly upload files with this many folders. Please double check to make sure you <strong>have uploaded all the files in the distribution</strong>.</p>
<p>If that doesn\'t help, please make sure this upgrade.php file is in the same place as the Themes folder.</p>
<p>If you continue to get this error message, feel free to <a href="https://support.simplemachines.org/">look to us for support</a>.</p>
</body>
</html>';
die;
}
if (!isset($_SESSION['upgrader_langfile']) || preg_match('~[^\w.-]~', $_SESSION['upgrader_langfile']) === 1 || !file_exists($lang_dir . '/' . $_SESSION['upgrader_langfile']))
{
list ($_SESSION['upgrader_langfile']) = array_keys($detected_languages);
if ($_SESSION['upgrader_langfile'] == 'Install.english.php' && count($detected_languages) > 1)
list (, $_SESSION['upgrader_langfile']) = array_keys($detected_languages);
}
if ($_SESSION['upgrader_langfile'] != 'Install.english.php')
require_once($lang_dir . '/Install.english.php');
require_once($lang_dir . '/' . $_SESSION['upgrader_langfile']);
$loaded_langfile = $lang_dir . '/' . $_SESSION['upgrader_langfile'];
}
function redirectLocation($location, $addForm = true)
{
global $upgradeurl, $upcontext, $command_line;
if ($command_line)
upgradeExit(true);
if ($addForm)
{
$upcontext['upgrade_status']['curstep'] = $upcontext['current_step'];
$location = $upgradeurl . '?step=' . $upcontext['current_step'] . '&substep=' . $_GET['substep'] . '&data=' . base64_encode(json_encode($upcontext['upgrade_status'])) . $location;
}
while (@ob_end_clean())
header('location: ' . strtr($location, array('&' => '&')));
upgradeExit(true);
}
function loadEssentialData()
{
global $db_server, $db_user, $db_passwd, $db_name, $db_connection;
global $db_prefix, $db_character_set, $db_type, $db_port;
global $db_mb4, $modSettings, $sourcedir, $smcFunc, $txt, $utf8;
error_reporting(E_ALL);
define('SMF', 1);
if (@ini_get('session.save_handler') == 'user')
@ini_set('session.save_handler', 'files');
@session_start();
if (empty($smcFunc))
$smcFunc = array();
require_once($sourcedir . '/Subs.php');
$smcFunc['random_int'] = function($min = 0, $max = PHP_INT_MAX)
{
global $sourcedir;
if (!is_callable('random_int'))
require_once($sourcedir . '/random_compat/random.php');
return random_int($min, $max);
};
require_once($sourcedir . '/Subs-Auth.php');
require_once($sourcedir . '/Class-Package.php');
$smcFunc['strtolower'] = 'smf_strtolower';
initialize_inputs();
$utf8 = (empty($modSettings['global_character_set']) ? $txt['lang_character_set'] : $modSettings['global_character_set']) === 'UTF-8';
if (empty($db_type) || $db_type == 'mysqli')
{
$db_type = 'mysql';
$changes = array();
$changes['db_type'] = 'mysql';
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile($changes);
}
if (file_exists($sourcedir . '/Subs-Db-' . $db_type . '.php'))
{
require_once($sourcedir . '/Subs-Db-' . $db_type . '.php');
if (empty($db_connection))
{
$options = array('non_fatal' => true);
if (!empty($db_port))
$options['port'] = $db_port;
if (!empty($db_mb4))
$options['db_mb4'] = $db_mb4;
$db_connection = smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, $options);
}
else
$smcFunc['db_ping']($db_connection);
if ($db_connection === null)
die($txt['error_db_connect_settings']);
if ($db_type == 'mysql' && isset($db_character_set) && preg_match('~^\w+$~', $db_character_set) === 1)
$smcFunc['db_query']('', '
SET NAMES {string:db_character_set}',
array(
'db_error_skip' => true,
'db_character_set' => $db_character_set,
)
);
$request = $smcFunc['db_query']('', '
SELECT variable, value
FROM {db_prefix}settings',
array(
'db_error_skip' => true,
)
);
$modSettings = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$modSettings[$row['variable']] = $row['value'];
$smcFunc['db_free_result']($request);
}
else
return throw_error(sprintf($txt['error_sourcefile_missing'], 'Subs-Db-' . $db_type . '.php'));
if (file_exists($sourcedir . '/QueryString.php') && php_version_check())
{
require_once($sourcedir . '/QueryString.php');
cleanRequest();
}
if (!isset($_GET['substep']))
$_GET['substep'] = 0;
}
function initialize_inputs()
{
global $start_time, $db_type;
$start_time = time();
umask(0);
ob_start();
ignore_user_abort(true);
if (isset($_GET['delete']))
{
@unlink(__FILE__);
@unlink(dirname(__FILE__) . '/upgrade_1-0.sql');
@unlink(dirname(__FILE__) . '/upgrade_1-1.sql');
@unlink(dirname(__FILE__) . '/upgrade_2-0_' . $db_type . '.sql');
@unlink(dirname(__FILE__) . '/upgrade_2-1_' . $db_type . '.sql');
@unlink(dirname(__FILE__) . '/upgrade-helper.php');
$dh = opendir(dirname(__FILE__));
while ($file = readdir($dh))
{
if (preg_match('~upgrade_\d-\d_([A-Za-z])+\.sql~i', $file, $matches) && isset($matches[1]))
@unlink(dirname(__FILE__) . '/' . $file);
}
closedir($dh);
@unlink(dirname(__FILE__) . '/Sources/ModSettings.php');
@unlink(dirname(__FILE__) . '/Themes/default/Combat.template.php');
@unlink(dirname(__FILE__) . '/Themes/default/Modlog.template.php');
@unlink(dirname(__FILE__) . '/Themes/default/fader.js');
@unlink(dirname(__FILE__) . '/Themes/default/script.js');
@unlink(dirname(__FILE__) . '/Themes/default/spellcheck.js');
@unlink(dirname(__FILE__) . '/Themes/default/xml_board.js');
@unlink(dirname(__FILE__) . '/Themes/default/xml_topic.js');
@unlink(dirname(__FILE__) . '/Sources/DumpDatabase.php');
@unlink(dirname(__FILE__) . '/Sources/LockTopic.php');
header('location: http://' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']) . dirname($_SERVER['PHP_SELF']) . '/Themes/default/images/blank.png');
exit;
}
$temp = 'upgrade_php?step';
while (strlen($temp) > 4)
{
if (isset($_GET[$temp]))
unset($_GET[$temp]);
$temp = substr($temp, 1);
}
$_GET['step'] = (int) @$_GET['step'];
$_GET['substep'] = (int) @$_GET['substep'];
}
function WelcomeLogin()
{
global $boarddir, $sourcedir, $modSettings, $cachedir, $upgradeurl, $upcontext;
global $smcFunc, $db_type, $databases, $boardurl;
global $txt;
$upcontext['sub_template'] = 'welcome_message';
$check = @file_exists($modSettings['theme_dir'] . '/index.template.php')
&& @file_exists($sourcedir . '/QueryString.php')
&& @file_exists($sourcedir . '/Subs-Db-' . $db_type . '.php')
&& @file_exists(dirname(__FILE__) . '/upgrade_2-1_' . $db_type . '.sql');
if (!isset($modSettings['smfVersion']) || $modSettings['smfVersion'] < 2.1)
$check &= @file_exists(dirname(__FILE__) . '/upgrade_2-0_' . $db_type . '.sql');
if (!isset($modSettings['smfVersion']) || $modSettings['smfVersion'] < 2.0)
$check &= @file_exists(dirname(__FILE__) . '/upgrade_1-1.sql');
if (!isset($modSettings['smfVersion']) || $modSettings['smfVersion'] < 1.1)
$check &= @file_exists(dirname(__FILE__) . '/upgrade_1-0.sql');
$upcontext['language'] = str_ireplace('-utf8', '', $upcontext['language']);
if (!$check)
return throw_error($txt['error_upgrade_files_missing']);
if (!php_version_check())
return throw_error($txt['error_php_too_low']);
if (!db_version_check())
return throw_error(sprintf($txt['error_db_too_low'], $databases[$db_type]['name']));
db_extend('packages');
$create = $smcFunc['db_create_table']('{db_prefix}priv_check', array(array('name' => 'id_test', 'type' => 'int', 'size' => 10, 'unsigned' => true, 'auto' => true)), array(array('columns' => array('id_test'), 'type' => 'primary')), array(), 'overwrite');
$alter = $smcFunc['db_add_column']('{db_prefix}priv_check', array('name' => 'txt', 'type' => 'varchar', 'size' => 4, 'null' => false, 'default' => ''));
$drop = $smcFunc['db_drop_table']('{db_prefix}priv_check');
if (!$create || !$alter || !$drop)
return throw_error(sprintf($txt['error_db_privileges'], $databases[$db_type]['name']));
$temp = substr(@implode('', @file($boarddir . '/index.php')), 0, 4096);
preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $temp, $match);
if (empty($match[1]) || (trim($match[1]) != SMF_VERSION))
return throw_error($txt['error_upgrade_old_files']);
$writable_files = array(
$boarddir . '/Settings.php',
$boarddir . '/Settings_bak.php',
);
if (!empty($modSettings['minimize_files']) || !isset($modSettings['minimize_files']))
$writable_files += array(
$modSettings['theme_dir'] . '/css/minified.css',
$modSettings['theme_dir'] . '/scripts/minified.js',
$modSettings['theme_dir'] . '/scripts/minified_deferred.js',
);
$need_settings_update = empty($modSettings['custom_avatar_dir']);
$custom_av_dir = !empty($modSettings['custom_avatar_dir']) ? $modSettings['custom_avatar_dir'] : $GLOBALS['boarddir'] . '/custom_avatar';
$custom_av_url = !empty($modSettings['custom_avatar_url']) ? $modSettings['custom_avatar_url'] : $boardurl . '/custom_avatar';
quickFileWritable($custom_av_dir);
if (!is_writable($custom_av_dir))
return throw_error(sprintf($txt['error_dir_not_writable'], $custom_av_dir));
elseif ($need_settings_update)
{
if (!function_exists('cache_put_data'))
require_once($sourcedir . '/Load.php');
updateSettings(array('custom_avatar_dir' => $custom_av_dir));
updateSettings(array('custom_avatar_url' => $custom_av_url));
}
require_once($sourcedir . '/Security.php');
$cachedir_temp = empty($cachedir) ? $boarddir . '/cache' : $cachedir;
if (!file_exists($cachedir_temp))
@mkdir($cachedir_temp);
if (!file_exists($cachedir_temp))
return throw_error($txt['error_cache_not_found']);
quickFileWritable($cachedir_temp . '/db_last_error.php');
if (!file_exists($modSettings['theme_dir'] . '/languages/index.' . $upcontext['language'] . '.php'))
return throw_error(sprintf($txt['error_lang_index_missing'], $upcontext['language'], $upgradeurl));
elseif (!isset($_GET['skiplang']))
{
$temp = substr(@implode('', @file($modSettings['theme_dir'] . '/languages/index.' . $upcontext['language'] . '.php')), 0, 4096);
preg_match('~(?://|/\*)\s*Version:\s+(.+?);\s*index(?:[\s]{2}|\*/)~i', $temp, $match);
if (empty($match[1]) || $match[1] != SMF_LANG_VERSION)
return throw_error(sprintf($txt['error_upgrade_old_lang_files'], $upcontext['language'], $upgradeurl));
}
if (!makeFilesWritable($writable_files))
return false;
if (isset($modSettings['agreement']) && (!is_writable($boarddir) || file_exists($boarddir . '/agreement.txt')) && !is_writable($boarddir . '/agreement.txt'))
return throw_error($txt['error_agreement_not_writable']);
elseif (isset($modSettings['agreement']))
{
$fp = fopen($boarddir . '/agreement.txt', 'w');
fwrite($fp, $modSettings['agreement']);
fclose($fp);
}
if (strtr($boarddir, array('/' => '', '\\' => '')) != strtr(dirname(__FILE__), array('/' => '', '\\' => '')))
$upcontext['warning'] = '
' . sprintf($txt['upgrade_boarddir_settings'], $boarddir, dirname(__FILE__)) . '<br>
<ul>
<li>' . $txt['upgrade_boarddir'] . ' ' . $boarddir . '</li>
<li>' . $txt['upgrade_sourcedir'] . ' ' . $boarddir . '</li>
<li>' . $txt['upgrade_cachedir'] . ' ' . $cachedir_temp . '</li>
</ul>
' . $txt['upgrade_incorrect_settings'] . '';
if (!extension_loaded('mbstring'))
return throw_error($txt['install_no_mbstring']);
$supported_streams = stream_get_wrappers();
if (!in_array('https', $supported_streams))
$upcontext['custom_warning'] = $txt['install_no_https'];
if (checkLogin())
return true;
$upcontext += createToken('login');
return false;
}
function checkLogin()
{
global $modSettings, $upcontext, $disable_security;
global $smcFunc, $db_type, $support_js, $sourcedir, $txt;
if (isset($_POST['contbutt']) && (!empty($_POST['user']) || $disable_security))
{
if (empty($_POST['user']))
$_POST['user'] = 'Administrator';
$oldDB = false;
if (empty($db_type) || $db_type == 'mysql')
{
$request = $smcFunc['db_query']('', '
SHOW COLUMNS
FROM {db_prefix}members
LIKE {string:member_name}',
array(
'member_name' => 'memberName',
'db_error_skip' => true,
)
);
if ($smcFunc['db_num_rows']($request) != 0)
$oldDB = true;
$smcFunc['db_free_result']($request);
}
if (!$disable_security)
{
if ($oldDB)
$request = $smcFunc['db_query']('', '
SELECT id_member, memberName AS member_name, passwd, id_group,
additionalGroups AS additional_groups, lngfile
FROM {db_prefix}members
WHERE memberName = {string:member_name}',
array(
'member_name' => $_POST['user'],
'db_error_skip' => true,
)
);
else
$request = $smcFunc['db_query']('', '
SELECT id_member, member_name, passwd, id_group, additional_groups, lngfile
FROM {db_prefix}members
WHERE member_name = {string:member_name}',
array(
'member_name' => $_POST['user'],
'db_error_skip' => true,
)
);
if ($smcFunc['db_num_rows']($request) != 0)
{
list ($id_member, $name, $password, $id_group, $addGroups, $user_language) = $smcFunc['db_fetch_row']($request);
$groups = explode(',', $addGroups);
$groups[] = $id_group;
foreach ($groups as $k => $v)
$groups[$k] = (int) $v;
$sha_passwd = sha1(strtolower($name) . un_htmlspecialchars($_REQUEST['passwrd']));
$user_language = str_ireplace('-utf8', '', $user_language);
}
else
$upcontext['username_incorrect'] = true;
$smcFunc['db_free_result']($request);
}
$upcontext['username'] = $_POST['user'];
if (isset($_POST['js_works']))
{
if (!empty($_POST['js_works']))
{
$upcontext['upgrade_status']['js'] = 1;
$support_js = 1;
}
else
$support_js = 0;
}
if (!empty($modSettings['smfVersion']) && empty($upcontext['user']['version']))
$upcontext['user']['version'] = $modSettings['smfVersion'];
if (!$disable_security && (empty($sha_passwd) || (!empty($password) ? $password : '') != $sha_passwd) && !hash_verify_password((!empty($name) ? $name : ''), $_REQUEST['passwrd'], (!empty($password) ? $password : '')) && empty($upcontext['username_incorrect']))
{
$md5pass = md5_hmac($_REQUEST['passwrd'], strtolower($_POST['user']));
if ($md5pass != $password)
{
$upcontext['password_failed'] = true;
$upcontext['disable_login_hashing'] = true;
}
}
if ((empty($upcontext['password_failed']) && !empty($name)) || $disable_security)
{
if (!$disable_security)
{
if (!in_array(1, $groups))
{
$request = $smcFunc['db_query']('', '
SELECT permission
FROM {db_prefix}permissions
WHERE id_group IN ({array_int:groups})
AND permission = {string:admin_forum}',
array(
'groups' => $groups,
'admin_forum' => 'admin_forum',
'db_error_skip' => true,
)
);
if ($smcFunc['db_num_rows']($request) == 0)
return throw_error($txt['error_not_admin']);
$smcFunc['db_free_result']($request);
}
$upcontext['user']['id'] = $id_member;
$upcontext['user']['name'] = $name;
}
else
{
$upcontext['user']['id'] = 1;
$upcontext['user']['name'] = 'Administrator';
}
if (!is_callable('random_int'))
require_once('Sources/random_compat/random.php');
$upcontext['user']['pass'] = random_int(0, 60000);
$upcontext['upgrade_status']['pass'] = $upcontext['user']['pass'];
if (isset($user_language) && $user_language != $upcontext['language'] && file_exists($modSettings['theme_dir'] . '/languages/index.' . basename($user_language, '.lng') . '.php'))
{
$user_language = basename($user_language, '.lng');
$temp = substr(@implode('', @file($modSettings['theme_dir'] . '/languages/index.' . $user_language . '.php')), 0, 4096);
preg_match('~(?://|/\*)\s*Version:\s+(.+?);\s*index(?:[\s]{2}|\*/)~i', $temp, $match);
if (empty($match[1]) || $match[1] != SMF_LANG_VERSION)
$upcontext['upgrade_options_warning'] = sprintf($txt['warning_lang_old'], $user_language, $upcontext['language']);
elseif (!file_exists($modSettings['theme_dir'] . '/languages/Install.' . $user_language . '.php'))
$upcontext['upgrade_options_warning'] = sprintf($txt['warning_lang_missing'], $user_language, $upcontext['language']);
else
{
$upcontext['language'] = $user_language;
$upcontext['upgrade_status']['lang'] = $upcontext['language'];
load_lang_file();
}
}
if (isset($_POST['cont']))
{
$upcontext['current_step'] = $upcontext['user']['step'];
$_GET['substep'] = $upcontext['user']['substep'];
}
return true;
}
}
return false;
}
function UpgradeOptions()
{
global $db_prefix, $command_line, $modSettings, $is_debug, $smcFunc, $packagesdir, $tasksdir, $language, $txt, $db_port;
global $boarddir, $boardurl, $sourcedir, $maintenance, $cachedir, $upcontext, $db_type, $db_server, $image_proxy_enabled;
$upcontext['sub_template'] = 'upgrade_options';
$upcontext['page_title'] = $txt['upgrade_options'];
db_extend('packages');
$upcontext['karma_installed'] = array('good' => false, 'bad' => false);
$member_columns = $smcFunc['db_list_columns']('{db_prefix}members');
$upcontext['karma_installed']['good'] = in_array('karma_good', $member_columns);
$upcontext['karma_installed']['bad'] = in_array('karma_bad', $member_columns);
$upcontext['migrate_settings_recommended'] = empty($modSettings['smfVersion']) || version_compare(strtolower($modSettings['smfVersion']), substr(SMF_VERSION, 0, strpos(SMF_VERSION, '.') + 1 + strspn(SMF_VERSION, '1234567890', strpos(SMF_VERSION, '.') + 1)) . ' foo', '<');
unset($member_columns);
if (empty($_POST['upcont']))
return false;
if (!empty($_POST['stats']) && substr($boardurl, 0, 16) != 'http://localhost' && empty($modSettings['allow_sm_stats']) && empty($modSettings['enable_sm_stats']))
{
$upcontext['allow_sm_stats'] = true;
if (empty($modSettings['sm_stats_key']))
{
$fp = @fsockopen('www.simplemachines.org', 80, $errno, $errstr);
if ($fp)
{
$out = 'GET /smf/stats/register_stats.php?site=' . base64_encode($boardurl) . ' HTTP/1.1' . "\r\n";
$out .= 'Host: www.simplemachines.org' . "\r\n";
$out .= 'Connection: Close' . "\r\n\r\n";
fwrite($fp, $out);
$return_data = '';
while (!feof($fp))
$return_data .= fgets($fp, 128);
fclose($fp);
preg_match('~SITE-ID:\s(\w{10})~', $return_data, $ID);
if (!empty($ID[1]))
$smcFunc['db_insert']('replace',
$db_prefix . 'settings',
array('variable' => 'string', 'value' => 'string'),
array(
array('sm_stats_key', $ID[1]),
array('enable_sm_stats', 1),
),
array('variable')
);
}
}
else
{
$smcFunc['db_insert']('replace',
$db_prefix . 'settings',
array('variable' => 'string', 'value' => 'string'),
array('enable_sm_stats', 1),
array('variable')
);
}
}
elseif (empty($_POST['stats']) && empty($upcontext['allow_sm_stats']))
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}settings
WHERE variable = {string:enable_sm_stats}',
array(
'enable_sm_stats' => 'enable_sm_stats',
'db_error_skip' => true,
)
);
if (!empty($_POST['delete_karma']))
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}settings
WHERE variable IN ({array_string:karma_vars})',
array(
'karma_vars' => array('karmaMode', 'karmaTimeRestrictAdmins', 'karmaWaitTime', 'karmaMinPosts', 'karmaLabel', 'karmaSmiteLabel', 'karmaApplaudLabel'),
)
);
if ($upcontext['karma_installed']['good'])
$smcFunc['db_query']('', '
ALTER TABLE {db_prefix}members
DROP karma_good',
array()
);
if ($upcontext['karma_installed']['bad'])
$smcFunc['db_query']('', '
ALTER TABLE {db_prefix}members
DROP karma_bad',
array()
);
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}permissions
WHERE permission = {string:karma_vars}',
array(
'karma_vars' => 'karma_edit',
)
);
$smcFunc['db_query']('', '
DROP TABLE IF EXISTS {db_prefix}log_karma',
array()
);
}
if (!empty($_POST['empty_error']))
$smcFunc['db_query']('truncate_table', '
TRUNCATE {db_prefix}log_errors',
array(
)
);
$changes = array();
if (!isset($GLOBALS['image_proxy_secret']) || $GLOBALS['image_proxy_secret'] == 'smfisawesome')
$changes['image_proxy_secret'] = substr(sha1(mt_rand()), 0, 20);
if (!isset($GLOBALS['image_proxy_maxsize']))
$changes['image_proxy_maxsize'] = 5190;
if (!isset($GLOBALS['image_proxy_enabled']))
$changes['image_proxy_enabled'] = false;
if (!function_exists('cache_put_data'))
require_once($sourcedir . '/Load.php');
if (stripos($boardurl, 'https://') !== false)
updateSettings(array('force_ssl' => '1'));
if (isset($upcontext['lang']) && file_exists($modSettings['theme_dir'] . '/languages/index.' . $upcontext['lang'] . '.php'))
$changes['language'] = $upcontext['lang'];
if (!empty($_POST['maint']))
{
$changes['maintenance'] = 2;
$upcontext['user']['main'] = $maintenance;
if (!empty($_POST['maintitle']))
{
$changes['mtitle'] = $_POST['maintitle'];
$changes['mmessage'] = $_POST['mainmessage'];
}
else
{
$changes['mtitle'] = $txt['mtitle'];
$changes['mmessage'] = $txt['mmessage'];
}
}
if ($command_line)
echo ' * Updating Settings.php...';
if (substr($boarddir, 0, 1) == '.')
$changes['boarddir'] = fixRelativePath($boarddir);
if (substr($sourcedir, 0, 1) == '.')
$changes['sourcedir'] = fixRelativePath($sourcedir);
if (empty($cachedir) || substr($cachedir, 0, 1) == '.')
$changes['cachedir'] = fixRelativePath($boarddir) . '/cache';
if (!isset($GLOBALS['cache_enable']))
$changes += array(
'cache_accelerator' => !empty($modSettings['cache_enable']) ? 'smf' : '',
'cache_enable' => !empty($modSettings['cache_enable']) ? $modSettings['cache_enable'] : 0,
'cache_memcached' => !empty($modSettings['cache_memcached']) ? $modSettings['cache_memcached'] : '',
);
if (strpos($db_server, ':') !== false && $db_type == 'mysql')
{
list ($db_server, $db_port) = explode(':', $db_server);
$changes['db_server'] = $db_server;
if ($db_port != ini_get('mysqli.default_port'))
$changes['db_port'] = (int) $db_port;
}
if (!empty($db_port))
{
if ($db_type == 'mysql' && $db_port == ini_get('mysqli.default_port'))
$changes['db_port'] = 0;
elseif ($db_type == 'postgresql' && $db_port == 5432)
$changes['db_port'] = 0;
}
if (empty($packagesdir))
$changes['packagesdir'] = fixRelativePath($boarddir) . '/Packages';
if (empty($tasksdir))
$changes['tasksdir'] = fixRelativePath($sourcedir) . '/tasks';
if (stristr($language, '-utf8'))
$changes['language'] = str_ireplace('-utf8', '', $language);
$changes['upgradeData'] = base64_encode(json_encode($upcontext['user']));
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile($changes, false, !empty($_POST['migrateSettings']));
if ($command_line)
echo ' Successful.' . "\n";
if (isset($_POST['debug']))
{
$upcontext['upgrade_status']['debug'] = true;
$is_debug = true;
}
if (empty($_POST['backup']))
$upcontext['current_step']++;
return true;
}
function BackupDatabase()
{
global $upcontext, $db_prefix, $command_line, $support_js, $file_steps, $smcFunc, $txt;
$upcontext['sub_template'] = isset($_GET['xml']) ? 'backup_xml' : 'backup_database';
$upcontext['page_title'] = $txt['backup_database'];
if (!empty($_POST['backup_done']))
return true;
db_extend();
db_extend('packages');
$filter = str_replace('_', '\_', preg_match('~^`(.+?)`\.(.+?)$~', $db_prefix, $match) != 0 ? $match[2] : $db_prefix) . '%';
$db = preg_match('~^`(.+?)`\.(.+?)$~', $db_prefix, $match) != 0 ? strtr($match[1], array('`' => '')) : false;
$tables = $smcFunc['db_list_tables']($db, $filter);
$table_names = array();
foreach ($tables as $table)
if (substr($table, 0, 7) !== 'backup_')
$table_names[] = $table;
$upcontext['table_count'] = count($table_names);
$upcontext['cur_table_num'] = $_GET['substep'];
$upcontext['cur_table_name'] = str_replace($db_prefix, '', isset($table_names[$_GET['substep']]) ? $table_names[$_GET['substep']] : $table_names[0]);
$upcontext['step_progress'] = (int) (($upcontext['cur_table_num'] / $upcontext['table_count']) * 100);
$file_steps = $upcontext['table_count'];
foreach ($table_names as $id => $table)
if ($id < $_GET['substep'])
$upcontext['previous_tables'][] = $table;
if ($command_line)
echo 'Backing Up Tables.';
if (!$support_js || isset($_GET['xml']))
{
for ($substep = $_GET['substep'], $n = count($table_names); $substep < $n; $substep++)
{
$upcontext['cur_table_name'] = str_replace($db_prefix, '', (isset($table_names[$substep + 1]) ? $table_names[$substep + 1] : $table_names[$substep]));
$upcontext['cur_table_num'] = $substep + 1;
$upcontext['step_progress'] = (int) (($upcontext['cur_table_num'] / $upcontext['table_count']) * 100);
nextSubstep($substep);
backupTable($table_names[$substep]);
if (isset($_GET['xml']))
return upgradeExit();
}
if ($command_line)
{
echo "\n" . ' Successful.\'' . "\n";
flush();
}
$upcontext['step_progress'] = 100;
$_GET['substep'] = 0;
return true;
}
$_GET['substep'] = 0;
return false;
}
function backupTable($table)
{
global $command_line, $db_prefix, $smcFunc;
if ($command_line)
{
echo "\n" . ' +++ Backing up \"' . str_replace($db_prefix, '', $table) . '"...';
flush();
}
$smcFunc['db_backup_table']($table, 'backup_' . $table);
if ($command_line)
echo ' done.';
}
function DatabaseChanges()
{
global $db_prefix, $modSettings, $smcFunc, $txt;
global $upcontext, $support_js, $db_type;
if (!empty($_POST['database_done']))
return true;
$upcontext['sub_template'] = isset($_GET['xml']) ? 'database_xml' : 'database_changes';
$upcontext['page_title'] = $txt['database_changes'];
$files = array(
array('upgrade_1-0.sql', '1.1', '1.1 RC0', false),
array('upgrade_1-1.sql', '2.0', '2.0 a', false),
array('upgrade_2-0_' . $db_type . '.sql', '2.1', '2.1 dev0', false),
array('upgrade_2-1_' . $db_type . '.sql', '3.0', SMF_VERSION, true),
);
if (isset($_GET['filecount']))
$upcontext['file_count'] = (int) $_GET['filecount'];
else
{
$upcontext['file_count'] = 0;
foreach ($files as $file)
{
if (!isset($modSettings['smfVersion']) || $modSettings['smfVersion'] < $file[1])
$upcontext['file_count']++;
}
}
$did_not_do = count($files) - $upcontext['file_count'];
$upcontext['step_progress'] = 0;
$upcontext['cur_file_num'] = 0;
foreach ($files as $file)
{
if ($did_not_do)
$did_not_do--;
else
{
$upcontext['cur_file_num']++;
$upcontext['cur_file_name'] = $file[0];
if (!isset($modSettings['smfVersion']) || $modSettings['smfVersion'] < $file[1])
{
setSqlMode($file[3]);
$nextFile = parse_sql(dirname(__FILE__) . '/' . $file[0]);
if ($nextFile)
{
$smcFunc['db_insert']('replace',
$db_prefix . 'settings',
array('variable' => 'string', 'value' => 'string'),
array('smfVersion', $file[2]),
array('variable')
);
$modSettings['smfVersion'] = $file[2];
}
if (isset($_GET['xml']))
{
$upcontext['completed_step'] = true;
if ($nextFile)
$upcontext['current_debug_item_num'] = -1;
return upgradeExit();
}
elseif ($support_js)
break;
}
$upcontext['step_progress'] = ($upcontext['cur_file_num'] / $upcontext['file_count']) * 100;
}
}
$_GET['substep'] = 0;
if (!$support_js)
{
$upcontext['changes_complete'] = true;
return true;
}
return false;
}
function setSqlMode($strict = true)
{
global $db_type, $db_connection;
if ($db_type != 'mysql')
return;
if ($strict)
$mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
else
$mode = '';
mysqli_query($db_connection, 'SET SESSION sql_mode = \'' . $mode . '\'');
return;
}
function DeleteUpgrade()
{
global $command_line, $language, $upcontext, $sourcedir;
global $user_info, $maintenance, $smcFunc, $db_type, $txt, $settings;
if (!isset($_GET['ssi']) && !$command_line)
redirectLocation('&ssi=1');
$upcontext['sub_template'] = 'upgrade_complete';
$upcontext['page_title'] = $txt['upgrade_complete'];
$endl = $command_line ? "\n" : '<br>' . "\n";
$changes = array(
'language' => (substr($language, -4) == '.lng' ? substr($language, 0, -4) : $language),
'db_error_send' => true,
'upgradeData' => null,
);
if (isset($upcontext['user']['main']))
{
if ($command_line)
echo ' * ';
$upcontext['removed_maintenance'] = true;
$changes['maintenance'] = $upcontext['user']['main'];
}
elseif (!empty($maintenance) && $maintenance == 2)
$changes['maintenance'] = 1;
$upcontext['user'] = array();
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile($changes);
upgrade_clean_cache();
$upcontext['can_delete_script'] = is_writable(dirname(__FILE__)) || is_writable(__FILE__);
if ($command_line)
cli_scheduled_fetchSMfiles();
else
{
require_once($sourcedir . '/ScheduledTasks.php');
scheduled_fetchSMfiles();
if (httpsOn())
$settings['default_theme_url'] = strtr($settings['default_theme_url'], array('http://' => 'https://'));
}
if (empty($user_info['id']))
$user_info['id'] = !empty($upcontext['user']['id']) ? $upcontext['user']['id'] : 0;
$smcFunc['db_insert']('',
'{db_prefix}log_actions',
array(
'log_time' => 'int', 'id_log' => 'int', 'id_member' => 'int', 'ip' => 'inet', 'action' => 'string',
'id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534',
),
array(
time(), 3, $user_info['id'], $command_line ? '127.0.0.1' : $user_info['ip'], 'upgrade',
0, 0, 0, json_encode(array('version' => SMF_FULL_VERSION, 'member' => $user_info['id'])),
),
array('id_action')
);
$user_info['id'] = 0;
if ($command_line)
{
echo $endl;
echo 'Upgrade Complete!', $endl;
echo 'Please delete this file as soon as possible for security reasons.', $endl;
exit;
}
$upcontext['overall_percent'] = 100;
if (isset($upcontext['step_progress']))
unset($upcontext['step_progress']);
$_GET['substep'] = 0;
return false;
}
function cli_scheduled_fetchSMfiles()
{
global $sourcedir, $language, $modSettings, $smcFunc;
if (empty($modSettings['time_format']))
$modSettings['time_format'] = '%B %d, %Y, %I:%M:%S %p';
$request = $smcFunc['db_query']('', '
SELECT id_file, filename, path, parameters
FROM {db_prefix}admin_info_files',
array(
)
);
$js_files = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
$js_files[$row['id_file']] = array(
'filename' => $row['filename'],
'path' => $row['path'],
'parameters' => sprintf($row['parameters'], $language, urlencode($modSettings['time_format']), urlencode(SMF_FULL_VERSION)),
);
}
$smcFunc['db_free_result']($request);
require_once($sourcedir . '/Subs.php');
foreach ($js_files as $ID_FILE => $file)
{
$server = empty($file['path']) || substr($file['path'], 0, 7) != 'http://' ? 'https://www.simplemachines.org' : '';
$url = $server . (!empty($file['path']) ? $file['path'] : $file['path']) . $file['filename'] . (!empty($file['parameters']) ? '?' . $file['parameters'] : '');
$file_data = fetch_web_data($url);
if ($file_data === false)
return throw_error(sprintf('Could not retrieve the file %1$s.', $url));
$smcFunc['db_query']('substring', '
UPDATE {db_prefix}admin_info_files
SET data = SUBSTRING({string:file_data}, 1, 65534)
WHERE id_file = {int:id_file}',
array(
'id_file' => $ID_FILE,
'file_data' => $file_data,
)
);
}
return true;
}
function convertSettingsToTheme()
{
global $db_prefix, $modSettings, $smcFunc;
$values = array(
'show_latest_member' => @$GLOBALS['showlatestmember'],
'show_bbc' => isset($GLOBALS['showyabbcbutt']) ? $GLOBALS['showyabbcbutt'] : @$GLOBALS['showbbcbutt'],
'show_modify' => @$GLOBALS['showmodify'],
'show_user_images' => @$GLOBALS['showuserpic'],
'show_blurb' => @$GLOBALS['showusertext'],
'show_gender' => @$GLOBALS['showgenderimage'],
'show_newsfader' => @$GLOBALS['shownewsfader'],
'display_recent_bar' => @$GLOBALS['Show_RecentBar'],
'show_member_bar' => @$GLOBALS['Show_MemberBar'],
'linktree_link' => @$GLOBALS['curposlinks'],
'show_profile_buttons' => @$GLOBALS['profilebutton'],
'show_mark_read' => @$GLOBALS['showmarkread'],
'newsfader_time' => @$GLOBALS['fadertime'],
'use_image_buttons' => empty($GLOBALS['MenuType']) ? 1 : 0,
'enable_news' => @$GLOBALS['enable_news'],
'return_to_post' => @$modSettings['returnToPost'],
);
$themeData = array();
foreach ($values as $variable => $value)
{
if (!isset($value) || $value === null)
$value = 0;
$themeData[] = array(0, 1, $variable, $value);
}
if (!empty($themeData))
{
$smcFunc['db_insert']('ignore',
$db_prefix . 'themes',
array('id_member' => 'int', 'id_theme' => 'int', 'variable' => 'string', 'value' => 'string'),
$themeData,
array('id_member', 'id_theme', 'variable')
);
}
}
function convertSettingstoOptions()
{
global $modSettings, $smcFunc;
$values = array(
'calendar_start_day' => 'cal_startmonday',
'view_newest_first' => 'viewNewestFirst',
'view_newest_pm_first' => 'viewNewestFirst',
);
foreach ($values as $variable => $value)
{
if (empty($modSettings[$value[0]]))
continue;
$smcFunc['db_query']('', '
INSERT IGNORE INTO {db_prefix}themes
(id_member, id_theme, variable, value)
SELECT id_member, 1, {string:variable}, {string:value}
FROM {db_prefix}members',
array(
'variable' => $variable,
'value' => $modSettings[$value[0]],
'db_error_skip' => true,
)
);
$smcFunc['db_query']('', '
INSERT IGNORE INTO {db_prefix}themes
(id_member, id_theme, variable, value)
VALUES (-1, 1, {string:variable}, {string:value})',
array(
'variable' => $variable,
'value' => $modSettings[$value[0]],
'db_error_skip' => true,
)
);
}
}
function php_version_check()
{
return version_compare(PHP_VERSION, $GLOBALS['required_php_version'], '>=');
}
function db_version_check()
{
global $db_type, $databases;
$curver = eval($databases[$db_type]['version_check']);
$curver = preg_replace('~\-.+?$~', '', $curver);
return version_compare($databases[$db_type]['version'], $curver, '<=');
}
function fixRelativePath($path)
{
global $install_path;
return addslashes(preg_replace(array('~^\.([/\\\]|$)~', '~[/]+~', '~[\\\]+~', '~[/\\\]$~'), array($install_path . '$1', '/', '\\', ''), $path));
}
function parse_sql($filename)
{
global $db_prefix, $db_collation, $boarddir, $boardurl, $command_line, $file_steps, $step_progress, $custom_warning;
global $upcontext, $support_js, $is_debug, $db_type, $db_character_set;
db_extend();
db_extend('packages');
set_error_handler(
function($errno, $errstr, $errfile, $errline) use ($support_js)
{
if ($support_js)
return true;
else
echo 'Error: ' . $errstr . ' File: ' . $errfile . ' Line: ' . $errline;
}
);
if ($db_type == 'mysql')
$db_collation = ' DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci';
else
$db_collation = '';
$endl = $command_line ? "\n" : '<br>' . "\n";
$lines = file($filename);
$current_type = 'sql';
$current_data = '';
$substep = 0;
$last_step = '';
if (isset($db_character_set) && $db_character_set === 'utf8')
$lines = str_replace(') ENGINE=MyISAM;', ') ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;', $lines);
$file_steps = substr_count(implode('', $lines), '---#');
$upcontext['total_items'] = substr_count(implode('', $lines), '--- ');
$upcontext['debug_items'] = $file_steps;
$upcontext['current_item_num'] = 0;
$upcontext['current_item_name'] = '';
$upcontext['current_debug_item_num'] = 0;
$upcontext['current_debug_item_name'] = '';
$upcontext['actioned_items'] = array();
$done_something = false;
foreach ($lines as $line_number => $line)
{
$do_current = $substep >= $_GET['substep'];
if (substr(trim($line), 0, 2) === '/*')
$line = preg_replace('~/\*.+?\*/~', '', $line);
if ($is_debug && !$support_js && $command_line)
flush();
if (trim($line) === '')
continue;
if (trim(substr($line, 0, 3)) === '---')
{
$type = substr($line, 3, 1);
if (trim($current_data) != '' && $type !== '}')
{
$upcontext['error_message'] = 'Error in upgrade script - line ' . $line_number . '!' . $endl;
if ($command_line)
echo $upcontext['error_message'];
}
if ($type == ' ')
{
if (!$support_js && $do_current && $_GET['substep'] != 0 && $command_line)
{
echo ' Successful.', $endl;
flush();
}
$last_step = htmlspecialchars(rtrim(substr($line, 4)));
$upcontext['current_item_num']++;
$upcontext['current_item_name'] = $last_step;
if ($do_current)
{
$upcontext['actioned_items'][] = $last_step;
if ($command_line)
echo ' * ';
$upcontext['skip_db_substeps'] = false;
}
}
elseif ($type == '#')
{
$upcontext['step_progress'] += (100 / $upcontext['file_count']) / $file_steps;
$upcontext['current_debug_item_num']++;
if (trim($line) != '---#')
$upcontext['current_debug_item_name'] = htmlspecialchars(rtrim(substr($line, 4)));
if (isset($_GET['xml']) && $done_something)
{
restore_error_handler();
return $upcontext['current_debug_item_num'] >= $upcontext['debug_items'] ? true : false;
}
if ($do_current)
{
if (trim($line) == '---#' && $command_line)
echo ' done.', $endl;
elseif ($command_line)
echo ' +++ ', rtrim(substr($line, 4));
elseif (trim($line) != '---#')
{
if ($is_debug)
$upcontext['actioned_items'][] = $upcontext['current_debug_item_name'];
}
}
if ($substep < $_GET['substep'] && $substep + 1 >= $_GET['substep'])
{
if ($command_line)
echo ' * ';
else
$upcontext['actioned_items'][] = $last_step;
}
if ($do_current)
nextSubstep(++$substep);
else
$substep++;
}
elseif ($type == '{')
$current_type = 'code';
elseif ($type == '}')
{
$current_type = 'sql';
if (!$do_current || !empty($upcontext['skip_db_substeps']))
{
$current_data = '';
if ($do_current)
$done_something = true;
continue;
}
if (eval('global $db_prefix, $modSettings, $smcFunc, $txt, $upcontext, $db_name; ' . $current_data) === false)
{
$upcontext['error_message'] = 'Error in upgrade script ' . basename($filename) . ' on line ' . $line_number . '!' . $endl;
if ($command_line)
echo $upcontext['error_message'];
}
$current_data = '';
$done_something = true;
}
continue;
}
$current_data .= $line;
if (substr(rtrim($current_data), -1) === ';' && $current_type === 'sql')
{
if ((!$support_js || isset($_GET['xml'])))
{
if (!$do_current || !empty($upcontext['skip_db_substeps']))
{
$current_data = '';
if ($do_current)
$done_something = true;
continue;
}
$current_data = strtr(substr(rtrim($current_data), 0, -1), array('{$db_prefix}' => $db_prefix, '{$boarddir}' => $boarddir, '{$sboarddir}' => addslashes($boarddir), '{$boardurl}' => $boardurl, '{$db_collation}' => $db_collation));
upgrade_query($current_data);
$done_something = true;
}
$current_data = '';
}
elseif ($support_js && !isset($_GET['xml']) && $upcontext['current_debug_item_name'] != '' && $do_current)
{
restore_error_handler();
return false;
}
$step_progress = array();
$custom_warning = '';
}
restore_error_handler();
if ($command_line)
{
echo ' Successful.' . "\n";
flush();
}
$_GET['substep'] = 0;
return true;
}
function upgrade_query($string, $unbuffered = false)
{
global $db_connection, $db_server, $db_user, $db_passwd, $db_type;
global $command_line, $upcontext, $upgradeurl, $modSettings;
global $db_name, $db_unbuffered, $smcFunc, $txt;
$modSettings['disableQueryCheck'] = true;
$db_unbuffered = $unbuffered;
$ignore_insert_error = false;
if ($db_type == 'postgresql' && !$smcFunc['db_native_replace']() && strpos($string, 'ON CONFLICT DO NOTHING') !== false)
{
$ignore_insert_error = true;
$string = str_replace('ON CONFLICT DO NOTHING', '', $string);
}
$result = $smcFunc['db_query']('', $string, array('security_override' => true, 'db_error_skip' => true));
$db_unbuffered = false;
if ($result !== false)
return $result;
$db_error_message = $smcFunc['db_error']($db_connection);
if ($db_type == 'mysql')
{
$mysqli_errno = mysqli_errno($db_connection);
$error_query = in_array(substr(trim($string), 0, 11), array('INSERT INTO', 'UPDATE IGNO', 'ALTER TABLE', 'DROP TABLE ', 'ALTER IGNOR', 'INSERT IGNO'));
if ($mysqli_errno == 1016)
{
if (preg_match('~\'([^\.\']+)~', $db_error_message, $match) != 0 && !empty($match[1]))
{
mysqli_query($db_connection, 'REPAIR TABLE `' . $match[1] . '`');
$result = mysqli_query($db_connection, $string);
if ($result !== false)
return $result;
}
}
elseif ($mysqli_errno == 2013)
{
$db_connection = mysqli_connect($db_server, $db_user, $db_passwd);
mysqli_select_db($db_connection, $db_name);
if ($db_connection)
{
$result = mysqli_query($db_connection, $string);
if ($result !== false)
return $result;
}
}
elseif (in_array($mysqli_errno, array(1060, 1061, 1068, 1091)))
return false;
elseif (in_array($mysqli_errno, array(1054, 1062, 1146)) && $error_query)
return false;
elseif ($mysqli_errno == 1072)
return false;
elseif ($mysqli_errno == 1050 && substr(trim($string), 0, 12) == 'RENAME TABLE')
return false;
elseif (in_array($mysqli_errno, array(1054, 1146)) && in_array(substr(trim($string), 0, 7), array('SELECT ', 'SHOW CO')))
return false;
}
else
{
if (in_array(substr(trim($string), 0, 8), array('CREATE T', 'CREATE S', 'DROP TABL', 'ALTER TA', 'CREATE I', 'CREATE U')))
{
if (strpos($db_error_message, 'exist') !== false)
return true;
}
elseif (strpos(trim($string), 'INSERT ') !== false)
{
if (strpos($db_error_message, 'duplicate') !== false || $ignore_insert_error)
return true;
}
}
$query_string = '';
foreach ($_GET as $k => $v)
$query_string .= ';' . $k . '=' . $v;
if (strlen($query_string) != 0)
$query_string = '?' . substr($query_string, 1);
if ($command_line)
{
echo 'Unsuccessful! Database error message:', "\n", $db_error_message, "\n";
die;
}
if (!empty($upcontext['return_error']))
{
$upcontext['error_message'] = $db_error_message;
$upcontext['error_string'] = $string;
return false;
}
$upcontext['forced_error_message'] = '
<strong>' . $txt['upgrade_unsuccessful'] . '</strong><br>
<div style="margin: 2ex;">
' . $txt['upgrade_thisquery'] . '
<blockquote><pre>' . nl2br(htmlspecialchars(trim($string))) . ';</pre></blockquote>
' . $txt['upgrade_causerror'] . '
<blockquote>' . nl2br(htmlspecialchars($db_error_message)) . '</blockquote>
</div>
<form action="' . $upgradeurl . $query_string . '" method="post">
<input type="submit" value="' . $txt['upgrade_respondtime_clickhere'] . '" class="button">
</form>
</div>';
upgradeExit();
}
function protected_alter($change, $substep, $is_test = false)
{
global $db_prefix, $smcFunc;
db_extend('packages');
$found = false;
if ($change['type'] === 'column')
{
$columns = $smcFunc['db_list_columns']('{db_prefix}' . $change['table'], true);
foreach ($columns as $column)
{
if ($column['name'] === $change['name'])
{
$found |= true;
if (isset($change['col_type']))
$found &= $change['col_type'] === $column['type'];
if (isset($change['null_allowed']))
$found &= $column['null'] == $change['null_allowed'];
if (isset($change['default']))
$found &= $change['default'] === $column['default'];
}
}
}
elseif ($change['type'] === 'index')
{
$request = upgrade_query('
SHOW INDEX
FROM ' . $db_prefix . $change['table']);
if ($request !== false)
{
$cur_index = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
if ($row['Key_name'] === $change['name'])
$cur_index[(int) $row['Seq_in_index']] = $row['Column_name'];
ksort($cur_index, SORT_NUMERIC);
$found = array_values($cur_index) === $change['target_columns'];
$smcFunc['db_free_result']($request);
}
}
if ($found && in_array($change['method'], array('add', 'change')))
return true;
elseif (!$found && in_array($change['method'], array('remove', 'change_remove')))
return true;
elseif ($is_test)
return false;
$running = false;
$found = false;
while (1 == 1)
{
$request = upgrade_query('
SHOW FULL PROCESSLIST');
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (strpos($row['Info'], 'ALTER TABLE ' . $db_prefix . $change['table']) !== false && strpos($row['Info'], $change['text']) !== false)
$found = true;
}
if (!$found && !$running)
{
$smcFunc['db_free_result']($request);
$success = upgrade_query('
ALTER TABLE ' . $db_prefix . $change['table'] . '
' . $change['text'], true) !== false;
if (!$success)
return false;
$running = true;
}
elseif (!$found)
{
$smcFunc['db_free_result']($request);
return true;
}
sleep(3);
nextSubstep($substep);
}
nextSubstep($substep);
}
function textfield_alter($change, $substep)
{
global $db_prefix, $smcFunc;
$request = $smcFunc['db_query']('', '
SHOW FULL COLUMNS
FROM {db_prefix}' . $change['table'] . '
LIKE {string:column}',
array(
'column' => $change['column'],
'db_error_skip' => true,
)
);
if ($smcFunc['db_num_rows']($request) === 0)
die('Unable to find column ' . $change['column'] . ' inside table ' . $db_prefix . $change['table']);
$table_row = $smcFunc['db_fetch_assoc']($request);
$smcFunc['db_free_result']($request);
$column_fix = $table_row['Type'] !== $change['type'] || (strtolower($table_row['Null']) === 'yes') !== $change['null_allowed'] || ($table_row['Default'] === null) !== !isset($change['default']) || (isset($change['default']) && $change['default'] !== $table_row['Default']);
$null_fix = strtolower($table_row['Null']) === 'yes' && !$change['null_allowed'];
if ($column_fix && !empty($table_row['Collation']))
{
$request = $smcFunc['db_query']('', '
SHOW COLLATION
LIKE {string:collation}',
array(
'collation' => $table_row['Collation'],
'db_error_skip' => true,
)
);
if ($smcFunc['db_num_rows']($request) === 0)
unset($table_row['Collation']);
else
$collation_info = $smcFunc['db_fetch_assoc']($request);
$smcFunc['db_free_result']($request);
}
if ($column_fix)
{
if ($null_fix)
$smcFunc['db_query']('', '
UPDATE {db_prefix}' . $change['table'] . '
SET ' . $change['column'] . ' = {string:default}
WHERE ' . $change['column'] . ' IS NULL',
array(
'default' => isset($change['default']) ? $change['default'] : '',
'db_error_skip' => true,
)
);
$smcFunc['db_query']('', '
ALTER TABLE {db_prefix}' . $change['table'] . '
CHANGE COLUMN ' . $change['column'] . ' ' . $change['column'] . ' ' . $change['type'] . (isset($collation_info['Charset']) ? ' CHARACTER SET ' . $collation_info['Charset'] . ' COLLATE ' . $collation_info['Collation'] : '') . ($change['null_allowed'] ? '' : ' NOT NULL') . (isset($change['default']) ? ' default {string:default}' : ''),
array(
'default' => isset($change['default']) ? $change['default'] : '',
'db_error_skip' => true,
)
);
}
nextSubstep($substep);
}
function checkChange(&$change)
{
global $smcFunc, $db_type, $databases;
static $database_version, $where_field_support;
if (empty($database_version))
{
$database_version = $databases[$db_type]['version_check'];
$where_field_support = $db_type == 'mysql' && version_compare('5.0', $database_version, '<=');
}
if (!in_array($change['name'], array('memberGroups', 'passwordSalt')))
return;
$temp = explode(' ', str_replace('NOT NULL', 'NOT_NULL', $change['text']));
if ($where_field_support)
{
$request = $smcFunc['db_query']('', '
SHOW FIELDS
FROM {db_prefix}{raw:table}
WHERE Field = {string:old_name} OR Field = {string:new_name}',
array(
'table' => $change['table'],
'old_name' => $temp[1],
'new_name' => $temp[2],
)
);
if ($smcFunc['db_num_rows'] != 1)
return;
list (, $current_type) = $smcFunc['db_fetch_assoc']($request);
$smcFunc['db_free_result']($request);
}
else
{
$request = $smcFunc['db_query']('', '
SHOW FIELDS
FROM {db_prefix}{raw:table}',
array(
'table' => $change['table'],
)
);
if ($smcFunc['db_num_rows'] == 0)
return;
while ($row = $smcFunc['db_query']($request))
if ($row['Field'] == $temp[1] || $row['Field'] == $temp[2])
{
$current_type = $row['Type'];
break;
}
}
if (trim($current_type) != trim($temp[3]))
$temp[3] = $current_type;
$change['text'] = str_replace('NOT_NULL', 'NOT NULL', implode(' ', $temp));
}
function nextSubstep($substep)
{
global $start_time, $timeLimitThreshold, $command_line, $custom_warning;
global $step_progress, $is_debug, $upcontext;
if ($_GET['substep'] < $substep)
$_GET['substep'] = $substep;
if ($command_line)
{
if (time() - $start_time > 1 && empty($is_debug))
{
echo '.';
$start_time = time();
}
return;
}
@set_time_limit(300);
if (function_exists('apache_reset_timeout'))
@apache_reset_timeout();
if (time() - $start_time <= $timeLimitThreshold)
return;
if (!empty($step_progress))
{
$upcontext['substep_progress'] = 0;
$upcontext['substep_progress_name'] = $step_progress['name'];
if ($step_progress['current'] > $step_progress['total'])
$upcontext['substep_progress'] = 99.9;
else
$upcontext['substep_progress'] = ($step_progress['current'] / $step_progress['total']) * 100;
$upcontext['substep_progress'] = round($upcontext['substep_progress'], 1);
}
if (isset($_GET['xml']))
return upgradeExit();
$upcontext['pause'] = true;
$upcontext['query_string'] = '';
foreach ($_GET as $k => $v)
{
if ($k != 'data' && $k != 'substep' && $k != 'step')
$upcontext['query_string'] .= ';' . $k . '=' . $v;
}
if (!empty($custom_warning))
$upcontext['custom_warning'] = $custom_warning;
upgradeExit();
}
function cmdStep0()
{
global $boarddir, $sourcedir, $modSettings, $start_time, $cachedir, $databases, $db_type, $smcFunc, $upcontext;
global $is_debug;
$start_time = time();
ob_end_clean();
ob_implicit_flush(1);
@set_time_limit(600);
if (!isset($_SERVER['argv']))
$_SERVER['argv'] = array();
$_GET['maint'] = 1;
foreach ($_SERVER['argv'] as $i => $arg)
{
if (preg_match('~^--language=(.+)$~', $arg, $match) != 0)
$upcontext['lang'] = $match[1];
elseif (preg_match('~^--path=(.+)$~', $arg) != 0)
continue;
elseif ($arg == '--no-maintenance')
$_GET['maint'] = 0;
elseif ($arg == '--debug')
$is_debug = true;
elseif ($arg == '--backup')
$_POST['backup'] = 1;
elseif ($arg == '--template' && (file_exists($boarddir . '/template.php') || file_exists($boarddir . '/template.html') && !file_exists($modSettings['theme_dir'] . '/converted')))
$_GET['conv'] = 1;
elseif ($i != 0)
{
echo 'SMF Command-line Upgrader
Usage: /path/to/php -f ' . basename(__FILE__) . ' -- [OPTION]...
--language=LANG Reset the forum\'s language to LANG.
--no-maintenance Don\'t put the forum into maintenance mode.
--debug Output debugging information.
--backup Create backups of tables with "backup_" prefix.';
echo "\n";
exit;
}
}
if (!php_version_check())
print_error('Error: PHP ' . PHP_VERSION . ' does not match version requirements.', true);
if (!db_version_check())
print_error('Error: ' . $databases[$db_type]['name'] . ' ' . $databases[$db_type]['version'] . ' does not match minimum requirements.', true);
db_extend('packages');
$create = $smcFunc['db_create_table']('{db_prefix}priv_check', array(array('name' => 'id_test', 'type' => 'int', 'size' => 10, 'unsigned' => true, 'auto' => true)), array(array('columns' => array('id_test'), 'primary' => true)), array(), 'overwrite');
$alter = $smcFunc['db_add_column']('{db_prefix}priv_check', array('name' => 'txt', 'type' => 'varchar', 'size' => 4, 'null' => false, 'default' => ''));
$drop = $smcFunc['db_drop_table']('{db_prefix}priv_check');
if (!$create || !$alter || !$drop)
print_error("The " . $databases[$db_type]['name'] . " user you have set in Settings.php does not have proper privileges.\n\nPlease ask your host to give this user the ALTER, CREATE, and DROP privileges.", true);
$check = @file_exists($modSettings['theme_dir'] . '/index.template.php')
&& @file_exists($sourcedir . '/QueryString.php')
&& @file_exists($sourcedir . '/ManageBoards.php');
if (!$check && !isset($modSettings['smfVersion']))
print_error('Error: Some files are missing or out-of-date.', true);
$temp = substr(@implode('', @file($boarddir . '/index.php')), 0, 4096);
preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $temp, $match);
if (empty($match[1]) || (trim($match[1]) != SMF_VERSION))
print_error('Error: Some files have not yet been updated properly.');
quickFileWritable($boarddir . '/Settings.php');
if (!is_writable($boarddir . '/Settings.php'))
print_error('Error: Unable to obtain write access to "Settings.php".', true);
quickFileWritable($boarddir . '/Settings_bak.php');
if (!is_writable($boarddir . '/Settings_bak.php'))
print_error('Error: Unable to obtain write access to "Settings_bak.php".');
if (isset($modSettings['agreement']) && (!is_writable($boarddir) || file_exists($boarddir . '/agreement.txt')) && !is_writable($boarddir . '/agreement.txt'))
print_error('Error: Unable to obtain write access to "agreement.txt".');
elseif (isset($modSettings['agreement']))
{
$fp = fopen($boarddir . '/agreement.txt', 'w');
fwrite($fp, $modSettings['agreement']);
fclose($fp);
}
quickFileWritable($modSettings['theme_dir']);
if (!is_writable($modSettings['theme_dir']) && !isset($modSettings['smfVersion']))
print_error('Error: Unable to obtain write access to "Themes".');
$cachedir_temp = empty($cachedir) ? $boarddir . '/cache' : $cachedir;
if (!file_exists($cachedir_temp))
@mkdir($cachedir_temp);
quickFileWritable($cachedir_temp);
if (!is_writable($cachedir_temp))
print_error('Error: Unable to obtain write access to "cache".', true);
quickFileWritable($cachedir_temp . '/db_last_error.php');
if (!is_writable($cachedir_temp . '/db_last_error.php'))
print_error('Error: Unable to obtain write access to "db_last_error.php".');
if (!file_exists($modSettings['theme_dir'] . '/languages/index.' . $upcontext['language'] . '.php'))
print_error('Error: Unable to find language files!', true);
else
{
$temp = substr(@implode('', @file($modSettings['theme_dir'] . '/languages/index.' . $upcontext['language'] . '.php')), 0, 4096);
preg_match('~(?://|/\*)\s*Version:\s+(.+?);\s*index(?:[\s]{2}|\*/)~i', $temp, $match);
if (empty($match[1]) || $match[1] != SMF_LANG_VERSION)
print_error('Error: Language files out of date.', true);
if (!file_exists($modSettings['theme_dir'] . '/languages/Install.' . $upcontext['language'] . '.php'))
print_error('Error: Install language is missing for selected language.', true);
require_once($modSettings['theme_dir'] . '/languages/Install.' . $upcontext['language'] . '.php');
}
$_POST['upcont'] = true;
$upcontext['current_step'] = 1;
}
function ConvertUtf8()
{
global $upcontext, $db_character_set, $sourcedir, $smcFunc, $modSettings, $language;
global $db_prefix, $db_type, $command_line, $support_js, $txt;
if (!empty($_POST['utf8_done']))
return true;
if ($db_type == 'postgresql' || ($db_character_set === 'utf8' && !empty($modSettings['global_character_set']) && $modSettings['global_character_set'] === 'UTF-8'))
{
$smcFunc['db_insert']('replace',
'{db_prefix}settings',
array('variable' => 'string', 'value' => 'string'),
array(array('global_character_set', 'UTF-8')),
array('variable')
);
return true;
}
else
{
$upcontext['page_title'] = $txt['converting_utf8'];
$upcontext['sub_template'] = isset($_GET['xml']) ? 'convert_xml' : 'convert_utf8';
$charsets = array(
'armscii8' => 'armscii8',
'big5' => 'big5',
'gbk' => 'gbk',
'ISO-8859-1' => 'latin1',
'ISO-8859-2' => 'latin2',
'ISO-8859-9' => 'latin5',
'ISO-8859-13' => 'latin7',
'ISO-8859-15' => 'latin9',
'tis-620' => 'tis620',
'UTF-8' => 'utf8',
'windows-1251' => 'cp1251',
'windows-1253' => 'utf8',
'windows-1255' => 'utf8',
'windows-1256' => 'cp1256',
);
$request = $smcFunc['db_query']('', '
SHOW CHARACTER SET',
array(
)
);
$db_charsets = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$db_charsets[] = $row['Charset'];
$smcFunc['db_free_result']($request);
$charsets = array_intersect($charsets, $db_charsets);
$request = $smcFunc['db_query']('', '
SHOW FULL COLUMNS
FROM {db_prefix}messages
LIKE {string:body_like}',
array(
'body_like' => 'body',
)
);
$column_info = $smcFunc['db_fetch_assoc']($request);
$smcFunc['db_free_result']($request);
list($upcontext['database_charset']) = explode('_', $column_info['Collation']);
$upcontext['database_charset'] = in_array($upcontext['database_charset'], $charsets) ? array_search($upcontext['database_charset'], $charsets) : $upcontext['database_charset'];
$request = $smcFunc['db_query']('', '
SHOW INDEX
FROM {db_prefix}messages',
array(
)
);
$upcontext['dropping_index'] = false;
if ($request !== false || $smcFunc['db_num_rows']($request) != 0)
{
while ($row = $smcFunc['db_fetch_assoc']($request))
if ($row['Column_name'] == 'body' && (isset($row['Index_type']) && $row['Index_type'] == 'FULLTEXT' || isset($row['Comment']) && $row['Comment'] == 'FULLTEXT'))
$upcontext['fulltext_index'][] = $row['Key_name'];
$smcFunc['db_free_result']($request);
if (isset($upcontext['fulltext_index']))
$upcontext['fulltext_index'] = array_unique($upcontext['fulltext_index']);
}
if (!empty($upcontext['fulltext_index']))
{
$upcontext['dropping_index'] = true;
$smcFunc['db_query']('', '
ALTER TABLE {db_prefix}messages
DROP INDEX ' . implode(',
DROP INDEX ', $upcontext['fulltext_index']),
array(
'db_error_skip' => true,
)
);
$smcFunc['db_insert']('replace',
'{db_prefix}settings',
array('variable' => 'string', 'value' => 'string'),
array('db_search_index', ''),
array('variable')
);
}
$lang_charsets = array(
'arabic' => 'windows-1256',
'armenian_east' => 'armscii-8',
'armenian_west' => 'armscii-8',
'azerbaijani_latin' => 'ISO-8859-9',
'bangla' => 'UTF-8',
'belarusian' => 'ISO-8859-5',
'bulgarian' => 'windows-1251',
'cambodian' => 'UTF-8',
'chinese_simplified' => 'gbk',
'chinese_traditional' => 'big5',
'croation' => 'ISO-8859-2',
'czech' => 'ISO-8859-2',
'czech_informal' => 'ISO-8859-2',
'english_pirate' => 'UTF-8',
'esperanto' => 'ISO-8859-3',
'estonian' => 'ISO-8859-15',
'filipino_tagalog' => 'UTF-8',
'filipino_vasayan' => 'UTF-8',
'georgian' => 'UTF-8',
'greek' => 'ISO-8859-3',
'hebrew' => 'windows-1255',
'hungarian' => 'ISO-8859-2',
'irish' => 'UTF-8',
'japanese' => 'UTF-8',
'khmer' => 'UTF-8',
'korean' => 'UTF-8',
'kurdish_kurmanji' => 'ISO-8859-9',
'kurdish_sorani' => 'windows-1256',
'lao' => 'tis-620',
'latvian' => 'ISO-8859-13',
'lithuanian' => 'ISO-8859-4',
'macedonian' => 'UTF-8',
'malayalam' => 'UTF-8',
'mongolian' => 'UTF-8',
'nepali' => 'UTF-8',
'persian' => 'UTF-8',
'polish' => 'ISO-8859-2',
'romanian' => 'ISO-8859-2',
'russian' => 'windows-1252',
'sakha' => 'UTF-8',
'serbian_cyrillic' => 'ISO-8859-5',
'serbian_latin' => 'ISO-8859-2',
'sinhala' => 'UTF-8',
'slovak' => 'ISO-8859-2',
'slovenian' => 'ISO-8859-2',
'telugu' => 'UTF-8',
'thai' => 'tis-620',
'turkish' => 'ISO-8859-9',
'turkmen' => 'ISO-8859-9',
'ukranian' => 'windows-1251',
'urdu' => 'UTF-8',
'uzbek_cyrillic' => 'ISO-8859-5',
'uzbek_latin' => 'ISO-8859-5',
'vietnamese' => 'UTF-8',
'yoruba' => 'UTF-8'
);
$upcontext['charset_detected'] = (isset($lang_charsets[$language]) && isset($charsets[strtr(strtolower($upcontext['charset_detected']), array('utf' => 'UTF', 'iso' => 'ISO'))])) ? $lang_charsets[$language] : 'ISO-8859-1';
$upcontext['charset_list'] = array_keys($charsets);
$translation_tables = array(
'windows-1255' => array(
'0x81' => '\'\'', '0x8A' => '\'\'', '0x8C' => '\'\'',
'0x8D' => '\'\'', '0x8E' => '\'\'', '0x8F' => '\'\'',
'0x90' => '\'\'', '0x9A' => '\'\'', '0x9C' => '\'\'',
'0x9D' => '\'\'', '0x9E' => '\'\'', '0x9F' => '\'\'',
'0xCA' => '\'\'', '0xD9' => '\'\'', '0xDA' => '\'\'',
'0xDB' => '\'\'', '0xDC' => '\'\'', '0xDD' => '\'\'',
'0xDE' => '\'\'', '0xDF' => '\'\'', '0xFB' => '0xD792',
'0xFC' => '0xE282AC', '0xFF' => '0xD6B2', '0xC2' => '0xFF',
'0x80' => '0xFC', '0xE2' => '0xFB', '0xA0' => '0xC2A0',
'0xA1' => '0xC2A1', '0xA2' => '0xC2A2', '0xA3' => '0xC2A3',
'0xA5' => '0xC2A5', '0xA6' => '0xC2A6', '0xA7' => '0xC2A7',
'0xA8' => '0xC2A8', '0xA9' => '0xC2A9', '0xAB' => '0xC2AB',
'0xAC' => '0xC2AC', '0xAD' => '0xC2AD', '0xAE' => '0xC2AE',
'0xAF' => '0xC2AF', '0xB0' => '0xC2B0', '0xB1' => '0xC2B1',
'0xB2' => '0xC2B2', '0xB3' => '0xC2B3', '0xB4' => '0xC2B4',
'0xB5' => '0xC2B5', '0xB6' => '0xC2B6', '0xB7' => '0xC2B7',
'0xB8' => '0xC2B8', '0xB9' => '0xC2B9', '0xBB' => '0xC2BB',
'0xBC' => '0xC2BC', '0xBD' => '0xC2BD', '0xBE' => '0xC2BE',
'0xBF' => '0xC2BF', '0xD7' => '0xD7B3', '0xD1' => '0xD781',
'0xD4' => '0xD7B0', '0xD5' => '0xD7B1', '0xD6' => '0xD7B2',
'0xE0' => '0xD790', '0xEA' => '0xD79A', '0xEC' => '0xD79C',
'0xED' => '0xD79D', '0xEE' => '0xD79E', '0xEF' => '0xD79F',
'0xF0' => '0xD7A0', '0xF1' => '0xD7A1', '0xF2' => '0xD7A2',
'0xF3' => '0xD7A3', '0xF5' => '0xD7A5', '0xF6' => '0xD7A6',
'0xF7' => '0xD7A7', '0xF8' => '0xD7A8', '0xF9' => '0xD7A9',
'0x82' => '0xE2809A', '0x84' => '0xE2809E', '0x85' => '0xE280A6',
'0x86' => '0xE280A0', '0x87' => '0xE280A1', '0x89' => '0xE280B0',
'0x8B' => '0xE280B9', '0x93' => '0xE2809C', '0x94' => '0xE2809D',
'0x95' => '0xE280A2', '0x97' => '0xE28094', '0x99' => '0xE284A2',
'0xC0' => '0xD6B0', '0xC1' => '0xD6B1', '0xC3' => '0xD6B3',
'0xC4' => '0xD6B4', '0xC5' => '0xD6B5', '0xC6' => '0xD6B6',
'0xC7' => '0xD6B7', '0xC8' => '0xD6B8', '0xC9' => '0xD6B9',
'0xCB' => '0xD6BB', '0xCC' => '0xD6BC', '0xCD' => '0xD6BD',
'0xCE' => '0xD6BE', '0xCF' => '0xD6BF', '0xD0' => '0xD780',
'0xD2' => '0xD782', '0xE3' => '0xD793', '0xE4' => '0xD794',
'0xE5' => '0xD795', '0xE7' => '0xD797', '0xE9' => '0xD799',
'0xFD' => '0xE2808E', '0xFE' => '0xE2808F', '0x92' => '0xE28099',
'0x83' => '0xC692', '0xD3' => '0xD783', '0x88' => '0xCB86',
'0x98' => '0xCB9C', '0x91' => '0xE28098', '0x96' => '0xE28093',
'0xBA' => '0xC3B7', '0x9B' => '0xE280BA', '0xAA' => '0xC397',
'0xA4' => '0xE282AA', '0xE1' => '0xD791', '0xE6' => '0xD796',
'0xE8' => '0xD798', '0xEB' => '0xD79B', '0xF4' => '0xD7A4',
'0xFA' => '0xD7AA',
),
'windows-1253' => array(
'0x81' => '\'\'', '0x88' => '\'\'', '0x8A' => '\'\'',
'0x8C' => '\'\'', '0x8D' => '\'\'', '0x8E' => '\'\'',
'0x8F' => '\'\'', '0x90' => '\'\'', '0x98' => '\'\'',
'0x9A' => '\'\'', '0x9C' => '\'\'', '0x9D' => '\'\'',
'0x9E' => '\'\'', '0x9F' => '\'\'', '0xAA' => '\'\'',
'0xD2' => '0xE282AC', '0xFF' => '0xCE92', '0xCE' => '0xCE9E',
'0xB8' => '0xCE88', '0xBA' => '0xCE8A', '0xBC' => '0xCE8C',
'0xBE' => '0xCE8E', '0xBF' => '0xCE8F', '0xC0' => '0xCE90',
'0xC8' => '0xCE98', '0xCA' => '0xCE9A', '0xCC' => '0xCE9C',
'0xCD' => '0xCE9D', '0xCF' => '0xCE9F', '0xDA' => '0xCEAA',
'0xE8' => '0xCEB8', '0xEA' => '0xCEBA', '0xEC' => '0xCEBC',
'0xEE' => '0xCEBE', '0xEF' => '0xCEBF', '0xC2' => '0xFF',
'0xBD' => '0xC2BD', '0xED' => '0xCEBD', '0xB2' => '0xC2B2',
'0xA0' => '0xC2A0', '0xA3' => '0xC2A3', '0xA4' => '0xC2A4',
'0xA5' => '0xC2A5', '0xA6' => '0xC2A6', '0xA7' => '0xC2A7',
'0xA8' => '0xC2A8', '0xA9' => '0xC2A9', '0xAB' => '0xC2AB',
'0xAC' => '0xC2AC', '0xAD' => '0xC2AD', '0xAE' => '0xC2AE',
'0xB0' => '0xC2B0', '0xB1' => '0xC2B1', '0xB3' => '0xC2B3',
'0xB5' => '0xC2B5', '0xB6' => '0xC2B6', '0xB7' => '0xC2B7',
'0xBB' => '0xC2BB', '0xE2' => '0xCEB2', '0x80' => '0xD2',
'0x82' => '0xE2809A', '0x84' => '0xE2809E', '0x85' => '0xE280A6',
'0x86' => '0xE280A0', '0xA1' => '0xCE85', '0xA2' => '0xCE86',
'0x87' => '0xE280A1', '0x89' => '0xE280B0', '0xB9' => '0xCE89',
'0x8B' => '0xE280B9', '0x91' => '0xE28098', '0x99' => '0xE284A2',
'0x92' => '0xE28099', '0x93' => '0xE2809C', '0x94' => '0xE2809D',
'0x95' => '0xE280A2', '0x96' => '0xE28093', '0x97' => '0xE28094',
'0x9B' => '0xE280BA', '0xAF' => '0xE28095', '0xB4' => '0xCE84',
'0xC1' => '0xCE91', '0xC3' => '0xCE93', '0xC4' => '0xCE94',
'0xC5' => '0xCE95', '0xC6' => '0xCE96', '0x83' => '0xC692',
'0xC7' => '0xCE97', '0xC9' => '0xCE99', '0xCB' => '0xCE9B',
'0xD0' => '0xCEA0', '0xD1' => '0xCEA1', '0xD3' => '0xCEA3',
'0xD4' => '0xCEA4', '0xD5' => '0xCEA5', '0xD6' => '0xCEA6',
'0xD7' => '0xCEA7', '0xD8' => '0xCEA8', '0xD9' => '0xCEA9',
'0xDB' => '0xCEAB', '0xDC' => '0xCEAC', '0xDD' => '0xCEAD',
'0xDE' => '0xCEAE', '0xDF' => '0xCEAF', '0xE0' => '0xCEB0',
'0xE1' => '0xCEB1', '0xE3' => '0xCEB3', '0xE4' => '0xCEB4',
'0xE5' => '0xCEB5', '0xE6' => '0xCEB6', '0xE7' => '0xCEB7',
'0xE9' => '0xCEB9', '0xEB' => '0xCEBB', '0xF0' => '0xCF80',
'0xF1' => '0xCF81', '0xF2' => '0xCF82', '0xF3' => '0xCF83',
'0xF4' => '0xCF84', '0xF5' => '0xCF85', '0xF6' => '0xCF86',
'0xF7' => '0xCF87', '0xF8' => '0xCF88', '0xF9' => '0xCF89',
'0xFA' => '0xCF8A', '0xFB' => '0xCF8B', '0xFC' => '0xCF8C',
'0xFD' => '0xCF8D', '0xFE' => '0xCF8E',
),
);
if (isset($translation_tables[$upcontext['charset_detected']]))
{
$replace = '%field%';
foreach ($translation_tables[$upcontext['charset_detected']] as $from => $to)
$replace = 'REPLACE(' . $replace . ', ' . $from . ', ' . $to . ')';
}
db_extend();
$queryTables = $smcFunc['db_list_tables'](false, $db_prefix . '%');
$upcontext['table_count'] = count($queryTables);
foreach ($queryTables as $id => $table)
if ($id < $_GET['substep'])
$upcontext['previous_tables'][] = $table;
$upcontext['cur_table_num'] = $_GET['substep'];
$upcontext['cur_table_name'] = str_replace($db_prefix, '', $queryTables[$_GET['substep']]);
$upcontext['step_progress'] = (int) (($upcontext['cur_table_num'] / $upcontext['table_count']) * 100);
if ($support_js && !isset($_GET['xml']))
{
$_GET['substep'] = 0;
return false;
}
for ($substep = $_GET['substep'], $n = count($queryTables); $substep < $n; $substep++)
{
$table = $queryTables[$substep];
$getTableStatus = $smcFunc['db_query']('', '
SHOW TABLE STATUS
LIKE {string:table_name}',
array(
'table_name' => str_replace('_', '\_', $table)
)
);
$table_info = $smcFunc['db_fetch_assoc']($getTableStatus);
$smcFunc['db_free_result']($getTableStatus);
$upcontext['cur_table_name'] = str_replace($db_prefix, '', (isset($queryTables[$substep + 1]) ? $queryTables[$substep + 1] : $queryTables[$substep]));
$upcontext['cur_table_num'] = $substep + 1;
$upcontext['step_progress'] = (int) (($upcontext['cur_table_num'] / $upcontext['table_count']) * 100);
nextSubstep($substep);
if (function_exists('apache_reset_timeout'))
@apache_reset_timeout();
$table_charsets = array();
$queryColumns = $smcFunc['db_query']('', '
SHOW FULL COLUMNS
FROM ' . $table_info['Name'],
array(
)
);
while ($column_info = $smcFunc['db_fetch_assoc']($queryColumns))
{
if (strpos($column_info['Type'], 'text') !== false || strpos($column_info['Type'], 'char') !== false)
{
$collation = empty($column_info['Collation']) || $column_info['Collation'] === 'NULL' ? $table_info['Collation'] : $column_info['Collation'];
if (!empty($collation) && $collation !== 'NULL')
{
list($charset) = explode('_', $collation);
if ($charset != 'utf8')
{
if (!isset($table_charsets[$charset]))
$table_charsets[$charset] = array();
$table_charsets[$charset][] = $column_info;
}
}
}
}
$smcFunc['db_free_result']($queryColumns);
if (count($table_charsets) > 0)
{
$updates_blob = '';
$updates_text = '';
foreach ($table_charsets as $charset => $columns)
{
if ($charset !== $charsets[$upcontext['charset_detected']])
{
foreach ($columns as $column)
{
$updates_blob .= '
CHANGE COLUMN `' . $column['Field'] . '` `' . $column['Field'] . '` ' . strtr($column['Type'], array('text' => 'blob', 'char' => 'binary')) . ($column['Null'] === 'YES' ? ' NULL' : ' NOT NULL') . (strpos($column['Type'], 'char') === false ? '' : ' default \'' . $column['Default'] . '\'') . ',';
$updates_text .= '
CHANGE COLUMN `' . $column['Field'] . '` `' . $column['Field'] . '` ' . $column['Type'] . ' CHARACTER SET ' . $charsets[$upcontext['charset_detected']] . ($column['Null'] === 'YES' ? '' : ' NOT NULL') . (strpos($column['Type'], 'char') === false ? '' : ' default \'' . $column['Default'] . '\'') . ',';
}
}
}
$smcFunc['db_query']('', '
ALTER TABLE {raw:table_name}{raw:updates_blob}',
array(
'table_name' => $table_info['Name'],
'updates_blob' => substr($updates_blob, 0, -1),
)
);
if (isset($translation_tables[$upcontext['charset_detected']]))
{
$update = '';
foreach ($table_charsets as $charset => $columns)
foreach ($columns as $column)
$update .= '
' . $column['Field'] . ' = ' . strtr($replace, array('%field%' => $column['Field'])) . ',';
$smcFunc['db_query']('', '
UPDATE {raw:table_name}
SET {raw:updates}',
array(
'table_name' => $table_info['Name'],
'updates' => substr($update, 0, -1),
)
);
}
$smcFunc['db_query']('', '
ALTER TABLE {raw:table_name}{raw:updates_text}',
array(
'table_name' => $table_info['Name'],
'updates_text' => substr($updates_text, 0, -1),
)
);
}
if ($charsets[$upcontext['charset_detected']] !== 'utf8')
{
if ($command_line)
echo 'Converting table ' . $table_info['Name'] . ' to UTF-8...';
$smcFunc['db_query']('', '
ALTER TABLE {raw:table_name}
CONVERT TO CHARACTER SET utf8',
array(
'table_name' => $table_info['Name'],
)
);
if ($command_line)
echo " done.\n";
}
if (isset($_GET['xml']) && $upcontext['cur_table_num'] < $upcontext['table_count'])
return upgradeExit();
}
$prev_charset = empty($translation_tables[$upcontext['charset_detected']]) ? $charsets[$upcontext['charset_detected']] : $translation_tables[$upcontext['charset_detected']];
$smcFunc['db_insert']('replace',
'{db_prefix}settings',
array('variable' => 'string', 'value' => 'string'),
array(array('global_character_set', 'UTF-8'), array('previousCharacterSet', $prev_charset)),
array('variable')
);
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile(array('db_character_set' => 'utf8'));
$request = $smcFunc['db_query']('', '
SELECT id_action, extra
FROM {db_prefix}log_actions
WHERE action IN ({string:remove}, {string:delete})',
array(
'remove' => 'remove',
'delete' => 'delete',
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (@safe_unserialize($row['extra']) === false && preg_match('~^(a:3:{s:5:"topic";i:\d+;s:7:"subject";s:)(\d+):"(.+)"(;s:6:"member";s:5:"\d+";})$~', $row['extra'], $matches) === 1)
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_actions
SET extra = {string:extra}
WHERE id_action = {int:current_action}',
array(
'current_action' => $row['id_action'],
'extra' => $matches[1] . strlen($matches[3]) . ':"' . $matches[3] . '"' . $matches[4],
)
);
}
$smcFunc['db_free_result']($request);
if ($upcontext['dropping_index'] && $command_line)
{
echo "\n" . '', $txt['upgrade_fulltext_error'], '';
flush();
}
}
$_GET['substep'] = 0;
return false;
}
function fix_serialized_data($string)
{
if (!is_string($string) || !preg_match('/^[bidsa]:/', $string) || @safe_unserialize($string) !== false)
return $string;
$new_string = preg_replace_callback('~\bs:(\d+):"(.*?)";(?=$|[bidsa]:|[{}]|N;)~s', function ($matches) {return 's:' . strlen($matches[2]) . ':"' . $matches[2] . '";';}, $string);
if (@safe_unserialize($new_string) !== false)
return $new_string;
else
return $string;
}
function serialize_to_json()
{
global $command_line, $smcFunc, $modSettings, $sourcedir, $upcontext, $support_js, $txt;
$upcontext['sub_template'] = isset($_GET['xml']) ? 'serialize_json_xml' : 'serialize_json';
if (!empty($modSettings['json_done']))
{
if ($command_line)
return ConvertUtf8();
else
return true;
}
if (!empty($_POST['json_done']))
return true;
$tables = array(
'background_tasks' => array('id_task', 'task_data'),
'log_actions' => array('id_action', 'extra'),
'log_online' => array('session', 'url'),
'log_packages' => array('id_install', 'db_changes', 'failed_steps', 'credits'),
'log_spider_hits' => array('id_hit', 'url'),
'log_subscribed' => array('id_sublog', 'pending_details'),
'pm_rules' => array('id_rule', 'criteria', 'actions'),
'qanda' => array('id_question', 'answers'),
'subscriptions' => array('id_subscribe', 'cost'),
'user_alerts' => array('id_alert', 'extra', true),
'user_drafts' => array('id_draft', 'to_list', true),
'settings' => array(),
'themes' => array()
);
$keys = array_keys($tables);
$upcontext['page_title'] = $txt['converting_json'];
$upcontext['table_count'] = count($keys);
$upcontext['cur_table_num'] = $_GET['substep'];
$upcontext['cur_table_name'] = isset($keys[$_GET['substep']]) ? $keys[$_GET['substep']] : $keys[0];
$upcontext['step_progress'] = (int) (($upcontext['cur_table_num'] / $upcontext['table_count']) * 100);
foreach ($keys as $id => $table)
if ($id < $_GET['substep'])
$upcontext['previous_tables'][] = $table;
if ($command_line)
echo 'Converting data from serialize() to json_encode().';
if (!$support_js || isset($_GET['xml']))
{
for ($substep = $_GET['substep']; $substep < $upcontext['table_count']; $substep++)
{
$upcontext['cur_table_name'] = isset($keys[$substep + 1]) ? $keys[$substep + 1] : $keys[$substep];
$upcontext['cur_table_num'] = $substep + 1;
$upcontext['step_progress'] = (int) (($upcontext['cur_table_num'] / $upcontext['table_count']) * 100);
nextSubstep($substep);
$where = '';
$vars = array();
$table = $keys[$substep];
$info = $tables[$table];
if ($table == 'settings')
{
$serialized_settings = array(
'attachment_basedirectories',
'attachmentUploadDir',
'cal_today_birthday',
'cal_today_event',
'cal_today_holiday',
'displayFields',
'last_attachments_directory',
'memberlist_cache',
'search_custom_index_config',
'spider_name_cache'
);
$new_settings = array();
if ($command_line)
echo "\n" . 'Fixing some settings...';
foreach ($serialized_settings as $var)
{
if (isset($modSettings[$var]))
{
$temp = @safe_unserialize($modSettings[$var]);
if ($temp === false)
$temp = @safe_unserialize(fix_serialized_data($modSettings[$var]));
if (!$temp && $command_line)
echo "\n - Failed to unserialize the '" . $var . "' setting. Skipping.";
elseif ($temp !== false)
$new_settings[$var] = json_encode($temp);
}
}
if (!function_exists('cache_put_data'))
require_once($sourcedir . '/Load.php');
updateSettings($new_settings, true);
if ($command_line)
echo ' done.';
}
elseif ($table == 'themes')
{
$query = $smcFunc['db_query']('', '
SELECT id_member, id_theme, value FROM {db_prefix}themes
WHERE variable = {string:admin_prefs}',
array(
'admin_prefs' => 'admin_preferences'
)
);
if ($smcFunc['db_num_rows']($query) != 0)
{
while ($row = $smcFunc['db_fetch_assoc']($query))
{
$temp = @safe_unserialize($row['value']);
if ($temp === false)
$temp = @safe_unserialize(fix_serialized_data($row['value']));
if ($command_line)
{
if ($temp === false)
echo "\n" . 'Unserialize of admin_preferences for user ' . $row['id_member'] . ' failed. Skipping.';
else
echo "\n" . 'Fixing admin preferences...';
}
if ($temp !== false)
{
$row['value'] = json_encode($temp);
$smcFunc['db_query']('', '
UPDATE {db_prefix}themes
SET value = {string:prefs}
WHERE id_theme = {int:theme}
AND id_member = {int:member}
AND variable = {string:admin_prefs}',
array(
'prefs' => $row['value'],
'theme' => $row['id_theme'],
'member' => $row['id_member'],
'admin_prefs' => 'admin_preferences'
)
);
if ($command_line)
echo ' done.';
}
}
$smcFunc['db_free_result']($query);
}
}
else
{
$key = $info[0];
unset($info[0]);
if (count($info) == 2 && $info[2] === true)
{
$col_select = $info[1];
$where = ' WHERE ' . $info[1] . ' != {empty}';
}
else
{
$col_select = implode(', ', $info);
}
$query = $smcFunc['db_query']('', '
SELECT ' . $key . ', ' . $col_select . '
FROM {db_prefix}' . $table . $where,
array()
);
if ($smcFunc['db_num_rows']($query) != 0)
{
if ($command_line)
{
echo "\n" . ' +++ Fixing the "' . $table . '" table...';
flush();
}
while ($row = $smcFunc['db_fetch_assoc']($query))
{
$update = '';
foreach ($info as $col)
{
if ($col !== true && $row[$col] != '')
{
$temp = @safe_unserialize($row[$col]);
if ($temp === false)
$temp = @safe_unserialize(fix_serialized_data($row[$col]));
if ($temp === false)
$temp = smf_json_decode($row[$col], true, false);
if ($temp === null)
{
$temp = array();
if ($command_line)
echo "\nFailed to unserialize " . $row[$col] . ". Setting to empty value.\n";
}
$row[$col] = json_encode($temp);
$update .= (empty($update) ? '' : ', ') . $col . ' = {string:' . $col . '}';
$vars[$col] = $row[$col];
}
}
$vars[$key] = $row[$key];
if (!empty($update))
{
$smcFunc['db_query']('', '
UPDATE {db_prefix}' . $table . '
SET ' . $update . '
WHERE ' . $key . ' = {' . ($key == 'session' ? 'string' : 'int') . ':' . $key . '}',
$vars
);
}
}
if ($command_line)
echo ' done.';
$smcFunc['db_free_result']($query);
}
}
if (isset($_GET['xml']))
return upgradeExit();
}
if ($command_line)
{
echo "\n" . 'Successful.' . "\n";
flush();
}
$upcontext['step_progress'] = 100;
updateSettings(array('json_done' => true));
$_GET['substep'] = 0;
if ($command_line)
return ConvertUtf8();
return true;
}
$_GET['substep'] = 0;
return false;
}
function template_chmod()
{
global $upcontext, $txt, $settings;
if (!empty($upcontext['chmod_called']))
return;
$upcontext['chmod_called'] = true;
if (empty($upcontext['chmod']['files']) && empty($upcontext['chmod']['ftp_error']))
return;
if (!empty($upcontext['chmod']['ftp_error']) && $upcontext['chmod']['ftp_error'] == 'total_mess')
{
echo '
<div class="error">
<p>', $txt['upgrade_writable_files'], '</p>
<ul class="error_content">
<li>' . implode('</li>
<li>', $upcontext['chmod']['files']) . '</li>
</ul>
</div>';
return false;
}
echo '
<div class="panel">
<h2>', $txt['upgrade_ftp_login'], '</h2>
<h3>', $txt['upgrade_ftp_perms'], '</h3>
<script>
function warning_popup()
{
popup = window.open(\'\',\'popup\',\'height=150,width=400,scrollbars=yes\');
var content = popup.document;
content.write(\'<!DOCTYPE html>\n\');
content.write(\'<html', $txt['lang_rtl'] == true ? ' dir="rtl"' : '', '>\n\t<head>\n\t\t<meta name="robots" content="noindex">\n\t\t\');
content.write(\'<title>', $txt['upgrade_ftp_warning'], '</title>\n\t\t<link rel="stylesheet" href="', $settings['default_theme_url'], '/css/index.css">\n\t</head>\n\t<body id="popup">\n\t\t\');
content.write(\'<div class="windowbg description">\n\t\t\t<h4>', $txt['upgrade_ftp_files'], '</h4>\n\t\t\t\');
content.write(\'<p>', implode('<br>\n\t\t\t', $upcontext['chmod']['files']), '</p>\n\t\t\t\');';
if (isset($upcontext['systemos']) && $upcontext['systemos'] == 'linux')
echo '
content.write(\'<hr>\n\t\t\t\');
content.write(\'<p>', $txt['upgrade_ftp_shell'], '</p>\n\t\t\t\');
content.write(\'<tt># chmod a+w ', implode(' ', $upcontext['chmod']['files']), '</tt>\n\t\t\t\');';
echo '
content.write(\'<a href="javascript:self.close();">close</a>\n\t\t</div>\n\t</body>\n</html>\');
content.close();
}
</script>';
if (!empty($upcontext['chmod']['ftp_error']))
echo '
<div class="error">
<p>', $txt['upgrade_ftp_error'], '<p>
<code>', $upcontext['chmod']['ftp_error'], '</code>
</div>';
if (empty($upcontext['chmod_in_form']))
echo '
<form action="', $upcontext['form_url'], '" method="post">';
echo '
<dl class="settings">
<dt>
<label for="ftp_server">', $txt['ftp_server'], ':</label>
</dt>
<dd>
<div class="floatright">
<label for="ftp_port" class="textbox"><strong>', $txt['ftp_port'], ':</strong></label>
<input type="text" size="3" name="ftp_port" id="ftp_port" value="', isset($upcontext['chmod']['port']) ? $upcontext['chmod']['port'] : '21', '">
</div>
<input type="text" size="30" name="ftp_server" id="ftp_server" value="', isset($upcontext['chmod']['server']) ? $upcontext['chmod']['server'] : 'localhost', '">
<div class="smalltext">', $txt['ftp_server_info'], '</div>
</dd>
<dt>
<label for="ftp_username">', $txt['ftp_username'], ':</label>
</dt>
<dd>
<input type="text" size="30" name="ftp_username" id="ftp_username" value="', isset($upcontext['chmod']['username']) ? $upcontext['chmod']['username'] : '', '">
<div class="smalltext">', $txt['ftp_username_info'], '</div>
</dd>
<dt>
<label for="ftp_password">', $txt['ftp_password'], ':</label>
</dt>
<dd>
<input type="password" size="30" name="ftp_password" id="ftp_password">
<div class="smalltext">', $txt['ftp_password_info'], '</div>
</dd>
<dt>
<label for="ftp_path">', $txt['ftp_path'], ':</label>
</dt>
<dd>
<input type="text" size="30" name="ftp_path" id="ftp_path" value="', isset($upcontext['chmod']['path']) ? $upcontext['chmod']['path'] : '', '">
<div class="smalltext">', !empty($upcontext['chmod']['path']) ? $txt['ftp_path_found_info'] : $txt['ftp_path_info'], '</div>
</dd>
</dl>
<div class="righttext buttons">
<input type="submit" value="', $txt['ftp_connect'], '" class="button">
</div>';
if (empty($upcontext['chmod_in_form']))
echo '
</form>';
echo '
</div><!-- .panel -->';
}
function template_upgrade_above()
{
global $modSettings, $txt, $settings, $upcontext, $upgradeurl;
echo '<!DOCTYPE html>
<html', $txt['lang_rtl'] == true ? ' dir="rtl"' : '', '>
<head>
<meta charset="', isset($txt['lang_character_set']) ? $txt['lang_character_set'] : 'UTF-8', '">
<meta name="robots" content="noindex">
<title>', $txt['upgrade_upgrade_utility'], '</title>
<link rel="stylesheet" href="', $settings['default_theme_url'], '/css/index.css">
<link rel="stylesheet" href="', $settings['default_theme_url'], '/css/install.css">
', $txt['lang_rtl'] == true ? '<link rel="stylesheet" href="' . $settings['default_theme_url'] . '/css/rtl.css">' : '', '
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="', $settings['default_theme_url'], '/scripts/script.js"></script>
<script>
var smf_scripturl = \'', $upgradeurl, '\';
var smf_charset = \'', (empty($modSettings['global_character_set']) ? (empty($txt['lang_character_set']) ? 'UTF-8' : $txt['lang_character_set']) : $modSettings['global_character_set']), '\';
var startPercent = ', $upcontext['overall_percent'], ';
// This function dynamically updates the step progress bar - and overall one as required.
function updateStepProgress(current, max, overall_weight)
{
// What out the actual percent.
var width = parseInt((current / max) * 100);
if (document.getElementById(\'step_progress\'))
{
document.getElementById(\'step_progress\').style.width = width + "%";
setInnerHTML(document.getElementById(\'step_text\'), width + "%");
}
if (overall_weight && document.getElementById(\'overall_progress\'))
{
overall_width = parseInt(startPercent + width * (overall_weight / 100));
document.getElementById(\'overall_progress\').style.width = overall_width + "%";
setInnerHTML(document.getElementById(\'overall_text\'), overall_width + "%");
}
}
</script>
</head>
<body>
<div id="footerfix">
<div id="header">
<h1 class="forumtitle">', $txt['upgrade_upgrade_utility'], '</h1>
<img id="smflogo" src="', $settings['default_theme_url'], '/images/smflogo.svg" alt="Simple Machines Forum" title="Simple Machines Forum">
</div>
<div id="wrapper">
<div id="content_section">
<div id="main_content_section">
<div id="main_steps">
<h2>', $txt['upgrade_progress'], '</h2>
<ul class="steps_list">';
foreach ($upcontext['steps'] as $num => $step)
echo '
<li', $num == $upcontext['current_step'] ? ' class="stepcurrent"' : '', '>
', $txt['upgrade_step'], ' ', $step[0], ': ', $txt[$step[1]], '
</li>';
echo '
</ul>
</div><!-- #main_steps -->
<div id="install_progress">
<div id="progress_bar" class="progress_bar progress_green">
<h3>', $txt['upgrade_overall_progress'], '</h3>
<div id="overall_progress" class="bar" style="width: ', $upcontext['overall_percent'], '%;"></div>
<span id="overall_text">', $upcontext['overall_percent'], '%</span>
</div>';
if (isset($upcontext['step_progress']))
echo '
<div id="progress_bar_step" class="progress_bar progress_yellow">
<h3>', $txt['upgrade_step_progress'], '</h3>
<div id="step_progress" class="bar" style="width: ', $upcontext['step_progress'], '%;"></div>
<span id="step_text">', $upcontext['step_progress'], '%</span>
</div>';
echo '
<div id="substep_bar_div" class="progress_bar ', isset($upcontext['substep_progress']) ? '' : 'hidden', '">
<h3 id="substep_name">', isset($upcontext['substep_progress_name']) ? trim(strtr($upcontext['substep_progress_name'], array('.' => ''))) : '', '</h3>
<div id="substep_progress" class="bar" style="width: ', isset($upcontext['substep_progress']) ? $upcontext['substep_progress'] : 0, '%;"></div>
<span id="substep_text">', isset($upcontext['substep_progress']) ? $upcontext['substep_progress'] : 0, '%</span>
</div>';
$elapsed = time() - $upcontext['started'];
$mins = (int) ($elapsed / 60);
$seconds = $elapsed - $mins * 60;
echo '
<div class="smalltext time_elapsed">
', $txt['upgrade_time_elapsed'], ':
<span id="mins_elapsed">', $mins, '</span> ', $txt['upgrade_time_mins'], ', <span id="secs_elapsed">', $seconds, '</span> ', $txt['upgrade_time_secs'], '.
</div>';
echo '
</div><!-- #install_progress -->
<div id="main_screen" class="clear">
<h2>', $upcontext['page_title'], '</h2>
<div class="panel">';
}
function template_upgrade_below()
{
global $upcontext, $txt;
if (!empty($upcontext['pause']))
echo '
<em>', $txt['upgrade_incomplete'], '.</em><br>
<h2 style="margin-top: 2ex;">', $txt['upgrade_not_quite_done'], '</h2>
<h3>
', $txt['upgrade_paused_overload'], '
</h3>';
if (!empty($upcontext['custom_warning']))
echo '
<div class="errorbox">
<h3>', $txt['upgrade_note'], '</h3>
', $upcontext['custom_warning'], '
</div>';
echo '
<div class="righttext buttons">';
if (!empty($upcontext['continue']))
echo '
<input type="submit" id="contbutt" name="contbutt" value="', $txt['upgrade_continue'], '"', $upcontext['continue'] == 2 ? ' disabled' : '', ' class="button">';
if (!empty($upcontext['skip']))
echo '
<input type="submit" id="skip" name="skip" value="', $txt['upgrade_skip'], '" onclick="dontSubmit = true; document.getElementById(\'contbutt\').disabled = \'disabled\'; return true;" class="button">';
echo '
</div>
</form>
</div><!-- .panel -->
</div><!-- #main_screen -->
</div><!-- #main_content_section -->
</div><!-- #content_section -->
</div><!-- #wrapper -->
</div><!-- #footerfix -->
<div id="footer">
<ul>
<li class="copyright"><a href="https://www.simplemachines.org/" title="Simple Machines Forum" target="_blank" rel="noopener">SMF © ' . SMF_SOFTWARE_YEAR . ', Simple Machines</a></li>
</ul>
</div>';
if (!empty($upcontext['pause']))
{
echo '
<script>
window.onload = doAutoSubmit;
var countdown = 3;
var dontSubmit = false;
function doAutoSubmit()
{
if (countdown == 0 && !dontSubmit)
document.upform.submit();
else if (countdown == -1)
return;
document.getElementById(\'contbutt\').value = "', $txt['upgrade_continue'], ' (" + countdown + ")";
countdown--;
setTimeout("doAutoSubmit();", 1000);
}
</script>';
}
echo '
</body>
</html>';
}
function template_xml_above()
{
global $upcontext;
echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
<smf>';
if (!empty($upcontext['get_data']))
foreach ($upcontext['get_data'] as $k => $v)
echo '
<get key="', $k, '">', $v, '</get>';
}
function template_xml_below()
{
echo '
</smf>';
}
function template_error_message()
{
global $upcontext;
echo '
<div class="error">
', $upcontext['error_msg'], '
<br>
<a href="', $_SERVER['PHP_SELF'], '">Click here to try again.</a>
</div>';
}
function template_welcome_message()
{
global $upcontext, $disable_security, $settings, $txt;
echo '
<script src="https://www.simplemachines.org/smf/current-version.js?version=' . SMF_VERSION . '"></script>
<h3>', sprintf($txt['upgrade_ready_proceed'], SMF_VERSION), '</h3>
<form action="', $upcontext['form_url'], '" method="post" name="upform" id="upform">
<input type="hidden" name="', $upcontext['login_token_var'], '" value="', $upcontext['login_token'], '">
<div id="version_warning" class="noticebox hidden">
<h3>', $txt['upgrade_warning'], '</h3>
', sprintf($txt['upgrade_warning_out_of_date'], SMF_VERSION, 'https://www.simplemachines.org'), '
</div>';
$upcontext['chmod_in_form'] = true;
template_chmod();
if ($upcontext['is_large_forum'])
echo '
<div class="errorbox">
<h3>', $txt['upgrade_warning'], '</h3>
', $txt['upgrade_warning_lots_data'], '
</div>';
if (!empty($upcontext['warning']))
echo '
<div class="errorbox">
<h3>', $txt['upgrade_warning'], '</h3>
', $upcontext['warning'], '
</div>';
echo '
<div class="errorbox', (file_exists($settings['default_theme_dir'] . '/scripts/script.js') ? ' hidden' : ''), '" id="js_script_missing_error">
<h3>', $txt['upgrade_critical_error'], '</h3>
', sprintf($txt['upgrade_error_script_js'], 'https://download.simplemachines.org/?tools'), '
</div>';
if (!empty($upcontext['user']['id']) && (time() - $upcontext['started'] < 72600 || time() - $upcontext['updated'] < 3600))
{
$ago = time() - $upcontext['started'];
$ago_hours = floor($ago / 3600);
$ago_minutes = intval(($ago / 60) % 60);
$ago_seconds = intval($ago % 60);
$agoTxt = $ago < 60 ? 'upgrade_time_s' : ($ago < 3600 ? 'upgrade_time_ms' : 'upgrade_time_hms');
$updated = time() - $upcontext['updated'];
$updated_hours = floor($updated / 3600);
$updated_minutes = intval(($updated / 60) % 60);
$updated_seconds = intval($updated % 60);
$updatedTxt = $updated < 60 ? 'upgrade_time_updated_s' : ($updated < 3600 ? 'upgrade_time_updated_hm' : 'upgrade_time_updated_hms');
echo '
<div class="errorbox">
<h3>', $txt['upgrade_warning'], '</h3>
<p>', sprintf($txt['upgrade_time_user'], $upcontext['user']['name']), '</p>
<p>', sprintf($txt[$agoTxt], $ago_seconds, $ago_minutes, $ago_hours), '</p>
<p>', sprintf($txt[$updatedTxt], $updated_seconds, $updated_minutes, $updated_hours), '</p>';
if ($updated < 600)
echo '
<p>', $txt['upgrade_run_script'], ' ', $upcontext['user']['name'], ' ', $txt['upgrade_run_script2'], '</p>';
if ($updated > $upcontext['inactive_timeout'])
echo '
<p>', $txt['upgrade_run'], '</p>';
elseif ($upcontext['inactive_timeout'] > 120)
echo '
<p>', sprintf($txt['upgrade_script_timeout_minutes'], $upcontext['user']['name'], round($upcontext['inactive_timeout'] / 60, 1)), '</p>';
else
echo '
<p>', sprintf($txt['upgrade_script_timeout_seconds'], $upcontext['user']['name'], $upcontext['inactive_timeout']), '</p>';
echo '
</div>';
}
echo '
<strong>', $txt['upgrade_admin_login'], ' ', $disable_security ? '(DISABLED)' : '', '</strong>
<h3>', $txt['upgrade_sec_login'], '</h3>
<dl class="settings adminlogin">
<dt>
<label for="user"', $disable_security ? ' disabled' : '', '>', $txt['upgrade_username'], '</label>
</dt>
<dd>
<input type="text" name="user" value="', !empty($upcontext['username']) ? $upcontext['username'] : '', '"', $disable_security ? ' disabled' : '', '>';
if (!empty($upcontext['username_incorrect']))
echo '
<div class="smalltext red">', $txt['upgrade_wrong_username'], '</div>';
echo '
</dd>
<dt>
<label for="passwrd"', $disable_security ? ' disabled' : '', '>', $txt['upgrade_password'], '</label>
</dt>
<dd>
<input type="password" name="passwrd" value=""', $disable_security ? ' disabled' : '', '>
<input type="hidden" name="hash_passwrd" value="">';
if (!empty($upcontext['password_failed']))
echo '
<div class="smalltext red">', $txt['upgrade_wrong_password'], '</div>';
echo '
</dd>';
if (!empty($upcontext['user']['id']) && time() - $upcontext['user']['updated'] >= $upcontext['inactive_timeout'] && $upcontext['user']['step'] > 1)
{
echo '
<dd>
<label for="cont"><input type="checkbox" id="cont" name="cont" checked>', $txt['upgrade_continue_step'], '</label>
</dd>';
}
echo '
</dl>
<span class="smalltext">
', $txt['upgrade_bypass'], '
</span>
<input type="hidden" name="login_attempt" id="login_attempt" value="1">
<input type="hidden" name="js_works" id="js_works" value="0">';
$upcontext['continue'] = !empty($upcontext['user']['id']) && time() - $upcontext['user']['updated'] < $upcontext['inactive_timeout'] ? 2 : 1;
echo '
<script>
if (\'XMLHttpRequest\' in window && document.getElementById(\'js_works\'))
document.getElementById(\'js_works\').value = 1;
// Latest version?
function smfCurrentVersion()
{
var smfVer, yourVer;
if (!(\'smfVersion\' in window))
return;
window.smfVersion = window.smfVersion.replace(/SMF\s?/g, \'\');
smfVer = document.getElementById(\'smfVersion\');
yourVer = document.getElementById(\'yourVersion\');
setInnerHTML(smfVer, window.smfVersion);
var currentVersion = getInnerHTML(yourVer);
if (currentVersion < window.smfVersion)
document.getElementById(\'version_warning\').classList.remove(\'hidden\');
}
addLoadEvent(smfCurrentVersion);
// This checks that the script file even exists!
if (typeof(smfSelectText) == \'undefined\')
document.getElementById(\'js_script_missing_error\').classList.remove(\'hidden\');
</script>';
}
function template_upgrade_options()
{
global $upcontext, $modSettings, $db_prefix, $mmessage, $mtitle, $txt;
echo '
<h3>', $txt['upgrade_areyouready'], '</h3>
<form action="', $upcontext['form_url'], '" method="post" name="upform" id="upform">';
if (!empty($upcontext['upgrade_options_warning']))
echo '
<div class="errorbox">
<h3>', $txt['upgrade_warning'], '</h3>
', $upcontext['upgrade_options_warning'], '
</div>';
echo '
<ul class="upgrade_settings">
<li>
<input type="checkbox" name="backup" id="backup" value="1">
<label for="backup">', $txt['upgrade_backup_table'], ' "backup_' . $db_prefix . '".</label>
(', $txt['upgrade_recommended'], ')
</li>
<li>
<input type="checkbox" name="maint" id="maint" value="1" checked>
<label for="maint">', $txt['upgrade_maintenance'], '</label>
<span class="smalltext">(<a href="javascript:void(0)" onclick="document.getElementById(\'mainmess\').classList.toggle(\'hidden\')">', $txt['upgrade_customize'], '</a>)</span>
<div id="mainmess" class="hidden">
<strong class="smalltext">', $txt['upgrade_maintenance_title'], ' </strong><br>
<input type="text" name="maintitle" size="30" value="', htmlspecialchars($mtitle), '"><br>
<strong class="smalltext">', $txt['upgrade_maintenance_message'], ' </strong><br>
<textarea name="mainmessage" rows="3" cols="50">', htmlspecialchars($mmessage), '</textarea>
</div>
</li>
<li>
<input type="checkbox" name="debug" id="debug" value="1">
<label for="debug">'.$txt['upgrade_debug_info'], '</label>
</li>
<li>
<input type="checkbox" name="empty_error" id="empty_error" value="1">
<label for="empty_error">', $txt['upgrade_empty_errorlog'], '</label>
</li>';
if (!empty($upcontext['karma_installed']['good']) || !empty($upcontext['karma_installed']['bad']))
echo '
<li>
<input type="checkbox" name="delete_karma" id="delete_karma" value="1">
<label for="delete_karma">', $txt['upgrade_delete_karma'], '</label>
</li>';
echo '
<li>
<input type="checkbox" name="stats" id="stats" value="1"', empty($modSettings['allow_sm_stats']) && empty($modSettings['enable_sm_stats']) ? '' : ' checked="checked"', '>
<label for="stat">
', $txt['upgrade_stats_collection'], '<br>
<span class="smalltext">', sprintf($txt['upgrade_stats_info'], 'https://www.simplemachines.org/about/stats.php'), '</a></span>
</label>
</li>
<li>
<input type="checkbox" name="migrateSettings" id="migrateSettings" value="1"', empty($upcontext['migrate_settings_recommended']) ? '' : ' checked="checked"', '>
<label for="migrateSettings">
', $txt['upgrade_migrate_settings_file'], '
</label>
</li>
</ul>
<input type="hidden" name="upcont" value="1">';
$upcontext['continue'] = 1;
}
function template_backup_database()
{
global $upcontext, $support_js, $is_debug, $txt;
echo '
<h3>', $txt['upgrade_wait'], '</h3>';
echo '
<form action="', $upcontext['form_url'], '" name="upform" id="upform" method="post">
<input type="hidden" name="backup_done" id="backup_done" value="0">
<strong>', sprintf($txt['upgrade_completedtables_outof'], $upcontext['cur_table_num'], $upcontext['table_count']), '</strong>
<div id="debug_section">
<span id="debuginfo"></span>
</div>';
if (!empty($upcontext['previous_tables']))
foreach ($upcontext['previous_tables'] as $table)
echo '
<br>', $txt['upgrade_completed_table'], ' "', $table, '".';
echo '
<h3 id="current_tab">
', $txt['upgrade_current_table'], ' "<span id="current_table">', $upcontext['cur_table_name'], '</span>"
</h3>
<p id="commess" class="', $upcontext['cur_table_num'] == $upcontext['table_count'] ? 'inline_block' : 'hidden', '">Backup Complete! Click Continue to Proceed.</p>';
$upcontext['continue'] = $support_js ? 2 : 1;
if ($support_js)
{
echo '
<script>
var lastTable = ', $upcontext['cur_table_num'], ';
function getNextTables()
{
getXMLDocument(\'', $upcontext['form_url'], '&xml&substep=\' + lastTable, onBackupUpdate);
}
// Got an update!
function onBackupUpdate(oXMLDoc)
{
var sCurrentTableName = "";
var iTableNum = 0;
var sCompletedTableName = getInnerHTML(document.getElementById(\'current_table\'));
for (var i = 0; i < oXMLDoc.getElementsByTagName("table")[0].childNodes.length; i++)
sCurrentTableName += oXMLDoc.getElementsByTagName("table")[0].childNodes[i].nodeValue;
iTableNum = oXMLDoc.getElementsByTagName("table")[0].getAttribute("num");
// Update the page.
setInnerHTML(document.getElementById(\'tab_done\'), iTableNum);
setInnerHTML(document.getElementById(\'current_table\'), sCurrentTableName);
lastTable = iTableNum;
updateStepProgress(iTableNum, ', $upcontext['table_count'], ', ', $upcontext['step_weight'] * ((100 - $upcontext['step_progress']) / 100), ');';
if ($is_debug)
echo '
setOuterHTML(document.getElementById(\'debuginfo\'), \'<br>Completed Table: "\' + sCompletedTableName + \'".<span id="debuginfo"><\' + \'/span>\');
if (document.getElementById(\'debug_section\').scrollHeight)
document.getElementById(\'debug_section\').scrollTop = document.getElementById(\'debug_section\').scrollHeight';
echo '
// Get the next update...
if (iTableNum == ', $upcontext['table_count'], ')
{
document.getElementById(\'commess\').classList.remove("hidden");
document.getElementById(\'current_tab\').classList.add("hidden");
document.getElementById(\'contbutt\').disabled = 0;
document.getElementById(\'backup_done\').value = 1;
}
else
getNextTables();
}
getNextTables();
//# sourceURL=dynamicScript-bkup.js
</script>';
}
}
function template_backup_xml()
{
global $upcontext;
echo '
<table num="', $upcontext['cur_table_num'], '">', $upcontext['cur_table_name'], '</table>';
}
function template_database_changes()
{
global $upcontext, $support_js, $is_debug, $timeLimitThreshold, $txt;
if (empty($is_debug) && !empty($upcontext['upgrade_status']['debug']))
$is_debug = true;
echo '
<h3>', $txt['upgrade_db_changes'], '</h3>
<h4><em>', $txt['upgrade_db_patient'], '</em></h4>';
echo '
<form action="', $upcontext['form_url'], '&filecount=', $upcontext['file_count'], '" name="upform" id="upform" method="post">
<input type="hidden" name="database_done" id="database_done" value="0">';
if (!$support_js)
{
foreach ($upcontext['actioned_items'] as $num => $item)
{
if ($num != 0)
echo ' Successful!';
echo '<br>' . $item;
}
if (!empty($upcontext['changes_complete']))
{
if ($is_debug)
{
$active = time() - $upcontext['started'];
$hours = floor($active / 3600);
$minutes = intval(($active / 60) % 60);
$seconds = intval($active % 60);
echo '', sprintf($txt['upgrade_success_time_db'], $seconds, $minutes, $hours), '<br>';
}
else
echo '', $txt['upgrade_success'], '<br>';
echo '
<p id="commess">', $txt['upgrade_db_complete'], '</p>';
}
}
else
{
if ($upcontext['file_count'] > 1)
echo '
<strong id="info1">', $txt['upgrade_script'], ' <span id="file_done">', $upcontext['cur_file_num'], '</span> of ', $upcontext['file_count'], '.</strong>';
echo '
<h3 id="info2">
<strong>', $txt['upgrade_executing'], '</strong> "<span id="cur_item_name">', $upcontext['current_item_name'], '</span>" (<span id="item_num">', $upcontext['current_item_num'], '</span> ', $txt['upgrade_of'], ' <span id="total_items"><span id="item_count">', $upcontext['total_items'], '</span>', $upcontext['file_count'] > 1 ? ' - of this script' : '', ')</span>
</h3>
<p id="commess" class="', !empty($upcontext['changes_complete']) || $upcontext['current_debug_item_num'] == $upcontext['debug_items'] ? 'inline_block' : 'hidden', '">', $txt['upgrade_db_complete2'], '</p>';
if ($is_debug)
{
if ($upcontext['current_debug_item_num'] == $upcontext['debug_items'])
{
$active = time() - $upcontext['started'];
$hours = floor($active / 3600);
$minutes = intval(($active / 60) % 60);
$seconds = intval($active % 60);
echo '
<p id="upgradeCompleted">', sprintf($txt['upgrade_success_time_db'], $seconds, $minutes, $hours), '</p>';
}
else
echo '
<p id="upgradeCompleted"></p>';
echo '
<div id="debug_section">
<span id="debuginfo"></span>
</div>';
}
}
echo '
<div id="error_block" class="errorbox', empty($upcontext['error_message']) ? ' hidden' : '', '">
<h3>', $txt['upgrade_error'], '</h3>
<div id="error_message">', isset($upcontext['error_message']) ? $upcontext['error_message'] : $txt['upgrade_unknown_error'], '</div>
</div>';
$upcontext['continue'] = $support_js ? 2 : 1;
if ($support_js)
{
echo '
<script>
var lastItem = ', $upcontext['current_debug_item_num'], ';
var sLastString = "', strtr($upcontext['current_debug_item_name'], array('"' => '"')), '";
var iLastSubStepProgress = -1;
var curFile = ', $upcontext['cur_file_num'], ';
var totalItems = 0;
var prevFile = 0;
var retryCount = 0;
var testvar = 0;
var timeOutID = 0;
var getData = "";
var debugItems = ', $upcontext['debug_items'], ';';
if ($is_debug)
echo '
var upgradeStartTime = ' . $upcontext['started'] . ';';
echo '
function getNextItem()
{
// We want to track this...
if (timeOutID)
clearTimeout(timeOutID);
timeOutID = window.setTimeout("retTimeout()", ', (10 * $timeLimitThreshold), '000);
getXMLDocument(\'', $upcontext['form_url'], '&xml&filecount=', $upcontext['file_count'], '&substep=\' + lastItem + getData, onItemUpdate);
}
// Got an update!
function onItemUpdate(oXMLDoc)
{
var sItemName = "";
var sDebugName = "";
var iItemNum = 0;
var iSubStepProgress = -1;
var iDebugNum = 0;
var bIsComplete = 0;
var bSkipped = 0;
getData = "";
// We\'ve got something - so reset the timeout!
if (timeOutID)
clearTimeout(timeOutID);
// Assume no error at this time...
document.getElementById("error_block").classList.add("hidden");
// Are we getting some duff info?
if (!oXMLDoc.getElementsByTagName("item")[0])
{
// Too many errors?
if (retryCount > 15)
{
document.getElementById("error_block").classList.remove("hidden");
setInnerHTML(document.getElementById("error_message"), "Error retrieving information on step: " + (sDebugName == "" ? sLastString : sDebugName));';
if ($is_debug)
echo '
setOuterHTML(document.getElementById(\'debuginfo\'), \'<span class="red">failed<\' + \'/span><span id="debuginfo"><\' + \'/span>\');';
echo '
}
else
{
retryCount++;
getNextItem();
}
return false;
}
// Never allow loops.
if (curFile == prevFile)
{
retryCount++;
if (retryCount > 10)
{
document.getElementById("error_block").classList.remove("hidden");
setInnerHTML(document.getElementById("error_message"), "', $txt['upgrade_loop'], '" + sDebugName);';
if ($is_debug)
echo '
setOuterHTML(document.getElementById(\'debuginfo\'), \'<span class="red">failed<\' + \'/span><span id="debuginfo"><\' + \'/span>\');';
echo '
}
}
retryCount = 0;
for (var i = 0; i < oXMLDoc.getElementsByTagName("item")[0].childNodes.length; i++)
sItemName += oXMLDoc.getElementsByTagName("item")[0].childNodes[i].nodeValue;
for (var i = 0; i < oXMLDoc.getElementsByTagName("debug")[0].childNodes.length; i++)
sDebugName += oXMLDoc.getElementsByTagName("debug")[0].childNodes[i].nodeValue;
for (var i = 0; i < oXMLDoc.getElementsByTagName("get").length; i++)
{
getData += "&" + oXMLDoc.getElementsByTagName("get")[i].getAttribute("key") + "=";
for (var j = 0; j < oXMLDoc.getElementsByTagName("get")[i].childNodes.length; j++)
{
getData += oXMLDoc.getElementsByTagName("get")[i].childNodes[j].nodeValue;
}
}
iItemNum = oXMLDoc.getElementsByTagName("item")[0].getAttribute("num");
iDebugNum = parseInt(oXMLDoc.getElementsByTagName("debug")[0].getAttribute("num"));
bIsComplete = parseInt(oXMLDoc.getElementsByTagName("debug")[0].getAttribute("complete"));
bSkipped = parseInt(oXMLDoc.getElementsByTagName("debug")[0].getAttribute("skipped"));
iSubStepProgress = parseFloat(oXMLDoc.getElementsByTagName("debug")[0].getAttribute("percent"));
sLastString = sDebugName + " (Item: " + iDebugNum + ")";
curFile = parseInt(oXMLDoc.getElementsByTagName("file")[0].getAttribute("num"));
debugItems = parseInt(oXMLDoc.getElementsByTagName("file")[0].getAttribute("debug_items"));
totalItems = parseInt(oXMLDoc.getElementsByTagName("file")[0].getAttribute("items"));
// If we have an error we haven\'t completed!
if (oXMLDoc.getElementsByTagName("error")[0] && bIsComplete)
iDebugNum = lastItem;
// Do we have the additional progress bar?
if (iSubStepProgress != -1)
{
document.getElementById("substep_bar_div").classList.remove("hidden");
document.getElementById("substep_progress").style.width = iSubStepProgress + "%";
setInnerHTML(document.getElementById("substep_text"), iSubStepProgress + "%");
setInnerHTML(document.getElementById("substep_name"), sDebugName.replace(/\./g, ""));
}
else
{
document.getElementById("substep_bar_div").classList.add("hidden");
}
// Move onto the next item?
if (bIsComplete)
lastItem = iDebugNum;
else
lastItem = iDebugNum - 1;
// Are we finished?
if (bIsComplete && iDebugNum == -1 && curFile >= ', $upcontext['file_count'], ')
{';
if ($is_debug)
echo '
document.getElementById(\'debug_section\').classList.add("hidden");
var upgradeFinishedTime = parseInt(oXMLDoc.getElementsByTagName("curtime")[0].childNodes[0].nodeValue);
var diffTime = upgradeFinishedTime - upgradeStartTime;
var diffHours = Math.floor(diffTime / 3600);
var diffMinutes = parseInt((diffTime / 60) % 60);
var diffSeconds = parseInt(diffTime % 60);
var completedTxt = "', $txt['upgrade_success_time_db'], '";
console.log(completedTxt, upgradeFinishedTime, diffTime, diffHours, diffMinutes, diffSeconds);
completedTxt = completedTxt.replace("%1$d", diffSeconds).replace("%2$d", diffMinutes).replace("%3$d", diffHours);
console.log(completedTxt, upgradeFinishedTime, diffTime, diffHours, diffMinutes, diffSeconds);
setInnerHTML(document.getElementById("upgradeCompleted"), completedTxt);';
echo '
document.getElementById(\'commess\').classList.remove("hidden");
document.getElementById(\'contbutt\').disabled = 0;
document.getElementById(\'database_done\').value = 1;';
if ($upcontext['file_count'] > 1)
echo '
document.getElementById(\'info1\').classList.add(\'hidden\');';
echo '
document.getElementById(\'info2\').classList.add(\'hidden\');
updateStepProgress(100, 100, ', $upcontext['step_weight'] * ((100 - $upcontext['step_progress']) / 100), ');
return true;
}
// Was it the last step in the file?
else if (bIsComplete && iDebugNum == -1)
{
lastItem = 0;
prevFile = curFile;';
if ($is_debug)
echo '
setOuterHTML(document.getElementById(\'debuginfo\'), \'Moving to next script file...done<br><span id="debuginfo"><\' + \'/span>\');';
echo '
getNextItem();
return true;
}';
if ($is_debug)
echo '
if (iLastSubStepProgress == -1)
{
// Give it consistent dots.
dots = sDebugName.match(/\./g);
numDots = dots ? dots.length : 0;
for (var i = numDots; i < 3; i++)
sDebugName += ".";
setOuterHTML(document.getElementById(\'debuginfo\'), sDebugName + \'<span id="debuginfo"><\' + \'/span>\');
}
iLastSubStepProgress = iSubStepProgress;
if (bIsComplete && bSkipped)
setOuterHTML(document.getElementById(\'debuginfo\'), \'skipped<br><span id="debuginfo"><\' + \'/span>\');
else if (bIsComplete)
setOuterHTML(document.getElementById(\'debuginfo\'), \'done<br><span id="debuginfo"><\' + \'/span>\');
else
setOuterHTML(document.getElementById(\'debuginfo\'), \'...<span id="debuginfo"><\' + \'/span>\');
if (document.getElementById(\'debug_section\').scrollHeight)
document.getElementById(\'debug_section\').scrollTop = document.getElementById(\'debug_section\').scrollHeight';
echo '
// Update the page.
setInnerHTML(document.getElementById(\'item_num\'), iItemNum);
setInnerHTML(document.getElementById(\'cur_item_name\'), sItemName);';
if ($upcontext['file_count'] > 1)
{
echo '
setInnerHTML(document.getElementById(\'file_done\'), curFile);
setInnerHTML(document.getElementById(\'item_count\'), totalItems);';
}
echo '
// Is there an error?
if (oXMLDoc.getElementsByTagName("error")[0])
{
var sErrorMsg = "";
for (var i = 0; i < oXMLDoc.getElementsByTagName("error")[0].childNodes.length; i++)
sErrorMsg += oXMLDoc.getElementsByTagName("error")[0].childNodes[i].nodeValue;
document.getElementById("error_block").classList.remove("hidden");
setInnerHTML(document.getElementById("error_message"), sErrorMsg);
return false;
}
// Get the progress bar right.
barTotal = debugItems * ', $upcontext['file_count'], ';
barDone = (debugItems * (curFile - 1)) + lastItem;
updateStepProgress(barDone, barTotal, ', $upcontext['step_weight'] * ((100 - $upcontext['step_progress']) / 100), ');
// Finally - update the time here as it shows the server is responding!
curTime = new Date();
iElapsed = (curTime.getTime() / 1000 - ', $upcontext['started'], ');
mins = parseInt(iElapsed / 60);
secs = parseInt(iElapsed - mins * 60);
setInnerHTML(document.getElementById("mins_elapsed"), mins);
setInnerHTML(document.getElementById("secs_elapsed"), secs);
getNextItem();
return true;
}
// What if we timeout?!
function retTimeout(attemptAgain)
{
// Oh noes...
if (!attemptAgain)
{
document.getElementById("error_block").classList.remove("hidden");
setInnerHTML(document.getElementById("error_message"), "', sprintf($txt['upgrade_respondtime'], ($timeLimitThreshold * 10)), '" + "<a href=\"#\" onclick=\"retTimeout(true); return false;\">', $txt['upgrade_respondtime_clickhere'], '</a>");
}
else
{
document.getElementById("error_block").classList.add("hidden");
getNextItem();
}
}';
if (empty($upcontext['error_message']))
echo '
getNextItem();';
echo '
//# sourceURL=dynamicScript-dbch.js
</script>';
}
return;
}
function template_database_xml()
{
global $is_debug, $upcontext;
echo '
<file num="', $upcontext['cur_file_num'], '" items="', $upcontext['total_items'], '" debug_items="', $upcontext['debug_items'], '">', $upcontext['cur_file_name'], '</file>
<item num="', $upcontext['current_item_num'], '">', $upcontext['current_item_name'], '</item>
<debug num="', $upcontext['current_debug_item_num'], '" percent="', isset($upcontext['substep_progress']) ? $upcontext['substep_progress'] : '-1', '" complete="', empty($upcontext['completed_step']) ? 0 : 1, '" skipped="', empty($upcontext['skip_db_substeps']) ? 0 : 1, '">', $upcontext['current_debug_item_name'], '</debug>';
if (!empty($upcontext['error_message']))
echo '
<error>', $upcontext['error_message'], '</error>';
if (!empty($upcontext['error_string']))
echo '
<sql>', $upcontext['error_string'], '</sql>';
if ($is_debug)
echo '
<curtime>', time(), '</curtime>';
}
function template_convert_utf8()
{
global $upcontext, $support_js, $is_debug, $txt;
echo '
<h3>', $txt['upgrade_wait2'], '</h3>
<form action="', $upcontext['form_url'], '" name="upform" id="upform" method="post">
<input type="hidden" name="utf8_done" id="utf8_done" value="0">
<strong>', $txt['upgrade_completed'], ' <span id="tab_done">', $upcontext['cur_table_num'], '</span> ', $txt['upgrade_outof'], ' ', $upcontext['table_count'], ' ', $txt['upgrade_tables'], '</strong>
<div id="debug_section">
<span id="debuginfo"></span>
</div>';
if (!empty($upcontext['previous_tables']))
foreach ($upcontext['previous_tables'] as $table)
echo '
<br>', $txt['upgrade_completed_table'], ' "', $table, '".';
echo '
<h3 id="current_tab">
', $txt['upgrade_current_table'], ' "<span id="current_table">', $upcontext['cur_table_name'], '</span>"
</h3>';
if ($upcontext['dropping_index'])
echo '
<p id="indexmsg" class="', $upcontext['cur_table_num'] == $upcontext['table_count'] ? 'inline_block' : 'hidden', '>', $txt['upgrade_fulltext'], '</p>';
echo '
<p id="commess" class="', $upcontext['cur_table_num'] == $upcontext['table_count'] ? 'inline_block' : 'hidden', '">', $txt['upgrade_conversion_proceed'], '</p>';
$upcontext['continue'] = $support_js ? 2 : 1;
if ($support_js)
{
echo '
<script>
var lastTable = ', $upcontext['cur_table_num'], ';
function getNextTables()
{
getXMLDocument(\'', $upcontext['form_url'], '&xml&substep=\' + lastTable, onConversionUpdate);
}
// Got an update!
function onConversionUpdate(oXMLDoc)
{
var sCurrentTableName = "";
var iTableNum = 0;
var sCompletedTableName = getInnerHTML(document.getElementById(\'current_table\'));
for (var i = 0; i < oXMLDoc.getElementsByTagName("table")[0].childNodes.length; i++)
sCurrentTableName += oXMLDoc.getElementsByTagName("table")[0].childNodes[i].nodeValue;
iTableNum = oXMLDoc.getElementsByTagName("table")[0].getAttribute("num");
// Update the page.
setInnerHTML(document.getElementById(\'tab_done\'), iTableNum);
setInnerHTML(document.getElementById(\'current_table\'), sCurrentTableName);
lastTable = iTableNum;
updateStepProgress(iTableNum, ', $upcontext['table_count'], ', ', $upcontext['step_weight'] * ((100 - $upcontext['step_progress']) / 100), ');';
if ($is_debug)
echo '
setOuterHTML(document.getElementById(\'debuginfo\'), \'<br>Completed Table: "\' + sCompletedTableName + \'".<span id="debuginfo"><\' + \'/span>\');
if (document.getElementById(\'debug_section\').scrollHeight)
document.getElementById(\'debug_section\').scrollTop = document.getElementById(\'debug_section\').scrollHeight';
echo '
// Get the next update...
if (iTableNum == ', $upcontext['table_count'], ')
{
document.getElementById(\'commess\').classList.remove(\'hidden\');
if (document.getElementById(\'indexmsg\') != null) {
document.getElementById(\'indexmsg\').classList.remove(\'hidden\');
}
document.getElementById(\'current_tab\').classList.add(\'hidden\');
document.getElementById(\'contbutt\').disabled = 0;
document.getElementById(\'utf8_done\').value = 1;
}
else
getNextTables();
}
getNextTables();
//# sourceURL=dynamicScript-conv.js
</script>';
}
}
function template_convert_xml()
{
global $upcontext;
echo '
<table num="', $upcontext['cur_table_num'], '">', $upcontext['cur_table_name'], '</table>';
}
function template_serialize_json()
{
global $upcontext, $support_js, $is_debug, $txt;
echo '
<h3>', $txt['upgrade_convert_datajson'], '</h3>
<form action="', $upcontext['form_url'], '" name="upform" id="upform" method="post">
<input type="hidden" name="json_done" id="json_done" value="0">
<strong>', $txt['upgrade_completed'], ' <span id="tab_done">', $upcontext['cur_table_num'], '</span> ', $txt['upgrade_outof'], ' ', $upcontext['table_count'], ' ', $txt['upgrade_tables'], '</strong>
<div id="debug_section">
<span id="debuginfo"></span>
</div>';
if (!empty($upcontext['previous_tables']))
foreach ($upcontext['previous_tables'] as $table)
echo '
<br>', $txt['upgrade_completed_table'], ' "', $table, '".';
echo '
<h3 id="current_tab">
', $txt['upgrade_current_table'], ' "<span id="current_table">', $upcontext['cur_table_name'], '</span>"
</h3>
<p id="commess" class="', $upcontext['cur_table_num'] == $upcontext['table_count'] ? 'inline_block' : 'hidden', '">', $txt['upgrade_json_completed'], '</p>';
if ($upcontext['cur_table_num'] == $upcontext['table_count'])
echo '
<input type="hidden" name="substep" id="substep" value="0">';
$upcontext['continue'] = $support_js ? 2 : 1;
if ($support_js)
{
echo '
<script>
var lastTable = ', $upcontext['cur_table_num'], ';
function getNextTables()
{
getXMLDocument(\'', $upcontext['form_url'], '&xml&substep=\' + lastTable, onBackupUpdate);
}
// Got an update!
function onBackupUpdate(oXMLDoc)
{
var sCurrentTableName = "";
var iTableNum = 0;
var sCompletedTableName = getInnerHTML(document.getElementById(\'current_table\'));
for (var i = 0; i < oXMLDoc.getElementsByTagName("table")[0].childNodes.length; i++)
sCurrentTableName += oXMLDoc.getElementsByTagName("table")[0].childNodes[i].nodeValue;
iTableNum = oXMLDoc.getElementsByTagName("table")[0].getAttribute("num");
// Update the page.
setInnerHTML(document.getElementById(\'tab_done\'), iTableNum);
setInnerHTML(document.getElementById(\'current_table\'), sCurrentTableName);
lastTable = iTableNum;
updateStepProgress(iTableNum, ', $upcontext['table_count'], ', ', $upcontext['step_weight'] * ((100 - $upcontext['step_progress']) / 100), ');';
if ($is_debug)
echo '
setOuterHTML(document.getElementById(\'debuginfo\'), \'<br>', $txt['upgrade_completed_table'], ' "\' + sCompletedTableName + \'".<span id="debuginfo"><\' + \'/span>\');
if (document.getElementById(\'debug_section\').scrollHeight)
document.getElementById(\'debug_section\').scrollTop = document.getElementById(\'debug_section\').scrollHeight';
echo '
// Get the next update...
if (iTableNum == ', $upcontext['table_count'], ')
{
document.getElementById(\'commess\').classList.remove("hidden");
document.getElementById(\'current_tab\').classList.add("hidden");
document.getElementById(\'contbutt\').disabled = 0;
document.getElementById(\'json_done\').value = 1;
}
else
getNextTables();
}
getNextTables();
//# sourceURL=dynamicScript-json.js
</script>';
}
}
function template_serialize_json_xml()
{
global $upcontext;
echo '
<table num="', $upcontext['cur_table_num'], '">', $upcontext['cur_table_name'], '</table>';
}
function template_upgrade_complete()
{
global $upcontext, $upgradeurl, $settings, $boardurl, $is_debug, $txt;
echo '
<h3>', $txt['upgrade_done'], ' <a href="', $boardurl, '/index.php">', $txt['upgrade_done2'], '</a>. ', $txt['upgrade_done3'], '</h3>
<form action="', $boardurl, '/index.php">';
if (!empty($upcontext['can_delete_script']))
echo '
<label>
<input type="checkbox" id="delete_self" onclick="doTheDelete(this);"> ', $txt['upgrade_delete_now'], '
</label>
<em>', $txt['upgrade_delete_server'], '</em>
<script>
function doTheDelete(theCheck)
{
var theImage = document.getElementById ? document.getElementById("delete_upgrader") : document.all.delete_upgrader;
theImage.src = "', $upgradeurl, '?delete=1&ts_" + (new Date().getTime());
theCheck.disabled = true;
}
</script>
<img src="', $settings['default_theme_url'], '/images/blank.png" alt="" id="delete_upgrader"><br>';
if ($is_debug)
{
$active = time() - $upcontext['started'];
$hours = floor($active / 3600);
$minutes = intval(($active / 60) % 60);
$seconds = intval($active % 60);
if ($hours > 0)
echo '', sprintf($txt['upgrade_completed_time_hms'], $seconds, $minutes, $hours), '';
elseif ($minutes > 0)
echo '', sprintf($txt['upgrade_completed_time_ms'], $seconds, $minutes), '';
elseif ($seconds > 0)
echo '', sprintf($txt['upgrade_completed_time_s'], $seconds), '';
}
echo '
<p>
', sprintf($txt['upgrade_problems'], 'http://simplemachines.org'), '
<br>
', $txt['upgrade_luck'], '<br>
Simple Machines
</p>';
}
function MySQLConvertOldIp($targetTable, $oldCol, $newCol, $limit = 50000, $setSize = 100)
{
global $smcFunc, $step_progress;
$current_substep = $_GET['substep'];
if (empty($_GET['a']))
$_GET['a'] = 0;
$step_progress['name'] = 'Converting ips';
$step_progress['current'] = $_GET['a'];
$request = $smcFunc['db_query']('', '
SHOW FIELDS
FROM {db_prefix}{raw:table}
WHERE Field = {string:name}',
array(
'table' => $targetTable,
'name' => $oldCol,
)
);
if ($smcFunc['db_num_rows']($request) !== 1)
{
$smcFunc['db_free_result']($request);
return;
}
$smcFunc['db_free_result']($request);
$is_done = false;
while (!$is_done)
{
nextSubstep($current_substep);
$arIp = array();
$request = $smcFunc['db_query']('', '
SELECT DISTINCT {raw:old_col}
FROM {db_prefix}{raw:table_name}
WHERE {raw:new_col} IS NULL AND
{raw:old_col} != {string:unknown} AND
{raw:old_col} != {string:empty}
LIMIT {int:limit}',
array(
'old_col' => $oldCol,
'new_col' => $newCol,
'table_name' => $targetTable,
'empty' => '',
'limit' => $limit,
'unknown' => 'unknown',
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
$arIp[] = $row[$oldCol];
$smcFunc['db_free_result']($request);
if (is_null($arIp[0]))
unset($arIp[0]);
if (empty($arIp))
$is_done = true;
$updates = array();
$cases = array();
$count = count($arIp);
for ($i = 0; $i < $count; $i++)
{
$arIp[$i] = trim($arIp[$i]);
if (empty($arIp[$i]))
continue;
$updates['ip' . $i] = $arIp[$i];
$cases[$arIp[$i]] = 'WHEN ' . $oldCol . ' = {string:ip' . $i . '} THEN {inet:ip' . $i . '}';
if ($setSize > 0 && $i % $setSize === 0)
{
if (count($updates) == 1)
continue;
$updates['whereSet'] = array_values($updates);
$smcFunc['db_query']('', '
UPDATE {db_prefix}' . $targetTable . '
SET ' . $newCol . ' = CASE ' .
implode('
', $cases) . '
ELSE NULL
END
WHERE ' . $oldCol . ' IN ({array_string:whereSet})',
$updates
);
$updates = array();
$cases = array();
}
}
if (!empty($updates))
{
if (count($updates) == 1)
{
foreach ($updates as $key => $ip)
{
$smcFunc['db_query']('', '
UPDATE {db_prefix}' . $targetTable . '
SET ' . $newCol . ' = {inet:ip}
WHERE ' . $oldCol . ' = {string:ip}',
array(
'ip' => $ip
)
);
}
}
else
{
$updates['whereSet'] = array_values($updates);
$smcFunc['db_query']('', '
UPDATE {db_prefix}' . $targetTable . '
SET ' . $newCol . ' = CASE ' .
implode('
', $cases) . '
ELSE NULL
END
WHERE ' . $oldCol . ' IN ({array_string:whereSet})',
$updates
);
}
}
else
$is_done = true;
$_GET['a'] += $limit;
$step_progress['current'] = $_GET['a'];
}
unset($_GET['a']);
}
function upgradeGetColumnInfo($targetTable, $column)
{
global $smcFunc;
db_extend('packages');
$columns = $smcFunc['db_list_columns']($targetTable, true);
if (isset($columns[$column]))
return $columns[$column];
else
return null;
}
?>