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:
<?php
if (!defined('SMF'))
die('No direct access...');
function getServerVersions($checkFor)
{
global $txt, $db_connection, $_PHPA, $smcFunc, $cache_accelerator, $cache_memcached, $cacheAPI, $modSettings;
loadLanguage('Admin');
$versions = array();
if (in_array('gd', $checkFor) && function_exists('gd_info'))
{
$temp = gd_info();
$versions['gd'] = array('title' => $txt['support_versions_gd'], 'version' => $temp['GD Version']);
}
if (in_array('imagemagick', $checkFor) && (class_exists('Imagick') || function_exists('MagickGetVersionString')))
{
if (class_exists('Imagick'))
{
$temp = New Imagick;
$temp2 = $temp->getVersion();
$im_version = $temp2['versionString'];
$extension_version = 'Imagick ' . phpversion('Imagick');
}
else
{
$im_version = MagickGetVersionString();
$extension_version = 'MagickWand ' . phpversion('MagickWand');
}
$im_version = str_replace(array('ImageMagick ', ' https://www.imagemagick.org'), '', $im_version);
$versions['imagemagick'] = array('title' => $txt['support_versions_imagemagick'], 'version' => $im_version . ' (' . $extension_version . ')');
}
if (in_array('db_server', $checkFor))
{
db_extend();
if (!isset($db_connection) || $db_connection === false)
trigger_error('getServerVersions(): you need to be connected to the database in order to get its server version', E_USER_NOTICE);
else
{
$versions['db_engine'] = array('title' => sprintf($txt['support_versions_db_engine'], $smcFunc['db_title']), 'version' => '');
$versions['db_engine']['version'] = $smcFunc['db_get_vendor']();
$versions['db_server'] = array('title' => sprintf($txt['support_versions_db'], $smcFunc['db_title']), 'version' => '');
$versions['db_server']['version'] = $smcFunc['db_get_version']();
}
}
$memcache_version = '???';
if (!empty($cache_accelerator) && ($cache_accelerator == 'memcached' || $cache_accelerator == 'memcache') && !empty($cache_memcached) && !empty($cacheAPI))
$memcache_version = $cacheAPI->getVersion();
if (in_array('phpa', $checkFor) && isset($_PHPA))
$versions['phpa'] = array('title' => 'ionCube PHP-Accelerator', 'version' => $_PHPA['VERSION']);
if (in_array('apc', $checkFor) && extension_loaded('apc'))
$versions['apc'] = array('title' => 'Alternative PHP Cache', 'version' => phpversion('apc'));
if (in_array('memcache', $checkFor) && function_exists('memcache_set'))
$versions['memcache'] = array('title' => 'Memcached', 'version' => $memcache_version);
if (in_array('xcache', $checkFor) && function_exists('xcache_set'))
$versions['xcache'] = array('title' => 'XCache', 'version' => XCACHE_VERSION);
if (in_array('php', $checkFor))
$versions['php'] = array('title' => 'PHP', 'version' => PHP_VERSION, 'more' => '?action=admin;area=serversettings;sa=phpinfo');
if (in_array('server', $checkFor))
$versions['server'] = array('title' => $txt['support_versions_server'], 'version' => $_SERVER['SERVER_SOFTWARE']);
return $versions;
}
function getFileVersions(&$versionOptions)
{
global $boarddir, $sourcedir, $settings, $tasksdir;
$lang_dir = $settings['default_theme_dir'] . '/languages';
$version_info = array(
'file_versions' => array(),
'default_template_versions' => array(),
'template_versions' => array(),
'default_language_versions' => array(),
'tasks_versions' => array(),
);
if (!empty($versionOptions['include_ssi']) && file_exists($boarddir . '/SSI.php'))
{
$fp = fopen($boarddir . '/SSI.php', 'rb');
$header = fread($fp, 4096);
fclose($fp);
if (preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $header, $match) == 1)
$version_info['file_versions']['SSI.php'] = $match[1];
else
$version_info['file_versions']['SSI.php'] = '??';
}
if (!empty($versionOptions['include_subscriptions']) && file_exists($boarddir . '/subscriptions.php'))
{
$fp = fopen($boarddir . '/subscriptions.php', 'rb');
$header = fread($fp, 4096);
fclose($fp);
if (preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $header, $match) == 1)
$version_info['file_versions']['subscriptions.php'] = $match[1];
else
$version_info['file_versions']['subscriptions.php'] = '??';
}
$sources_dir = dir($sourcedir);
while ($entry = $sources_dir->read())
{
if (substr($entry, -4) === '.php' && !is_dir($sourcedir . '/' . $entry) && $entry !== 'index.php')
{
$fp = fopen($sourcedir . '/' . $entry, 'rb');
$header = fread($fp, 4096);
fclose($fp);
if (preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $header, $match) == 1)
$version_info['file_versions'][$entry] = $match[1];
else
$version_info['file_versions'][$entry] = '??';
}
}
$sources_dir->close();
if (!empty($versionOptions['include_tasks']))
{
$tasks_dir = dir($tasksdir);
while ($entry = $tasks_dir->read())
{
if (substr($entry, -4) === '.php' && !is_dir($tasksdir . '/' . $entry) && $entry !== 'index.php')
{
$fp = fopen($tasksdir . '/' . $entry, 'rb');
$header = fread($fp, 4096);
fclose($fp);
if (preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $header, $match) == 1)
$version_info['tasks_versions'][$entry] = $match[1];
else
$version_info['tasks_versions'][$entry] = '??';
}
}
$tasks_dir->close();
}
$directories = array('default_template_versions' => $settings['default_theme_dir']);
if ($settings['theme_id'] != 1)
$directories += array('template_versions' => $settings['theme_dir']);
foreach ($directories as $type => $dirname)
{
$this_dir = dir($dirname);
while ($entry = $this_dir->read())
{
if (substr($entry, -12) == 'template.php' && !is_dir($dirname . '/' . $entry))
{
$fp = fopen($dirname . '/' . $entry, 'rb');
$header = fread($fp, 768);
fclose($fp);
if (preg_match('~\*\s@version\s+(.+)[\s]{2}~i', $header, $match) == 1)
$version_info[$type][$entry] = $match[1];
else
$version_info[$type][$entry] = '??';
}
}
$this_dir->close();
}
$this_dir = dir($lang_dir);
while ($entry = $this_dir->read())
{
if (substr($entry, -4) == '.php' && $entry != 'index.php' && !is_dir($lang_dir . '/' . $entry))
{
$fp = fopen($lang_dir . '/' . $entry, 'rb');
$header = fread($fp, 768);
fclose($fp);
list ($name, $language) = explode('.', $entry);
if (preg_match('~(?://|/\*)\s*Version:\s+(.+?);\s*' . preg_quote($name, '~') . '(?:[\s]{2}|\*/)~i', $header, $match) == 1)
$version_info['default_language_versions'][$language][$name] = $match[1];
else
$version_info['default_language_versions'][$language][$name] = '??';
}
}
$this_dir->close();
if (!empty($versionOptions['sort_results']))
{
ksort($version_info['file_versions']);
ksort($version_info['default_template_versions']);
ksort($version_info['template_versions']);
ksort($version_info['default_language_versions']);
ksort($version_info['tasks_versions']);
foreach ($version_info['default_language_versions'] as $language => $dummy)
ksort($version_info['default_language_versions'][$language]);
}
return $version_info;
}
function updateSettingsFile($config_vars, $keep_quotes = null, $rebuild = false)
{
static $mtime;
if (empty($keep_quotes))
{
foreach ($config_vars as $var => $val)
{
if (is_string($val) && ($keep_quotes === false || strpos($val, '\'') === 0 && strrpos($val, '\'') === strlen($val) - 1))
$config_vars[$var] = trim(stripcslashes($val), '\'');
}
}
if (isset($config_vars['db_last_error']))
{
updateDbLastError($config_vars['db_last_error']);
if (count($config_vars) === 1 && empty($rebuild))
return true;
$config_vars['db_last_error'] = 0;
}
if (!is_bool($rebuild))
$rebuild = false;
$mtime = isset($mtime) ? (int) $mtime : (defined('TIME_START') ? TIME_START : $_SERVER['REQUEST_TIME']);
foreach (get_included_files() as $settingsFile)
if (basename($settingsFile) === 'Settings.php')
break;
if (basename($settingsFile) !== 'Settings.php')
$settingsFile = (!empty($GLOBALS['boarddir']) && @realpath($GLOBALS['boarddir']) ? $GLOBALS['boarddir'] : (!empty($_SERVER['SCRIPT_FILENAME']) ? dirname($_SERVER['SCRIPT_FILENAME']) : dirname(__DIR__))) . '/Settings.php';
if (!file_exists($settingsFile))
@touch($settingsFile);
$last_settings_change = filemtime($settingsFile);
$settings_vars = get_current_settings($mtime, $settingsFile);
if (empty($settings_vars) && file_exists(dirname($settingsFile) . '/Settings_bak.php'))
$settings_vars = get_current_settings($mtime, dirname($settingsFile) . '/Settings_bak.php');
if ($settings_vars === false)
return false;
$new_settings_vars = array_merge($settings_vars, $config_vars);
$utf8 = isset($GLOBALS['context']['utf8']) ? $GLOBALS['context']['utf8'] : (isset($GLOBALS['utf8']) ? $GLOBALS['utf8'] : (isset($settings_vars['db_character_set']) ? $settings_vars['db_character_set'] === 'utf8' : false));
$settings_defs = array(
array(
'text' => implode("\n", array(
'',
'/**',
' * The settings file contains all of the basic settings that need to be present when a database/cache is not available.',
' *',
' * Simple Machines Forum (SMF)',
' *',
' * @package SMF',
' * @author Simple Machines https://www.simplemachines.org',
' * @copyright ' . SMF_SOFTWARE_YEAR . ' Simple Machines and individual contributors',
' * @license https://www.simplemachines.org/about/smf/license.php BSD',
' *',
' * @version ' . SMF_VERSION,
' */',
'',
)),
'search_pattern' => '~/\*\*.*?@package\h+SMF\b.*?\*/\n{0,2}~s',
),
'maintenance' => array(
'text' => implode("\n", array(
'',
'########## Maintenance ##########',
'/**',
' * The maintenance "mode"',
' * Set to 1 to enable Maintenance Mode, 2 to make the forum untouchable. (you\'ll have to make it 0 again manually!)',
' * 0 is default and disables maintenance mode.',
' *',
' * @var int 0, 1, 2',
' * @global int $maintenance',
' */',
)),
'default' => 0,
'type' => 'integer',
),
'mtitle' => array(
'text' => implode("\n", array(
'/**',
' * Title for the Maintenance Mode message.',
' *',
' * @var string',
' * @global int $mtitle',
' */',
)),
'default' => 'Maintenance Mode',
'type' => 'string',
),
'mmessage' => array(
'text' => implode("\n", array(
'/**',
' * Description of why the forum is in maintenance mode.',
' *',
' * @var string',
' * @global string $mmessage',
' */',
)),
'default' => 'Okay faithful users...we\'re attempting to restore an older backup of the database...news will be posted once we\'re back!',
'type' => 'string',
),
'mbname' => array(
'text' => implode("\n", array(
'',
'########## Forum Info ##########',
'/**',
' * The name of your forum.',
' *',
' * @var string',
' */',
)),
'default' => 'My Community',
'type' => 'string',
),
'language' => array(
'text' => implode("\n", array(
'/**',
' * The default language file set for the forum.',
' *',
' * @var string',
' */',
)),
'default' => 'english',
'type' => 'string',
),
'boardurl' => array(
'text' => implode("\n", array(
'/**',
' * URL to your forum\'s folder. (without the trailing /!)',
' *',
' * @var string',
' */',
)),
'default' => 'http://127.0.0.1/smf',
'type' => 'string',
),
'webmaster_email' => array(
'text' => implode("\n", array(
'/**',
' * Email address to send emails from. (like noreply@yourdomain.com.)',
' *',
' * @var string',
' */',
)),
'default' => 'noreply@myserver.com',
'type' => 'string',
),
'cookiename' => array(
'text' => implode("\n", array(
'/**',
' * Name of the cookie to set for authentication.',
' *',
' * @var string',
' */',
)),
'default' => 'SMFCookie11',
'type' => 'string',
),
'db_type' => array(
'text' => implode("\n", array(
'',
'########## Database Info ##########',
'/**',
' * The database type',
' * Default options: mysql, postgresql',
' *',
' * @var string',
' */',
)),
'default' => 'mysql',
'type' => 'string',
),
'db_port' => array(
'text' => implode("\n", array(
'/**',
' * The database port',
' * 0 to use default port for the database type',
' *',
' * @var int',
' */',
)),
'default' => 0,
'type' => 'integer',
),
'db_server' => array(
'text' => implode("\n", array(
'/**',
' * The server to connect to (or a Unix socket)',
' *',
' * @var string',
' */',
)),
'default' => 'localhost',
'required' => true,
'type' => 'string',
),
'db_name' => array(
'text' => implode("\n", array(
'/**',
' * The database name',
' *',
' * @var string',
' */',
)),
'default' => 'smf',
'required' => true,
'type' => 'string',
),
'db_user' => array(
'text' => implode("\n", array(
'/**',
' * Database username',
' *',
' * @var string',
' */',
)),
'default' => 'root',
'required' => true,
'type' => 'string',
),
'db_passwd' => array(
'text' => implode("\n", array(
'/**',
' * Database password',
' *',
' * @var string',
' */',
)),
'default' => '',
'required' => true,
'type' => 'string',
),
'ssi_db_user' => array(
'text' => implode("\n", array(
'/**',
' * Database user for when connecting with SSI',
' *',
' * @var string',
' */',
)),
'default' => '',
'type' => 'string',
),
'ssi_db_passwd' => array(
'text' => implode("\n", array(
'/**',
' * Database password for when connecting with SSI',
' *',
' * @var string',
' */',
)),
'default' => '',
'type' => 'string',
),
'db_prefix' => array(
'text' => implode("\n", array(
'/**',
' * A prefix to put in front of your table names.',
' * This helps to prevent conflicts',
' *',
' * @var string',
' */',
)),
'default' => 'smf_',
'required' => true,
'type' => 'string',
),
'db_persist' => array(
'text' => implode("\n", array(
'/**',
' * Use a persistent database connection',
' *',
' * @var bool',
' */',
)),
'default' => false,
'type' => 'boolean',
),
'db_error_send' => array(
'text' => implode("\n", array(
'/**',
' * Send emails on database connection error',
' *',
' * @var bool',
' */',
)),
'default' => false,
'type' => 'boolean',
),
'db_mb4' => array(
'text' => implode("\n", array(
'/**',
' * Override the default behavior of the database layer for mb4 handling',
' * null keep the default behavior untouched',
' *',
' * @var null|bool',
' */',
)),
'default' => null,
'type' => array('NULL', 'boolean'),
),
'cache_accelerator' => array(
'text' => implode("\n", array(
'',
'########## Cache Info ##########',
'/**',
' * Select a cache system. You want to leave this up to the cache area of the admin panel for',
' * proper detection of apc, memcached, output_cache, smf, or xcache',
' * (you can add more with a mod).',
' *',
' * @var string',
' */',
)),
'default' => '',
'type' => 'string',
),
'cache_enable' => array(
'text' => implode("\n", array(
'/**',
' * The level at which you would like to cache. Between 0 (off) through 3 (cache a lot).',
' *',
' * @var int',
' */',
)),
'default' => 0,
'type' => 'integer',
),
'cache_memcached' => array(
'text' => implode("\n", array(
'/**',
' * This is only used for memcache / memcached. Should be a string of \'server:port,server:port\'',
' *',
' * @var array',
' */',
)),
'default' => '',
'type' => 'string',
),
'cachedir' => array(
'text' => implode("\n", array(
'/**',
' * This is only for the \'smf\' file cache system. It is the path to the cache directory.',
' * It is also recommended that you place this in /tmp/ if you are going to use this.',
' *',
' * @var string',
' */',
)),
'default' => 'dirname(__FILE__) . \'/cache\'',
'raw_default' => true,
'type' => 'string',
),
'image_proxy_enabled' => array(
'text' => implode("\n", array(
'',
'########## Image Proxy ##########',
'# This is done entirely in Settings.php to avoid loading the DB while serving the images',
'/**',
' * Whether the proxy is enabled or not',
' *',
' * @var bool',
' */',
)),
'default' => true,
'type' => 'boolean',
),
'image_proxy_secret' => array(
'text' => implode("\n", array(
'/**',
' * Secret key to be used by the proxy',
' *',
' * @var string',
' */',
)),
'default' => 'smfisawesome',
'type' => 'string',
),
'image_proxy_maxsize' => array(
'text' => implode("\n", array(
'/**',
' * Maximum file size (in KB) for individual files',
' *',
' * @var int',
' */',
)),
'default' => 5192,
'type' => 'integer',
),
'boarddir' => array(
'text' => implode("\n", array(
'',
'########## Directories/Files ##########',
'# Note: These directories do not have to be changed unless you move things.',
'/**',
' * The absolute path to the forum\'s folder. (not just \'.\'!)',
' *',
' * @var string',
' */',
)),
'default' => 'dirname(__FILE__)',
'raw_default' => true,
'type' => 'string',
),
'sourcedir' => array(
'text' => implode("\n", array(
'/**',
' * Path to the Sources directory.',
' *',
' * @var string',
' */',
)),
'default' => 'dirname(__FILE__) . \'/Sources\'',
'raw_default' => true,
'type' => 'string',
),
'packagesdir' => array(
'text' => implode("\n", array(
'/**',
' * Path to the Packages directory.',
' *',
' * @var string',
' */',
)),
'default' => 'dirname(__FILE__) . \'/Packages\'',
'raw_default' => true,
'type' => 'string',
),
'tasksdir' => array(
'text' => implode("\n", array(
'/**',
' * Path to the tasks directory.',
' *',
' * @var string',
' */',
)),
'default' => '$sourcedir . \'/tasks\'',
'raw_default' => true,
'type' => 'string',
),
array(
'text' => implode("\n", array(
'',
'# Make sure the paths are correct... at least try to fix them.',
'if (!is_dir(realpath($boarddir)) && file_exists(dirname(__FILE__) . \'/agreement.txt\'))',
' $boarddir = dirname(__FILE__);',
'if (!is_dir(realpath($sourcedir)) && is_dir($boarddir . \'/Sources\'))',
' $sourcedir = $boarddir . \'/Sources\';',
'if (!is_dir(realpath($tasksdir)) && is_dir($sourcedir . \'/tasks\'))',
' $tasksdir = $sourcedir . \'/tasks\';',
'if (!is_dir(realpath($packagesdir)) && is_dir($boarddir . \'/Packages\'))',
' $packagesdir = $boarddir . \'/Packages\';',
'if (!is_dir(realpath($cachedir)) && is_dir($boarddir . \'/cache\'))',
' $cachedir = $boarddir . \'/cache\';',
)),
'search_pattern' => '~\n?(#[^\n]+)?(?:\n\h*if\s*\((?:\!file_exists\(\$(?>boarddir|sourcedir|tasksdir|packagesdir|cachedir)\)|\!is_dir\(realpath\(\$(?>boarddir|sourcedir|tasksdir|packagesdir|cachedir)\)\))[^;]+\n\h*\$(?>boarddir|sourcedir|tasksdir|packagesdir|cachedir)[^\n]+;)+~sm',
),
'db_character_set' => array(
'text' => implode("\n", array(
'',
'######### Legacy Settings #########',
'# UTF-8 is now the only character set supported in 2.1.',
)),
'default' => 'utf8',
'type' => 'string',
),
'db_show_debug' => array(
'text' => implode("\n", array(
'',
'######### Developer Settings #########',
'# Show debug info.',
)),
'default' => false,
'auto_delete' => 2,
'type' => 'boolean',
),
array(
'text' => implode("\n", array(
'',
'########## Error-Catching ##########',
'# Note: You shouldn\'t touch these settings.',
'if (file_exists((isset($cachedir) ? $cachedir : dirname(__FILE__)) . \'/db_last_error.php\'))',
' include((isset($cachedir) ? $cachedir : dirname(__FILE__)) . \'/db_last_error.php\');',
'',
'if (!isset($db_last_error))',
'{',
' // File does not exist so lets try to create it',
' file_put_contents((isset($cachedir) ? $cachedir : dirname(__FILE__)) . \'/db_last_error.php\', \'<\' . \'?\' . "php\n" . \'$db_last_error = 0;\' . "\n" . \'?\' . \'>\');',
' $db_last_error = 0;',
'}',
)),
'search_pattern' => '~\n?#+ Error.Catching #+.*?\$db_last_error = 0;(?' . '>\s*})?(?=\n|\?' . '>|$)~s',
),
'upgradeData' => array(
'default' => '',
'auto_delete' => 1,
'type' => 'string',
),
'db_last_error' => array(
'default' => 0,
'auto_delete' => 1,
'type' => 'integer',
),
);
if (function_exists('call_integration_hook'))
call_integration_hook('integrate_update_settings_file', array(&$settings_defs));
if ($settings_vars === array())
{
foreach ($settings_defs as $var => $setting_def)
if (isset($GLOBALS[$var]))
$settings_vars[$var] = $GLOBALS[$var];
$new_settings_vars = array_merge($settings_vars, $config_vars);
}
if (defined('SMF_INSTALLING') && empty($rebuild))
{
foreach ($settings_defs as $var => $setting_def)
if (!in_array($var, array_keys($new_settings_vars)) && !is_int($var))
unset($settings_defs[$var]);
}
$type_regex = array(
'string' =>
'(?:' .
'(["\'])' .
'(?:.(?!\\1)|\\\(?=\\1))*.?' .
'\\1' .
'(?:\s*\.\s*)*' .
')+',
'integer' => '["\']?[+-]?\d+["\']?',
'double' => '["\']?[+-]?\d+\.\d+([Ee][+-]\d+)?["\']?',
'boolean' => '(?i:TRUE|FALSE|(["\']?)[01]\b\\1)',
'NULL' => '(?i:NULL)',
'array' => 'array\s*(\((?>[^()]|(?1))*\))',
'object' => '\w+::__set_state\(array\s*(\((?>[^()]|(?1))*\))\)',
);
$prefix = mt_rand() . '-';
$neg_index = -1;
$substitutions = array(
$neg_index-- => array(
'search_pattern' => '~^\s*<\?(php\b)?\n?~',
'placeholder' => '',
'replace_pattern' => '~^~',
'replacement' => '<' . "?php\n",
),
$neg_index-- => array(
'search_pattern' => '~\S\K\s*(\?' . '>)?\s*$~',
'placeholder' => "\n" . md5($prefix . '?' . '>'),
'replacement' => "\n\n?" . '>',
),
$neg_index-- => array(
'search_pattern' => '~^if\s*\(file_exists\(dirname\(__FILE__\)\s*\.\s*\'/install\.php\'\)\)\s*(?:({(?>[^{}]|(?1))*})\h*|header(\((?' . '>[^()]|(?2))*\));\n)~m',
'placeholder' => '',
),
);
if (defined('SMF_INSTALLING'))
$substitutions[$neg_index--] = array(
'search_pattern' => '~/\*.*?SMF\s+1\.\d.*?\*/~s',
'placeholder' => '',
);
foreach ($settings_defs as $var => $setting_def)
{
$placeholder = md5($prefix . $var);
$replacement = '';
if (!empty($setting_def['text']))
{
if (strpos($setting_def['text'], "* @package SMF\n") !== false)
{
$substitutions[$var]['search_pattern'] = $setting_def['search_pattern'];
$substitutions[$var]['placeholder'] = '';
$substitutions[-1]['replacement'] .= $setting_def['text'] . "\n";
}
elseif (strpos($setting_def['text'], 'Error-Catching') !== false)
{
$errcatch_var = $var;
$substitutions[$var]['search_pattern'] = $setting_def['search_pattern'];
$substitutions[$var]['placeholder'] = '';
$substitutions[-2]['replacement'] = "\n" . $setting_def['text'] . $substitutions[-2]['replacement'];
}
elseif (is_int($var))
{
if (strpos($setting_def['text'], '# Make sure the paths are correct') !== false)
$pathcode_var = $var;
if (!empty($setting_def['search_pattern']))
$substitutions[$var]['search_pattern'] = $setting_def['search_pattern'];
else
$substitutions[$var]['search_pattern'] = '~' . preg_quote($setting_def['text'], '~') . '~';
$substitutions[$var]['placeholder'] = $placeholder;
$replacement .= $setting_def['text'] . "\n";
}
elseif (!empty($rebuild))
$replacement .= $setting_def['text'] . "\n";
}
if (is_string($var))
{
if (in_array($var, array_keys($new_settings_vars)))
{
if (is_object($new_settings_vars[$var]) && !method_exists($new_settings_vars[$var], '__set_state'))
{
if (method_exists($new_settings_vars[$var], '__toString'))
$new_settings_vars[$var] = (string) $new_settings_vars[$var];
else
$new_settings_vars[$var] = (array) $new_settings_vars[$var];
}
if (isset($setting_def['type']))
{
$expected_types = (array) $setting_def['type'];
$var_type = gettype($new_settings_vars[$var]);
if (!in_array($var_type, $expected_types))
{
if ($var_type == 'array')
{
$temp = reset($new_settings_vars[$var]);
if (count($new_settings_vars[$var]) === 1 && is_scalar($temp))
$new_settings_vars[$var] = $temp;
elseif (isset($settings_vars[$var]) && in_array(gettype($settings_vars[$var]), $expected_types))
$new_settings_vars[$var] = $settings_vars[$var];
else
$new_settings_vars[$var] = $setting_def['default'];
}
foreach (array('boolean', 'integer', 'double', 'string', 'array') as $to_type)
{
if (in_array($to_type, $expected_types))
{
settype($new_settings_vars[$var], $to_type);
break;
}
}
}
}
}
elseif (!empty($setting_def['required']) && !defined('SMF_INSTALLING'))
return false;
if (!empty($setting_def['search_pattern']))
$substitutions[$var]['search_pattern'] = $setting_def['search_pattern'];
else
{
$var_pattern = array();
if (isset($setting_def['type']))
{
foreach ((array) $setting_def['type'] as $type)
$var_pattern[] = $type_regex[$type];
}
if (in_array($var, array_keys($config_vars)))
{
$var_pattern[] = @$type_regex[gettype($config_vars[$var])];
if (is_string($config_vars[$var]) && strpos($config_vars[$var], dirname($settingsFile)) === 0)
$var_pattern[] = '(?:__DIR__|dirname\(__FILE__\)) . \'' . (preg_quote(str_replace(dirname($settingsFile), '', $config_vars[$var]), '~')) . '\'';
}
if (in_array($var, array_keys($settings_vars)))
{
$var_pattern[] = @$type_regex[gettype($settings_vars[$var])];
if (is_string($settings_vars[$var]) && strpos($settings_vars[$var], dirname($settingsFile)) === 0)
$var_pattern[] = '(?:__DIR__|dirname\(__FILE__\)) . \'' . (preg_quote(str_replace(dirname($settingsFile), '', $settings_vars[$var]), '~')) . '\'';
}
if (!empty($setting_def['raw_default']) && $setting_def['default'] !== '')
{
$var_pattern[] = preg_replace('/\s+/', '\s+', preg_quote($setting_def['default'], '~'));
if (strpos($setting_def['default'], 'dirname(__FILE__)') !== false)
$var_pattern[] = preg_replace('/\s+/', '\s+', preg_quote(str_replace('dirname(__FILE__)', '__DIR__', $setting_def['default']), '~'));
if (strpos($setting_def['default'], '__DIR__') !== false)
$var_pattern[] = preg_replace('/\s+/', '\s+', preg_quote(str_replace('__DIR__', 'dirname(__FILE__)', $setting_def['default']), '~'));
}
$var_pattern = array_unique($var_pattern);
$var_pattern = count($var_pattern) > 1 ? '(?:' . (implode('|', $var_pattern)) . ')' : $var_pattern[0];
$substitutions[$var]['search_pattern'] = '~(?<=^|\s)\h*\$' . preg_quote($var, '~') . '\s*=\s*' . $var_pattern . ';~' . (!empty($context['utf8']) ? 'u' : '');
}
if (!empty($setting_def['replace_pattern']))
$substitutions[$var]['replace_pattern'] = $setting_def['replace_pattern'];
else
$substitutions[$var]['placeholder'] = $placeholder;
if (!empty($setting_def['auto_delete']) && empty($new_settings_vars[$var]))
{
if ($setting_def['auto_delete'] === 2 && empty($rebuild) && in_array($var, array_keys($new_settings_vars)))
{
$replacement .= '$' . $var . ' = ' . ($new_settings_vars[$var] === $setting_def['default'] && !empty($setting_def['raw_default']) ? sprintf($new_settings_vars[$var]) : smf_var_export($new_settings_vars[$var], true)) . ";";
}
else
{
$replacement = '';
$substitutions[$var]['search_pattern'] = str_replace('(?<=^|\s)', '\n?', $substitutions[$var]['search_pattern']);
}
}
elseif (in_array($var, array_keys($new_settings_vars)))
{
$replacement .= '$' . $var . ' = ' . ($new_settings_vars[$var] === $setting_def['default'] && !empty($setting_def['raw_default']) ? sprintf($new_settings_vars[$var]) : smf_var_export($new_settings_vars[$var], true)) . ";";
}
elseif (isset($setting_def['default']))
{
$replacement .= '$' . $var . ' = ' . (!empty($setting_def['raw_default']) ? sprintf($setting_def['default']) : smf_var_export($setting_def['default'], true)) . ';';
}
else
$replacement .= '$' . $var . ' = null;';
}
$substitutions[$var]['replacement'] = $replacement;
unset($new_settings_vars[$var]);
}
foreach ($new_settings_vars as $var => $val)
{
$var_pattern = array();
if (in_array($var, array_keys($config_vars)))
$var_pattern[] = $type_regex[gettype($config_vars[$var])];
if (in_array($var, array_keys($settings_vars)))
$var_pattern[] = $type_regex[gettype($settings_vars[$var])];
$var_pattern = array_unique($var_pattern);
$var_pattern = count($var_pattern) > 1 ? '(?:' . (implode('|', $var_pattern)) . ')' : $var_pattern[0];
$placeholder = md5($prefix . $var);
$substitutions[$var]['search_pattern'] = '~(?<=^|\s)\h*\$' . preg_quote($var, '~') . '\s*=\s*' . $var_pattern . ';~' . (!empty($context['utf8']) ? 'u' : '');
$substitutions[$var]['placeholder'] = $placeholder;
$substitutions[$var]['replacement'] = '$' . $var . ' = ' . smf_var_export($val, true) . ";";
}
if (defined('SMF_INSTALLING') && empty($rebuild))
{
preg_match_all('~^\h*\$(\w+)\s*=\s*~m', $substitutions[$pathcode_var]['replacement'], $matches);
$missing_pathvars = array_diff($matches[1], array_keys($substitutions));
if (!empty($missing_pathvars))
{
foreach ($missing_pathvars as $var)
{
$substitutions[$pathcode_var]['replacement'] = preg_replace('~\nif[^\n]+\$' . $var . '[^\n]+\n\h*\$' . $var . ' = [^\n]+~', '', $substitutions[$pathcode_var]['replacement']);
}
}
}
uksort($substitutions, function($a, $b) {
if (is_int($a) && is_int($b))
return $a > $b;
elseif (is_int($a))
return -1;
elseif (is_int($b))
return 1;
else
return strcasecmp($b, $a);
});
$settingsText = trim(strtr(file_get_contents($settingsFile), array("\r\n" => "\n", "\r" => "\n")));
if ($settingsText == '' || substr($settingsText, 0, 5) !== '<' . '?php')
{
if (file_exists(dirname($settingsFile) . '/Settings_bak.php'))
$settingsText = strtr(file_get_contents(dirname($settingsFile) . '/Settings_bak.php'), array("\r\n" => "\n", "\r" => "\n"));
if ($settingsText == '' || substr($settingsText, 0, 5) !== '<' . '?php' || substr($settingsText, -2) !== '?' . '>')
{
$settingsText = '<' . "?php\n";
foreach ($settings_defs as $var => $setting_def)
{
if (!empty($setting_def['text']) && strpos($substitutions[$var]['replacement'], $setting_def['text']) === false)
$substitutions[$var]['replacement'] = $setting_def['text'] . "\n" . $substitutions[$var]['replacement'];
$settingsText .= $substitutions[$var]['replacement'] . "\n";
}
$settingsText .= "\n\n?" . '>';
$rebuild = true;
}
}
if (preg_match_all('/<<<(\'?)(\w+)\'?\n(.*?)\n\2;$/m', $settingsText, $matches))
{
foreach ($matches[0] as $mkey => $heredoc)
{
if (!empty($matches[1][$mkey]))
$heredoc_replacements[$heredoc] = var_export($matches[3][$mkey], true) . ';';
else
$heredoc_replacements[$heredoc] = '"' . strtr(substr(var_export($matches[3][$mkey], true), 1, -1), array("\\'" => "'", '"' => '\"')) . '";';
}
$settingsText = strtr($settingsText, $heredoc_replacements);
}
$last_var = null;
$bare_settingsText = $settingsText;
$force_before_pathcode = array();
foreach ($substitutions as $var => $substitution)
{
$placeholders[$var] = $substitution['placeholder'];
if (!empty($substitution['placeholder']))
{
$simple_replacements[$substitution['placeholder']] = $substitution['replacement'];
}
elseif (!empty($substitution['replace_pattern']))
{
$replace_patterns[$var] = $substitution['replace_pattern'];
$replace_strings[$var] = $substitution['replacement'];
}
if (strpos($substitutions[$pathcode_var]['replacement'], '$' . $var . ' = ') !== false)
$force_before_pathcode[] = $var;
preg_match_all($substitution['search_pattern'], $bare_settingsText, $matches);
if ((is_string($var) || $var === $pathcode_var) && count($matches[0]) !== 1 && $substitution['replacement'] !== '')
{
if (count($matches[0]) > 1)
{
if (is_string($var))
{
$sp = substr($substitution['search_pattern'], 1);
if (strpos($sp, '(?<=^|\s)') === 0)
$sp = substr($sp, 9);
if (strpos($sp, '^') === 0 || strpos($sp, '(?<') === 0)
return false;
$sp = '~(?:^|//[^\n]+c\n|\*/|[;}]|' . implode('|', array_filter($placeholders)) . ')\s*' . (strpos($sp, '\K') === false ? '\K' : '') . $sp;
preg_match_all($sp, $settingsText, $matches);
}
else
$sp = $substitution['search_pattern'];
if (count($matches[0]) > 0)
{
if (count($matches[0]) > 1)
$settingsText = preg_replace($sp, '', $settingsText, count($matches[0]) - 1);
$settingsText = preg_replace($sp, $substitution['placeholder'], $settingsText, 1);
}
else
{
unset($substitutions[$var], $new_settings_vars[$var], $settings_defs[$var], $simple_replacements[$substitution['placeholder']], $replace_patterns[$var], $replace_strings[$var]);
continue;
}
}
elseif (count($matches[0]) === 0)
{
$found = false;
$in_c = in_array($var, array_keys($config_vars));
$in_s = in_array($var, array_keys($settings_vars));
if (!preg_match('~(^|\s)\$' . preg_quote($var, '~') . '\s*=\s*~', $bare_settingsText))
{
if ($in_s)
unset($substitutions[$var], $settings_defs[$var]);
elseif ($in_c)
$new_settings_vars[$var] = $config_vars[$var];
continue;
}
foreach (array('scalar', 'object', 'array') as $type)
{
if ($type == 'scalar')
$sp = '(?:' . (implode('|', array_diff_key($type_regex, array($in_c ? gettype($config_vars[$var]) : ($in_s ? gettype($settings_vars[$var]) : PHP_INT_MAX) => '', 'array' => '', 'object' => '')))) . ')';
elseif ($type == 'object')
{
if (strpos($settingsText, '__set_state') === false)
continue;
$sp = $type_regex['object'];
}
else
$sp = $type_regex['array'];
if (preg_match('~(^|\s)\$' . preg_quote($var, '~') . '\s*=\s*' . $sp . '~', $bare_settingsText, $derp))
{
$settingsText = preg_replace('~(^|\s)\$' . preg_quote($var, '~') . '\s*=\s*' . $sp . '~', $substitution['placeholder'], $settingsText);
$found = true;
break;
}
}
if (!$found)
{
unset($substitutions[$var], $new_settings_vars[$var], $settings_defs[$var], $simple_replacements[$substitution['placeholder']], $replace_patterns[$var], $replace_strings[$var]);
continue;
}
}
}
else
$settingsText = preg_replace($substitution['search_pattern'], $substitution['placeholder'], $settingsText);
if (is_int($last_var) && is_string($var))
$bare_settingsText = strip_php_comments($settingsText);
$last_var = $var;
}
if (!empty($rebuild))
{
$settingsText = str_replace(array($substitutions[-1]['placeholder'], $substitutions[-2]['placeholder']), '', $settingsText);
foreach ($settings_defs as $var => $setting_def)
{
if (isset($setting_def['text']))
$settingsText = strtr($settingsText, array($setting_def['text'] . "\n" => '', $setting_def['text'] => '',));
}
$bare_settingsText = strip_php_comments($settingsText);
foreach ($placeholders as $placeholder)
{
$bare_settingsText = str_replace(array($placeholder . "\n\n", $placeholder), $placeholder . "\n", $bare_settingsText);
}
$bare_settingsText = preg_replace('/\h+$/m', '', rtrim($bare_settingsText));
$sections = array(array());
$section_num = 0;
$trimmed_placeholders = array_filter(array_map('trim', $placeholders));
$newsection_placeholders = array();
$all_custom_content = '';
foreach ($substitutions as $var => $substitution)
{
if (is_int($var) && ($var === -2 || $var > 0) && isset($trimmed_placeholders[$var]) && strpos($bare_settingsText, $trimmed_placeholders[$var]) !== false)
$newsection_placeholders[$var] = $trimmed_placeholders[$var];
}
foreach (preg_split('~(?<=' . implode('|', $trimmed_placeholders) . ')|(?=' . implode('|', $trimmed_placeholders) . ')~', $bare_settingsText) as $part)
{
$part = trim($part);
if (empty($part))
continue;
if (in_array($part, $trimmed_placeholders) && !in_array($part, $newsection_placeholders))
{
$sections[$section_num][] = $part;
}
else
{
if (!empty($sections[$section_num]))
++$section_num;
$sections[$section_num][] = $part;
++$section_num;
if (!in_array($part, $trimmed_placeholders))
$all_custom_content .= "\n" . $part;
}
}
$new_settingsText = '';
$done_defs = array();
$sectionkeys = array_keys($sections);
foreach ($sections as $sectionkey => $section)
{
if (count($section) === 1 && !in_array($section[0], $trimmed_placeholders))
{
$prev_section_end = $sectionkey < 1 ? 0 : strpos($settingsText, end($sections[$sectionkey - 1])) + strlen(end($sections[$sectionkey - 1]));
$next_section_start = $sectionkey == end($sectionkeys) ? strlen($settingsText) : strpos($settingsText, $sections[$sectionkey + 1][0]);
$new_settingsText .= "\n" . substr($settingsText, $prev_section_end, $next_section_start - $prev_section_end) . "\n";
}
else
{
$section_parts = array_flip($section);
$pathcode_reached = false;
foreach ($settings_defs as $var => $setting_def)
{
if ($var === $pathcode_var)
$pathcode_reached = true;
if (in_array($var, $done_defs))
continue;
if (isset($newsection_placeholders[$var]) && count($section) !== 1)
break;
if (empty($section_parts) && $sectionkey < (count($sections) - 1))
break;
$p = trim($substitutions[$var]['placeholder']);
if ($p === '')
continue;
if (strpos($new_settingsText, trim($substitutions[$pathcode_var]['placeholder'])) !== false && in_array($var, $force_before_pathcode))
{
$new_settingsText = strtr($new_settingsText, array($substitutions[$pathcode_var]['placeholder'] => $p . "\n" . $substitutions[$pathcode_var]['placeholder']));
$bare_settingsText .= "\n" . $substitutions[$var]['placeholder'];
$done_defs[] = $var;
unset($section_parts[trim($substitutions[$var]['placeholder'])]);
}
elseif (in_array($p, $section))
{
$new_settingsText .= "\n" . $substitutions[$var]['placeholder'];
$done_defs[] = $var;
unset($section_parts[trim($substitutions[$var]['placeholder'])]);
}
elseif (is_string($var) && strpos($new_settingsText, $p) === false && strpos($all_custom_content, '$' . $var) === false)
{
$new_settingsText .= "\n" . $substitutions[$var]['placeholder'];
$done_defs[] = $var;
unset($section_parts[trim($substitutions[$var]['placeholder'])]);
}
elseif (strpos($bare_settingsText, $p) === false)
{
if (!isset($newsection_placeholders[$pathcode_var]) && $pathcode_reached === true && $sectionkey < (count($sections) - 1))
break;
$new_settingsText .= "\n" . $substitutions[$var]['placeholder'];
$bare_settingsText .= "\n" . $substitutions[$var]['placeholder'];
$done_defs[] = $var;
unset($section_parts[trim($substitutions[$var]['placeholder'])]);
}
}
}
}
$settingsText = $new_settingsText;
foreach (array(-1, -2) as $var)
{
if (!empty($substitutions[$var]['placeholder']) && strpos($settingsText, $substitutions[$var]['placeholder']) === false);
{
$settingsText = ($var == -1 ? $substitutions[$var]['placeholder'] : '') . $settingsText . ($var == -2 ? $substitutions[$var]['placeholder'] : '');
}
}
}
else
{
$pathcode_pos = strpos($settingsText, $substitutions[$pathcode_var]['placeholder']);
if ($pathcode_pos !== false)
{
foreach ($force_before_pathcode as $var)
{
if (!empty($substitutions[$var]['placeholder']) && strpos($settingsText, $substitutions[$var]['placeholder']) > $pathcode_pos)
{
$settingsText = strtr($settingsText, array(
$substitutions[$var]['placeholder'] => '',
$substitutions[$pathcode_var]['placeholder'] => $substitutions[$var]['placeholder'] . "\n" . $substitutions[$pathcode_var]['placeholder'],
));
}
}
}
}
$settingsText = strtr($settingsText, $simple_replacements);
if (!empty($replace_patterns))
$settingsText = preg_replace($replace_patterns, $replace_strings, $settingsText);
if (strpos($settingsText, $substitutions[$pathcode_var]['replacement']) === false)
$settingsText = preg_replace('~(?=\n#+ Error.Catching #+)~', "\n" . $substitutions[$pathcode_var]['replacement'] . "\n", $settingsText);
if (empty($rebuild))
{
$bare_settingsText = $settingsText;
foreach ($substitutions as $var => $substitution)
{
if (!is_int($var))
break;
if (isset($substitution['replacement']))
$bare_settingsText = str_replace($substitution['replacement'], '', $bare_settingsText);
}
$bare_settingsText = strip_php_comments($bare_settingsText);
$pathcode_reached = false;
foreach ($settings_defs as $var => $setting_def)
{
if ($var === $pathcode_var)
$pathcode_reached = true;
if (is_int($var))
continue;
if (preg_match($substitutions[$var]['search_pattern'], $bare_settingsText))
continue;
if (!$pathcode_reached || in_array($var, $force_before_pathcode))
{
$settingsText = preg_replace($substitutions[$pathcode_var]['search_pattern'], $substitutions[$var]['replacement'] . "\n$0", $settingsText);
}
else
{
$settingsText = preg_replace($substitutions[$pathcode_var]['search_pattern'], "$0\n" . $substitutions[$var]['replacement'], $settingsText);
}
}
}
foreach ($new_settings_vars as $var => $val)
{
if (isset($substitutions[$var]) && !preg_match($substitutions[$var]['search_pattern'], $settingsText))
{
if (!isset($settings_defs[$var]) && strpos($settingsText, '# Custom Settings #') === false)
$settingsText = preg_replace('~(?=\n#+ Error.Catching #+)~', "\n\n######### Custom Settings #########\n", $settingsText);
$settingsText = preg_replace('~(?=\n#+ Error.Catching #+)~', $substitutions[$var]['replacement'] . "\n", $settingsText);
}
}
$settingsText = preg_replace('~\n\s*\n~', "\n\n", $settingsText);
$temp_sfile = tempnam(sys_get_temp_dir(), md5($prefix . 'Settings.php'));
file_put_contents($temp_sfile, $settingsText);
$result = get_current_settings(filemtime($temp_sfile), $temp_sfile);
unlink($temp_sfile);
if ($result === false)
return empty($rebuild) ? updateSettingsFile($config_vars, $keep_quotes, true) : false;
$success = safe_file_write($settingsFile, $settingsText, dirname($settingsFile) . '/Settings_bak.php', $last_settings_change);
$mtime = filemtime($settingsFile);
return $success;
}
function get_current_settings($mtime = null, $settingsFile = null)
{
$mtime = is_null($mtime) ? (defined('TIME_START') ? TIME_START : $_SERVER['REQUEST_TIME']) : (int) $mtime;
if (!is_file($settingsFile))
{
foreach (get_included_files() as $settingsFile)
if (basename($settingsFile) === 'Settings.php')
break;
if (basename($settingsFile) !== 'Settings.php')
return false;
}
clearstatcache();
if (filemtime($settingsFile) > $mtime)
return false;
$settingsText = trim(file_get_contents($settingsFile));
if (substr($settingsText, 0, 5) == '<' . '?php')
$settingsText = substr($settingsText, 5);
if (substr($settingsText, -2) == '?' . '>')
$settingsText = substr($settingsText, 0, -2);
$settingsText = strtr($settingsText, array(
'__FILE__' => var_export($settingsFile, true),
'__DIR__' => var_export(dirname($settingsFile), true),
));
$settingsText = preg_replace_callback(
'~\bdefine\s*\(\s*(["\'])(\w+)\1~',
function ($matches)
{
return 'define(\'' . md5(mt_rand()) . '\'';
},
$settingsText
);
try
{
if($settingsText !== '' && @eval($settingsText) === false)
throw new ErrorException('eval error');
unset($mtime, $settingsFile, $settingsText);
$defined_vars = get_defined_vars();
}
catch (Throwable $e) {}
catch (ErrorException $e) {}
if (isset($e))
return false;
return $defined_vars;
}
function safe_file_write($file, $data, $backup_file = null, $mtime = null, $append = false)
{
global $cachedir;
if (!file_exists($file) && !is_dir(dirname($file)))
return false;
if (!is_int($mtime))
$mtime = $_SERVER['REQUEST_TIME'];
$temp_dir = is_dir(@realpath($cachedir)) ? $cachedir : sys_get_temp_dir();
$temp_sfile = tempnam($temp_dir, pathinfo($file, PATHINFO_FILENAME) . '.');
if (!empty($backup_file))
$temp_bfile = tempnam($temp_dir, pathinfo($backup_file, PATHINFO_FILENAME) . '.');
$failed = false;
foreach (array($file, $backup_file) as $sf)
{
if (empty($sf))
continue;
if (!file_exists($sf))
touch($sf);
elseif (!is_file($sf))
$failed = true;
if (!$failed)
$failed = !smf_chmod($sf);
}
if (!$failed && disk_free_space(dirname($file)) < (strlen($data) + filesize($file) + (!empty($backup_file) ? filesize($backup_file) : 0)))
$failed = true;
if (!$failed && file_put_contents($temp_sfile, $data, LOCK_EX) !== strlen($data))
$failed = true;
if (!$failed)
{
if (file_exists($backup_file))
$temp_bfile_saved = @copy($backup_file, $temp_bfile);
clearstatcache();
if (filemtime($file) <= $mtime)
{
$sfhandle = @fopen($file, 'c');
if ($sfhandle !== false)
{
flock($sfhandle, LOCK_EX);
$temp_sfile_saved = @copy($file, $temp_sfile);
if ($temp_sfile_saved)
{
if (empty($append))
{
ftruncate($sfhandle, 0);
rewind($sfhandle);
}
$failed = fwrite($sfhandle, $data) !== strlen($data);
}
else
$failed = true;
if ($failed)
{
if (!empty($temp_sfile_saved))
@rename($temp_sfile, $file);
if (!empty($temp_bfile_saved))
@rename($temp_bfile, $backup_file);
}
elseif (!empty($backup_file))
@rename($temp_sfile, $backup_file);
flock($sfhandle, LOCK_UN);
fclose($sfhandle);
}
}
}
@unlink($temp_sfile);
@unlink($temp_bfile);
if ($failed)
return false;
if (function_exists('opcache_invalidate'))
opcache_invalidate($file, true);
return true;
}
function smf_var_export($var)
{
if (is_array($var))
{
$return = array();
foreach ($var as $key => $value)
$return[] = var_export($key, true) . ' => ' . smf_var_export($value);
return 'array(' . implode(', ', $return) . ')';
}
elseif (is_string($var) && (strpos($var, "\n") !== false || strpos($var, "\r") !== false))
{
return strtr(preg_replace_callback('/[\r\n]+/', function($m) {
return '\' . "' . strtr($m[0], array("\r" => '\r', "\n" => '\n')) . '" . \'';
}, $var), array("'' . " => '', " . ''" => ''));
}
elseif (in_array(gettype($var), array('boolean', 'NULL')))
return strtolower(var_export($var, true));
else
return var_export($var, true);
};
function strip_php_comments($code_str, $line_ending = null)
{
if (!in_array($line_ending, array("\r", "\n", "\r\n")))
{
if (strpos($code_str, "\r\n") !== false)
$line_ending = "\r\n";
elseif (strpos($code_str, "\n") !== false)
$line_ending = "\n";
elseif (strpos($code_str, "\r") !== false)
$line_ending = "\r";
}
if (preg_match_all('/<<<(\'?)(\w+)\'?'. $line_ending . '(.*?)'. $line_ending . '\2;$/m', $code_str, $matches))
{
foreach ($matches[0] as $mkey => $heredoc)
{
if (!empty($matches[1][$mkey]))
$heredoc_replacements[$heredoc] = var_export($matches[3][$mkey], true) . ';';
else
$heredoc_replacements[$heredoc] = '"' . strtr(substr(var_export($matches[3][$mkey], true), 1, -1), array("\\'" => "'", '"' => '\"')) . '";';
}
$code_str = strtr($code_str, $heredoc_replacements);
}
$parts = preg_split('~(?=#+|/(?=/|\*)|\*/|'. $line_ending . '|(?<!\\\)[\'"])~m', $code_str);
$in_string = 0;
$in_comment = 0;
foreach ($parts as $partkey => $part)
{
$one_char = substr($part, 0, 1);
$two_char = substr($part, 0, 2);
$to_remove = 0;
if ($one_char == "'")
{
if (!empty($in_comment))
$in_string = 0;
elseif (in_array($in_string, array(0, 1)))
$in_string = ($in_string ^ 1);
}
elseif ($one_char == '"')
{
if (!empty($in_comment))
$in_string = 0;
elseif (in_array($in_string, array(0, 2)))
$in_string = ($in_string ^ 2);
}
elseif ($one_char == '#' || $two_char == '//')
{
$in_comment = !empty($in_string) ? 0 : (empty($in_comment) ? 1 : $in_comment);
}
elseif (($line_ending === "\r\n" && $two_char === $line_ending) || $one_char == $line_ending)
{
if ($in_comment == 1)
{
$in_comment = 0;
if ($parts[$partkey - 1] === $line_ending)
$to_remove = strlen($line_ending);
}
}
elseif ($two_char == '/*')
{
$in_comment = !empty($in_string) ? 0 : (empty($in_comment) ? 2 : $in_comment);
}
elseif ($two_char == '*/')
{
if ($in_comment == 2)
{
$in_comment = 0;
$to_remove = 2;
}
}
if (empty($in_comment))
$parts[$partkey] = strlen($part) > $to_remove ? substr($part, $to_remove) : '';
else
$parts[$partkey] = '';
}
return implode('', $parts);
}
function updateDbLastError($time)
{
global $boarddir, $cachedir;
if (!empty($cachedir) && is_writable($cachedir))
$errorfile = $cachedir . '/db_last_error.php';
elseif (file_exists(dirname(__DIR__) . '/cache'))
$errorfile = dirname(__DIR__) . '/cache/db_last_error.php';
else
$errorfile = dirname(__DIR__) . '/db_last_error.php';
file_put_contents($errorfile, '<' . '?' . "php\n" . '$db_last_error = ' . $time . ';' . "\n" . '?' . '>', LOCK_EX);
@touch($boarddir . '/' . 'Settings.php');
}
function updateAdminPreferences()
{
global $options, $context, $smcFunc, $settings, $user_info;
if (!isset($context['admin_preferences']))
return false;
$options['admin_preferences'] = $smcFunc['json_encode']($context['admin_preferences']);
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}themes
WHERE id_theme != {int:default_theme}
AND variable = {string:admin_preferences}',
array(
'default_theme' => 1,
'admin_preferences' => 'admin_preferences',
)
);
$smcFunc['db_insert']('replace',
'{db_prefix}themes',
array('id_member' => 'int', 'id_theme' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'),
array($user_info['id'], 1, 'admin_preferences', $options['admin_preferences']),
array('id_member', 'id_theme', 'variable')
);
cache_put_data('theme_settings-' . $settings['theme_id'] . ':' . $user_info['id'], null, 0);
}
function emailAdmins($template, $replacements = array(), $additional_recipients = array())
{
global $smcFunc, $sourcedir, $language, $modSettings;
require_once($sourcedir . '/Subs-Post.php');
require_once($sourcedir . '/Subs-Members.php');
$members = membersAllowedTo('admin_forum');
require_once($sourcedir . '/Subs-Notify.php');
$prefs = getNotifyPrefs($members, 'announcements', true);
$request = $smcFunc['db_query']('', '
SELECT id_member, member_name, real_name, lngfile, email_address
FROM {db_prefix}members
WHERE id_member IN({array_int:members})',
array(
'members' => $members,
)
);
$emails_sent = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (empty($prefs[$row['id_member']]['announcements']))
continue;
$replacements['IDMEMBER'] = $row['id_member'];
$replacements['REALNAME'] = $row['member_name'];
$replacements['USERNAME'] = $row['real_name'];
$emaildata = loadEmailTemplate($template, $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']);
sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], null, $template, $emaildata['is_html'], 1);
$emails_sent[] = $row['email_address'];
}
$smcFunc['db_free_result']($request);
if (!empty($additional_recipients))
foreach ($additional_recipients as $recipient)
{
if (in_array($recipient['email'], $emails_sent))
continue;
$replacements['IDMEMBER'] = $recipient['id'];
$replacements['REALNAME'] = $recipient['name'];
$replacements['USERNAME'] = $recipient['name'];
$emaildata = loadEmailTemplate($template, $replacements, empty($recipient['lang']) || empty($modSettings['userLanguage']) ? $language : $recipient['lang']);
sendmail($recipient['email'], $emaildata['subject'], $emaildata['body'], null, $template, $emaildata['is_html'], 1);
}
}
?>