Compare commits
	
		
			430 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 5ca10f5439 | ||
|   | 75bfc2cdb0 | ||
|   | e542e8a7ce | ||
|   | fcfe5b0dbd | ||
|   | 149e10261b | ||
|   | 5726c9fa94 | ||
|   | 26b2c472cc | ||
|   | 76440a37d0 | ||
|   | 335b7b3112 | ||
|   | ddc13b110e | ||
|   | 02918684fd | ||
|   | 5bc70beae6 | ||
|   | 6418b782a3 | ||
|   | 687ccc4559 | ||
|   | 29a198bfce | ||
|   | 06a235237d | ||
|   | 9c15c2fa68 | ||
|   | 1708a48186 | ||
|   | 68170e42cd | ||
|   | 4b9a7eaf85 | ||
|   | 01dda11a2f | ||
|   | 1d33750e85 | ||
|   | 89f537c8c2 | ||
|   | 727da8b0cc | ||
|   | 5b6f29741d | ||
|   | e13bd879db | ||
|   | f696f74a06 | ||
|   | 3b18e400c0 | ||
|   | d1c72b3240 | ||
|   | 7abc3c7833 | ||
|   | c0c4fe33e9 | ||
|   | 05827b7861 | ||
|   | c304a9ab43 | ||
|   | d390ea325e | ||
|   | 37ba9c7366 | ||
|   | 7c3ebf70fa | ||
|   | eda773cb55 | ||
|   | c5c266b023 | ||
|   | 9483cfaad8 | ||
|   | b4ed68dfd7 | ||
|   | 39b19ed4c8 | ||
|   | 580b888b1d | ||
|   | 19d3e15c11 | ||
|   | 5a68d204bb | ||
|   | e09fe51774 | ||
|   | b2c9eb4745 | ||
|   | d96787ec21 | ||
|   | 5df5c64e4f | ||
|   | 3c4b19743f | ||
|   | 0e25ce553c | ||
|   | 2e4bbeb7f7 | ||
|   | cb6640343b | ||
|   | 4658d1cb29 | ||
|   | b25feaadf6 | ||
|   | 2693db5f6f | ||
|   | 8195b44061 | ||
|   | 035d0c1012 | ||
|   | 5a953ce901 | ||
|   | 01660bd2b4 | ||
|   | 5b858c521a | ||
|   | d1c5a189c3 | ||
|   | de1bb37bcb | ||
|   | e0036a3e32 | ||
|   | 7f4737631d | ||
|   | 317505bf19 | ||
|   | 55b8645d3f | ||
|   | ffb8f0879b | ||
|   | 79f5614dce | ||
|   | 2c347d0eac | ||
|   | d40178104b | ||
|   | 55543ee881 | ||
|   | d39386cfab | ||
|   | b5bbae62b0 | ||
|   | 71ef30d35e | ||
|   | 263c7bed07 | ||
|   | 1458b7a412 | ||
|   | 3e00c52128 | ||
|   | d73aceb272 | ||
|   | 1c55d4a220 | ||
|   | 1edf8833c8 | ||
|   | 0ffc5f68b4 | ||
|   | 81b6652738 | ||
|   | e5b4d2c6b3 | ||
|   | da1830371f | ||
|   | 6ba04967ed | ||
|   | f503e140f3 | ||
|   | f875f3cd20 | ||
|   | 72632c7b45 | ||
|   | 1f2e7bd72d | ||
|   | 016138ab55 | ||
|   | 77efb80a12 | ||
|   | 02eea950e4 | ||
|   | 2793c41655 | ||
|   | 62d3c198d5 | ||
|   | ef62b53cec | ||
|   | 7181b988e9 | ||
|   | 8b0b123f42 | ||
|   | f98332c698 | ||
|   | b1660bf27a | ||
|   | 191ad25eb2 | ||
|   | 7469be6efb | ||
|   | 47a3bfd265 | ||
|   | 5ae0be2323 | ||
|   | 42154d55a0 | ||
|   | 9dcc08ee6e | ||
|   | ba537b42bb | ||
|   | 9c318f9012 | ||
|   | a88103a956 | ||
|   | e26e6f3a1c | ||
|   | 08d67a07e0 | ||
|   | 6e9a89cb2e | ||
|   | e3aa3d4031 | ||
|   | 156a68f8bd | ||
|   | 6a28da5d33 | ||
|   | ee32384dca | ||
|   | 19afd73e8a | ||
|   | eead6a2975 | ||
|   | 11b11dd3ee | ||
|   | 483155cf4c | ||
|   | 55dbade8d5 | ||
|   | d1bc63d07a | ||
|   | 83a91ec540 | ||
|   | 7b43c972dd | ||
|   | 3fdf1d3f44 | ||
|   | 764db0c203 | ||
|   | 538076bc45 | ||
|   | 4327b66f91 | ||
|   | 3f27724569 | ||
|   | 9c0c2bbece | ||
|   | 946144016b | ||
|   | 5c3b01aca4 | ||
|   | 50983a2b85 | ||
|   | 765886f0c7 | ||
|   | 8ea78a5852 | ||
|   | 063cbab93e | ||
|   | f1670f4012 | ||
|   | 6fcf0f7117 | ||
|   | 7a07763625 | ||
|   | 8d2172a649 | ||
|   | b8f65207b6 | ||
|   | ea675afe86 | ||
|   | cc1cebf359 | ||
|   | 1e874c7027 | ||
|   | a338fd967c | ||
|   | 8796ff7e72 | ||
|   | a8172a518f | ||
|   | 559c2c7bd2 | ||
|   | 7a546e5a41 | ||
|   | 5f7a9154b7 | ||
|   | 0d52978d9f | ||
|   | df48363ea4 | ||
|   | 34725e0257 | ||
|   | df321154f6 | ||
|   | f2a3ec1185 | ||
|   | ce4aed0f17 | ||
|   | d0c82f6fb0 | ||
|   | 89b76e721d | ||
|   | 6091290efe | ||
|   | e4c4990e7f | ||
|   | 4f1235bfe9 | ||
|   | bf9d440a95 | ||
|   | 59a149c253 | ||
|   | 563099f290 | ||
|   | 3732bf988d | ||
|   | ab964fa1de | ||
|   | b5c694224e | ||
|   | 23810345f6 | ||
|   | b574a29331 | ||
|   | 6593e32d83 | ||
|   | b09adc836d | ||
|   | dcf9a45974 | ||
|   | 21258313ef | ||
|   | f851fa3845 | ||
|   | 2fdd507902 | ||
|   | b850e56ff1 | ||
|   | 8d10082179 | ||
|   | 996ae625c9 | ||
|   | 467f7ef927 | ||
|   | fa015b8d39 | ||
|   | 4b4864561c | ||
|   | 475cea8549 | ||
|   | 760214fdbd | ||
|   | 9c5dcd7b19 | ||
|   | 720e400f7c | ||
|   | c261c6ba48 | ||
|   | 933d4e1d6f | ||
|   | 1d08833726 | ||
|   | 7cfca55e3c | ||
|   | 7e13b62b8f | ||
|   | 5ccfcd541e | ||
|   | ba4d2a9c48 | ||
|   | 7a61f613ec | ||
|   | 073d9da0bc | ||
|   | e081a67589 | ||
|   | 37a27b8065 | ||
|   | d34f7eb2fc | ||
|   | f6c080cb5c | ||
|   | a983fd03b1 | ||
|   | 5b651886a5 | ||
|   | 6484ab75d9 | ||
|   | becad18465 | ||
|   | ec7e5a8838 | ||
|   | 300c1b4ebc | ||
|   | 4f0dd89eb9 | ||
|   | 79f7c3dbd4 | ||
|   | f24fc75b12 | ||
|   | 4fcc71e127 | ||
|   | 403b4aa89b | ||
|   | 613bcf379b | ||
|   | 8f2cc2ca38 | ||
|   | cdae11226d | ||
|   | 79fd97ad78 | ||
|   | b477d4c821 | ||
|   | 289f82ad23 | ||
|   | 92569b7965 | ||
|   | c03b041f40 | ||
|   | 2ac8ed7411 | ||
|   | 3280b3b9df | ||
|   | 05c37b94bb | ||
|   | a91e7226dc | ||
|   | a39600efe2 | ||
|   | 4fd5922784 | ||
|   | b3d1274ffe | ||
|   | 9de49b4b6a | ||
|   | e6a368c3ac | ||
|   | 3dca1b519a | ||
|   | ae8af396f4 | ||
|   | 38294420d5 | ||
|   | c0dee61add | ||
|   | a84c92e007 | ||
|   | 60a854e5fd | ||
|   | fa9f7aab7c | ||
|   | d697a556c2 | ||
|   | 802fd831cb | ||
|   | 52ca8a844a | ||
|   | 573fc819d3 | ||
|   | ead9d79cb1 | ||
|   | 43c197316a | ||
|   | c318d3a9de | ||
|   | 80d3f5ffe8 | ||
|   | f9d85b10b7 | ||
|   | 4028a58adc | ||
|   | 0a3a079b86 | ||
|   | d691148c84 | ||
|   | 48f74b9c7a | ||
|   | 99338afacb | ||
|   | 301c3b86e2 | ||
|   | 130f7ba405 | ||
|   | e552bcfe82 | ||
|   | ad75499a91 | ||
|   | 7ddcb441c8 | ||
|   | 99da8dbec1 | ||
|   | 743d5164b3 | ||
|   | 1f7dfdca50 | ||
|   | 2164d59331 | ||
|   | 0d845b764b | ||
|   | 0a2cd69a4b | ||
|   | ddb60fa1e0 | ||
|   | b7e33c5e6d | ||
|   | 095ff7963d | ||
|   | dfb8be07f0 | ||
|   | 74b4d98bba | ||
|   | 8a7e4f0132 | ||
|   | 6ebdb0ba89 | ||
|   | 33817e5ab1 | ||
|   | cd1b481de5 | ||
|   | ab99db62bd | ||
|   | dd3d6b3f47 | ||
|   | d99f507244 | ||
|   | b6c8a0923f | ||
|   | 0663b3bbf4 | ||
|   | d683fce2b9 | ||
|   | 3d56214c07 | ||
|   | e2575c3612 | ||
|   | 084256ce01 | ||
|   | 240be18367 | ||
|   | ac271839a6 | ||
|   | 734a63f6c3 | ||
|   | e73daedd42 | ||
|   | 802e6c228c | ||
|   | edf2004539 | ||
|   | 9e949eb32a | ||
|   | e255c35002 | ||
|   | dfd3c2c4a5 | ||
|   | 876543f064 | ||
|   | e10f82e0e9 | ||
|   | f496a48a4d | ||
|   | 1fbb7c373e | ||
|   | d58d7f79e7 | ||
|   | 0643c56bc5 | ||
|   | c51acf9dbd | ||
|   | 2f2a326eac | ||
|   | 10dad0fb4e | ||
|   | fe01070bd1 | ||
|   | b558109844 | ||
|   | ac37802b7a | ||
|   | f9c8027c3f | ||
|   | 28dd1969b3 | ||
|   | 50270f6d6f | ||
|   | fad80307d8 | ||
|   | 323d1b0504 | ||
|   | d6c1232d2d | ||
|   | 678d719036 | ||
|   | 723e81e90e | ||
|   | 60d2cfea99 | ||
|   | 84c39676ee | ||
|   | a11d038c1d | ||
|   | 2f627bf4b0 | ||
|   | 67c603ef94 | ||
|   | dec63f353f | ||
|   | 7ab6b026fb | ||
|   | a2a773d714 | ||
|   | aa26a71949 | ||
|   | e3c695175b | ||
|   | ccdcdd01d8 | ||
|   | ef2a408298 | ||
|   | 6a4dbcef62 | ||
|   | c8a87a2a8a | ||
|   | d0bfe93d38 | ||
|   | 75df8c5a6a | ||
|   | b55813e362 | ||
|   | 575f0c62b4 | ||
|   | 3e9544f1dc | ||
|   | 152e5ac70e | ||
|   | 3544643a07 | ||
|   | f7ae76d10f | ||
|   | add9370696 | ||
|   | cadc17cc52 | ||
|   | 878dfc5a01 | ||
|   | 2400f7c20a | ||
|   | 9d7854dda6 | ||
|   | 7303aabc2b | ||
|   | ab478f488a | ||
|   | c7a2b090d7 | ||
|   | f2c3b6362d | ||
|   | c664be7b74 | ||
|   | aa17ddbf24 | ||
|   | 62faacbed6 | ||
|   | d03d6e2ec1 | ||
|   | 93a1760263 | ||
|   | 0de8894e4d | ||
|   | e95ea22dbd | ||
|   | 5dbfde62a6 | ||
|   | 0ba886bc6b | ||
|   | 2684205b5a | ||
|   | 856507fb66 | ||
|   | d019fbc050 | ||
|   | 129d5653e6 | ||
|   | 9560ad0c20 | ||
|   | a4fa7567aa | ||
|   | 9ff032740c | ||
|   | dbc76abcdd | ||
|   | 746a5dc816 | ||
|   | 194d110079 | ||
|   | eed490507c | ||
|   | 2800ab1e88 | ||
|   | faf40f8bed | ||
|   | 3f12ee40ac | ||
|   | b4532bd473 | ||
|   | b389874a7e | ||
|   | ea2dc69f7c | ||
|   | b0593b0ae1 | ||
|   | 664348e475 | ||
|   | e3e00f0109 | ||
|   | d3850280f4 | ||
|   | d8b3b41358 | ||
|   | e7706cad74 | ||
|   | 727d6788fe | ||
|   | e3ecf8ec96 | ||
|   | 1999b19a1c | ||
|   | c55e2910ac | ||
|   | ad3694ef96 | ||
|   | 7fd784b2f6 | ||
|   | d8f0ac5880 | ||
|   | b4ee4de110 | ||
|   | b9713fea76 | ||
|   | c6dd937922 | ||
|   | 81d4158c03 | ||
|   | bf0e6ff862 | ||
|   | 8518afe70d | ||
|   | 091ab688e7 | ||
|   | 2e5b066d88 | ||
|   | cd3a15feab | ||
|   | 836499a48c | ||
|   | 4983816ff6 | ||
|   | 0326657d60 | ||
|   | fcff820858 | ||
|   | dc536f0fc0 | ||
|   | f958b8dd4f | ||
|   | 352d3b1bde | ||
|   | f3061a0e74 | ||
|   | d4222e98e6 | ||
|   | 8dd07d4873 | ||
|   | 5f891fb9d6 | ||
|   | b3b6d0ff5d | ||
|   | 0ac01b3f0d | ||
|   | c6e55edb09 | ||
|   | dfc70c098f | ||
|   | c1d1e9596a | ||
|   | 53078e046e | ||
|   | 2af968031c | ||
|   | bdd3c394a3 | ||
|   | f719b3c112 | ||
|   | 8e0001a635 | ||
|   | 5b3581b88e | ||
|   | ca1436ea3f | ||
|   | 5cd6b79ee0 | ||
|   | 0ec5942ee4 | ||
|   | 90af164a8a | ||
|   | fd83ee37ae | ||
|   | 8e935e62be | ||
|   | a0d38b1f36 | ||
|   | 6b49ecc99a | ||
|   | ae24a464dc | ||
|   | f519784cae | ||
|   | 601cbd5ab7 | ||
|   | fd4a507645 | ||
|   | bf8d07226e | ||
|   | fcddfb6adf | ||
|   | 5fcd97129e | ||
|   | af3a1c2f55 | ||
|   | 13584a4d96 | ||
|   | 6de4953d50 | ||
|   | b15c213890 | ||
|   | 2f52e5d9f3 | ||
|   | 1d6afea9c4 | ||
|   | 8d79efd6ad | ||
|   | 99bcd54afe | ||
|   | 6ce6eee529 | ||
|   | 054b40e358 | 
| @@ -11,9 +11,4 @@ insert_final_newline = true | |||||||
|  |  | ||||||
| [*.md] | [*.md] | ||||||
| trim_trailing_whitespace = false | trim_trailing_whitespace = false | ||||||
|  | indent_style = tab | ||||||
| [{composer.json,package.json}] |  | ||||||
| indent_style = space |  | ||||||
|  |  | ||||||
| [{package.json, *.yml}] |  | ||||||
| indent_size = 2 |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -3,11 +3,9 @@ | |||||||
| .gitignore export-ignore | .gitignore export-ignore | ||||||
| .github export-ignore | .github export-ignore | ||||||
| .editorconfig export-ignore | .editorconfig export-ignore | ||||||
|  | .travis.yml export-ignore | ||||||
| _config.yml export-ignore | _config.yml export-ignore | ||||||
| release.sh export-ignore | release.sh export-ignore | ||||||
|  |  | ||||||
| # cypress |  | ||||||
| cypress export-ignore |  | ||||||
| cypress.config.js export-ignore |  | ||||||
|  |  | ||||||
| *.sh text eol=lf | *.sh text eol=lf | ||||||
|  | VERSION text eol=lf | ||||||
|   | |||||||
							
								
								
									
										164
									
								
								.github/workflows/cypress.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,164 +0,0 @@ | |||||||
| name: Cypress |  | ||||||
| on: |  | ||||||
|   pull_request: |  | ||||||
|     branches: [main] |  | ||||||
|   push: |  | ||||||
|     branches: [main] |  | ||||||
|  |  | ||||||
| jobs: |  | ||||||
|   cypress: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     services: |  | ||||||
|       mysql: |  | ||||||
|         image: mysql:8.0 |  | ||||||
|         env: |  | ||||||
|           MYSQL_ROOT_PASSWORD: root |  | ||||||
|           MYSQL_DATABASE: myaac |  | ||||||
|           MYSQL_USER: myaac |  | ||||||
|           MYSQL_PASSWORD: myaac |  | ||||||
|         ports: |  | ||||||
|           - 3306/tcp |  | ||||||
|         options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 |  | ||||||
|     strategy: |  | ||||||
|       fail-fast: false |  | ||||||
|       matrix: |  | ||||||
|         php-versions: [ '8.1', '8.2', '8.3', '8.4' ] |  | ||||||
|         ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration) |  | ||||||
|     name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }}) |  | ||||||
|     steps: |  | ||||||
|         - name: 📌 MySQL Start & init & show db |  | ||||||
|           run: | |  | ||||||
|             sudo /etc/init.d/mysql start |  | ||||||
|             mysql -e 'CREATE DATABASE myaac;' -uroot -proot |  | ||||||
|             mysql -e "SHOW DATABASES" -uroot -proot |  | ||||||
|  |  | ||||||
|         - name: Checkout MyAAC |  | ||||||
|           uses: actions/checkout@v4 |  | ||||||
|           with: |  | ||||||
|             ref: main |  | ||||||
|  |  | ||||||
|         - uses: actions/setup-node@v4 |  | ||||||
|           with: |  | ||||||
|             node-version: 18 |  | ||||||
|         - run: npm ci |  | ||||||
|  |  | ||||||
|         - name: Checkout TFS |  | ||||||
|           uses: actions/checkout@v4 |  | ||||||
|           if: matrix.ots == 'tfs-1.4' |  | ||||||
|           with: |  | ||||||
|             repository: otland/forgottenserver |  | ||||||
|             ref: 1.4 |  | ||||||
|             path: ots |  | ||||||
|  |  | ||||||
|         - name: Checkout TFS |  | ||||||
|           uses: actions/checkout@v4 |  | ||||||
|           if: matrix.ots == 'tfs-master' |  | ||||||
|           with: |  | ||||||
|             repository: otland/forgottenserver |  | ||||||
|             ref: master |  | ||||||
|             path: ots |  | ||||||
|  |  | ||||||
|         - name: Checkout Canary |  | ||||||
|           uses: actions/checkout@v4 |  | ||||||
|           if: matrix.ots == 'canary-3.1.2' |  | ||||||
|           with: |  | ||||||
|             repository: opentibiabr/canary |  | ||||||
|             ref: v3.1.2 |  | ||||||
|             path: ots |  | ||||||
|  |  | ||||||
|         - name: Import OTS Schema |  | ||||||
|           run: | |  | ||||||
|               mysql -uroot -proot myaac < ots/schema.sql |  | ||||||
|  |  | ||||||
|         - name: Rename config.lua |  | ||||||
|           run: mv ots/config.lua.dist ots/config.lua |  | ||||||
|  |  | ||||||
|         - name: Replace mysqlUser (TFS 1.4) |  | ||||||
|           uses: jacobtomlinson/gha-find-replace@v3 |  | ||||||
|           if: matrix.ots == 'tfs-1.4' |  | ||||||
|           with: |  | ||||||
|             find: 'mysqlUser = "forgottenserver"' |  | ||||||
|             replace: 'mysqlUser = "root"' |  | ||||||
|             regex: false |  | ||||||
|             include: 'ots/config.lua' |  | ||||||
|  |  | ||||||
|         - name: Replace mysqlPass (TFS 1.4) |  | ||||||
|           uses: jacobtomlinson/gha-find-replace@v3 |  | ||||||
|           if: matrix.ots == 'tfs-1.4' |  | ||||||
|           with: |  | ||||||
|               find: 'mysqlPass = ""' |  | ||||||
|               replace: 'mysqlPass = "root"' |  | ||||||
|               regex: false |  | ||||||
|               include: 'ots/config.lua' |  | ||||||
|  |  | ||||||
|         - name: Replace mysqlDatabase (TFS 1.4) |  | ||||||
|           uses: jacobtomlinson/gha-find-replace@v3 |  | ||||||
|           if: matrix.ots == 'tfs-1.4' |  | ||||||
|           with: |  | ||||||
|               find: 'mysqlDatabase = "forgottenserver"' |  | ||||||
|               replace: 'mysqlDatabase = "myaac"' |  | ||||||
|               regex: false |  | ||||||
|               include: 'ots/config.lua' |  | ||||||
|  |  | ||||||
|         - name: Replace mysqlDatabase (Canary) |  | ||||||
|           uses: jacobtomlinson/gha-find-replace@v3 |  | ||||||
|           if: matrix.ots == 'canary-3.1.2' |  | ||||||
|           with: |  | ||||||
|               find: 'mysqlDatabase = "otservbr-global"' |  | ||||||
|               replace: 'mysqlDatabase = "myaac"' |  | ||||||
|               regex: false |  | ||||||
|               include: 'ots/config.lua' |  | ||||||
|  |  | ||||||
|         - name: Setup PHP |  | ||||||
|           uses: shivammathur/setup-php@v2 |  | ||||||
|           with: |  | ||||||
|             php-version: ${{ matrix.php-versions }} |  | ||||||
|             extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql |  | ||||||
|  |  | ||||||
|         - name: Get composer cache directory |  | ||||||
|           id: composer-cache |  | ||||||
|           run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT |  | ||||||
|  |  | ||||||
|         - name: Cache composer dependencies |  | ||||||
|           uses: actions/cache@v4 |  | ||||||
|           with: |  | ||||||
|             path: ${{ steps.composer-cache.outputs.dir }} |  | ||||||
|             # Use composer.json for key, if composer.lock is not committed. |  | ||||||
|             key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} |  | ||||||
|             #key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} |  | ||||||
|             restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} |  | ||||||
|  |  | ||||||
|         - name: Install Composer dependencies |  | ||||||
|           run: composer install --no-progress --prefer-dist --optimize-autoloader |  | ||||||
|  |  | ||||||
|         - name: Run PHP server |  | ||||||
|           run: nohup php -S localhost:8080 > php.log 2>&1 & |  | ||||||
|  |  | ||||||
|         - name: Cypress Run |  | ||||||
|           uses: cypress-io/github-action@v6 |  | ||||||
|           env: |  | ||||||
|             CYPRESS_URL: http://localhost:8080 |  | ||||||
|             CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/ots |  | ||||||
|  |  | ||||||
|         - name: Save screenshots |  | ||||||
|           uses: actions/upload-artifact@v4 |  | ||||||
|           if: always() |  | ||||||
|           with: |  | ||||||
|             name: cypress-screenshots-${{ matrix.php-versions }}-${{ matrix.ots }} |  | ||||||
|             path: cypress/screenshots |  | ||||||
|             if-no-files-found: ignore |  | ||||||
|  |  | ||||||
|         - name: Upload Cypress Videos |  | ||||||
|           uses: actions/upload-artifact@v4 |  | ||||||
|           if: always() |  | ||||||
|           with: |  | ||||||
|             name: cypress-videos-${{ matrix.php-versions }}-${{ matrix.ots }} |  | ||||||
|             path: cypress/videos |  | ||||||
|             if-no-files-found: ignore |  | ||||||
|  |  | ||||||
|         - name: Upload PHP Logs |  | ||||||
|           uses: actions/upload-artifact@v4 |  | ||||||
|           if: always() |  | ||||||
|           with: |  | ||||||
|             name: php-log-${{ matrix.php-versions }}-${{ matrix.ots }} |  | ||||||
|             path: php.log |  | ||||||
							
								
								
									
										8
									
								
								.github/workflows/phplint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,16 +1,16 @@ | |||||||
| name: PHP Linting | name: PHP Linting | ||||||
| on: | on: | ||||||
|   pull_request: |   pull_request: | ||||||
|     branches: [main] |     branches: [master] | ||||||
|   push: |   push: | ||||||
|     branches: [main] |     branches: [master] | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   phplint: |   phplint: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@v3 |       - uses: actions/checkout@v3 | ||||||
|       - uses: overtrue/phplint@8.2 |       - uses: overtrue/phplint@3.4.0 | ||||||
|         with: |         with: | ||||||
|           path: . |           path: . | ||||||
|           options: --exclude=*.log |           options: --exclude="system/libs/polyfill-mbstring/bootstrap80.php" | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								.github/workflows/phpstan.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,46 +0,0 @@ | |||||||
| name: "PHPStan" |  | ||||||
|  |  | ||||||
| on: |  | ||||||
|   pull_request: |  | ||||||
|     branches: [main] |  | ||||||
|   push: |  | ||||||
|     branches: [main] |  | ||||||
|  |  | ||||||
| jobs: |  | ||||||
|   tests: |  | ||||||
|     name: PhpStan on PHP ${{ matrix.php-versions }} |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|  |  | ||||||
|     strategy: |  | ||||||
|       fail-fast: false |  | ||||||
|       matrix: |  | ||||||
|         php-versions: [ '8.1', '8.2', '8.3', '8.4' ] |  | ||||||
|     steps: |  | ||||||
|       - name: "Checkout" |  | ||||||
|         uses: "actions/checkout@v4" |  | ||||||
|  |  | ||||||
|       - name: "Install PHP" |  | ||||||
|         uses: "shivammathur/setup-php@v2" |  | ||||||
|         with: |  | ||||||
|           coverage: "none" |  | ||||||
|           extensions: "intl, zip" |  | ||||||
|           ini-values: "memory_limit=-1" |  | ||||||
|           php-version: "${{ matrix.php-version }}" |  | ||||||
|  |  | ||||||
|       - name: Get composer cache directory |  | ||||||
|         id: composer-cache |  | ||||||
|         run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT |  | ||||||
|  |  | ||||||
|       - name: Cache composer dependencies |  | ||||||
|         uses: actions/cache@v4 |  | ||||||
|         with: |  | ||||||
|           path: ${{ steps.composer-cache.outputs.dir }} |  | ||||||
|           # Use composer.json for key, if composer.lock is not committed. |  | ||||||
|           key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} |  | ||||||
|           restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} |  | ||||||
|  |  | ||||||
|       - name: "Install composer dependencies" |  | ||||||
|         run: "composer install" |  | ||||||
|  |  | ||||||
|       - name: "Run PHPStan" |  | ||||||
|         run: "/usr/bin/php vendor/bin/phpstan analyse" |  | ||||||
							
								
								
									
										15
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -7,7 +7,7 @@ Thumbs.db | |||||||
| lua | lua | ||||||
|  |  | ||||||
| # composer | # composer | ||||||
| composer.phar | composer.lock | ||||||
| vendor | vendor | ||||||
|  |  | ||||||
| # npm | # npm | ||||||
| @@ -50,7 +50,10 @@ system/cache/* | |||||||
| !system/cache/twig/index.html | !system/cache/twig/index.html | ||||||
| !system/cache/signatures/index.html | !system/cache/signatures/index.html | ||||||
| !system/cache/plugins/index.html | !system/cache/plugins/index.html | ||||||
| !system/cache/persistent/index.html |  | ||||||
|  | # php sessions | ||||||
|  | system/php_sessions/* | ||||||
|  | !system/php_sessions/index.html | ||||||
|  |  | ||||||
| # logs | # logs | ||||||
| system/logs/* | system/logs/* | ||||||
| @@ -60,10 +63,6 @@ system/logs/* | |||||||
| system/data/* | system/data/* | ||||||
| !system/data/index.html | !system/data/index.html | ||||||
|  |  | ||||||
| # php sessions |  | ||||||
| system/php_sessions/* |  | ||||||
| !system/php_sessions/index.html |  | ||||||
|  |  | ||||||
| # plugins | # plugins | ||||||
| plugins/* | plugins/* | ||||||
| !plugins/.htaccess | !plugins/.htaccess | ||||||
| @@ -74,5 +73,5 @@ plugins/* | |||||||
| !plugins/email-confirmed-reward | !plugins/email-confirmed-reward | ||||||
| landing | landing | ||||||
|  |  | ||||||
| # system | # others/rest | ||||||
| system/functions_custom.php | system/pages/downloads.php | ||||||
|   | |||||||
| @@ -6,13 +6,11 @@ | |||||||
| 	Options -MultiViews | 	Options -MultiViews | ||||||
| </IfModule> | </IfModule> | ||||||
|  |  | ||||||
| <FilesMatch "^(.*\.md|.*\.json|.*\.dist|.*\.sql|CHANGELOG|README|composer\.lock)$"> |  | ||||||
| 	Require all denied |  | ||||||
| </FilesMatch> |  | ||||||
|  |  | ||||||
| <IfModule mod_rewrite.c> | <IfModule mod_rewrite.c> | ||||||
| 	RewriteEngine On | 	RewriteEngine On | ||||||
|  |  | ||||||
|  | 	# you can put here your myaac root folder | ||||||
|  | 	# path relative to web root | ||||||
|     #RewriteBase /myaac/ |     #RewriteBase /myaac/ | ||||||
|  |  | ||||||
| 	RewriteCond %{REQUEST_FILENAME} !-f | 	RewriteCond %{REQUEST_FILENAME} !-f | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,20 @@ | |||||||
|  |  | ||||||
|  | language: php | ||||||
|  | php: | ||||||
|  |   - 5.6 | ||||||
|  |   - 7.0 | ||||||
|  |   - 7.1 | ||||||
|  |   - 7.2 | ||||||
|  |   - 7.3 | ||||||
|  |   - 7.4 | ||||||
|  |   - 8.0 | ||||||
|  |  | ||||||
|  | cache: | ||||||
|  |   directories: | ||||||
|  |     - $HOME/.composer/cache | ||||||
|  |  | ||||||
|  | before_script: | ||||||
|  |   - composer require php-parallel-lint/php-parallel-lint --no-suggest --no-progress --no-interaction --no-ansi --quiet --optimize-autoloader | ||||||
|  |  | ||||||
|  | script: | ||||||
|  |   - php vendor/bin/parallel-lint --no-progress --no-colors --exclude vendor --exclude "system/libs/pot/OTS_DB_PDOQuery_PHP71.php" . | ||||||
							
								
								
									
										456
									
								
								CHANGELOG-1.x.md
									
									
									
									
									
								
							
							
						
						| @@ -1,456 +0,0 @@ | |||||||
| # Changelog |  | ||||||
|  |  | ||||||
| ## [1.8.4 - 27.10.2025] |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Reimport myaac_ tables on every install, this fixes errors when one table is missing or is duplicated (https://github.com/slawkens/myaac/commit/2580edadf84779f09fd395c21f92019b2c762f83) |  | ||||||
| * Use custom env init on migrate, migrate:run and migrate:to (https://github.com/slawkens/myaac/commit/13ea68cc0c9349380c8e4051d702a6c2c8256f44, https://github.com/slawkens/myaac/commit/07fd034fe4cb0ffdb88667b1e400f414d0c6d06f) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Show if there is mysql error on import schema (https://github.com/slawkens/myaac/commit/44110a9496b4385e42c31b75de301037e711b6c3) |  | ||||||
| * Fix the premium checks, introduced in v1.8.3 (https://github.com/slawkens/myaac/commit/9d92a11fb7cb6d7a1619d79c12faaa0b1c01f980) |  | ||||||
|  |  | ||||||
| ## [1.8.3 - 21.10.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Feature: resend email verify (https://github.com/slawkens/myaac/commit/fe821c58085483e70491dcf76376ad5b96de3fdd) |  | ||||||
| * New config: hooks_debug (To view where hooks are located in .twig files) (https://github.com/slawkens/myaac/commit/8c3cb0e06f9709c1de3398b48221241e7cbdd310) |  | ||||||
| * Functions: Add db->getColumnInfo(table, column) (https://github.com/slawkens/myaac/commit/c898fe25efff6793a01d11c26fc153cb23fcb858) |  | ||||||
| * Plugins: Add option to use ?subtopic=x for plugins pages (https://github.com/slawkens/myaac/commit/97f9d3d6f6c28aef6d824973058d7133f56e09c4) |  | ||||||
| * getTopPlayers() Function - Add lookmount & promotion (https://github.com/slawkens/myaac/commit/2da0024c68f1cedc38a16ebbc6f52ffa55e65f7a, https://github.com/slawkens/myaac/commit/901df48d134079d648a18f9d82b60182e818ac02) |  | ||||||
| * New hooks for account/change-password (https://github.com/slawkens/myaac/commit/470555f2687809a0c12491bbb27597e64b8929c1) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Feature: show vip days in account management (https://github.com/slawkens/myaac/commit/c88b08eb1ec1f560cbfdaaa16b24e3a0f26da7b3, by @andreoam) |  | ||||||
| * Allow links in error_box.html.twig (https://github.com/slawkens/myaac/commit/9acad15451071639acf7a7d4e81619b0a9742b12) |  | ||||||
| * Canary - Comment code to update lastday in login.php (https://github.com/slawkens/myaac/commit/38902c30d114fdbce259467f5820f97037b393e9) |  | ||||||
| * Cache::remember $ttl = -1 = infinite (https://github.com/slawkens/myaac/commit/64acf70d3854182d88aaf0b67f77cea2a254f179) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Online - Allow for html code (example - img) in online_datacenter (https://github.com/slawkens/myaac/commit/3bb272ebbbd2eb7769d174b7082061d14a17bd44) |  | ||||||
| * Guilds - Fix guild create with freePremium enabled (https://github.com/slawkens/myaac/commit/c91bb5d4097647dca2196d3dea87bc90c89181d2) |  | ||||||
| * Canary - Fix premDays count (https://github.com/slawkens/myaac/commit/3e61692780d4add93b7b0e9f12f7a283bd8f4b7a) |  | ||||||
| * Template Change: Ignore set last visit for AJAX pages - Fixes template change redirect (https://github.com/slawkens/myaac/commit/89fae38caa7e4f645957fcf1a9330a36358ac04f) |  | ||||||
| * Admin Panel - Accounts: Fix lastip v6 (TFS master) (https://github.com/slawkens/myaac/commit/f54b1bdd2af4c16c64ddff0e87a6c96bc4cf9eeb) |  | ||||||
| * Functions - Prevent injection in $db->hasColumn (https://github.com/slawkens/myaac/commit/56bd7ec5ed904666074492f2e4f13e4fce226bee) |  | ||||||
| * Compat Config: Add missing config: email_lai_sec_interval (https://github.com/slawkens/myaac/commit/2eae44e0755e624a91be68b4d1ec26d01eb4d9a1) |  | ||||||
|  |  | ||||||
| ## [1.8.2 - 26.09.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Routes: Possibility to override routes with plugins pages, like characters.php - No need to define routes in plugin.json anymore (https://github.com/slawkens/myaac/commit/3f24f961b1cdeff5c60387e837ae454448bc5e1b) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Style: Better look for myaac-table (https://github.com/slawkens/myaac/commit/a6032093b21e5bb3f0e75d2704da87d6dea6469d, https://github.com/slawkens/myaac/commit/5aa9bbf1c8e580d973ec82ac012489f8e7bc437e) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Install: Fix when config.local.php cannot be saved (https://github.com/slawkens/myaac/commit/4eab805d26d8c5562b29ed699769919d77dabced) |  | ||||||
| * Create Account: Fix an exception when email cannot be sent (https://github.com/slawkens/myaac/commit/d0112d1a67e8b854b65ad131f0375b79305df8d3) |  | ||||||
| * Login Page: Add missing csrf() - fix create account button (https://github.com/slawkens/myaac/commit/3c0cb53e17dd0b85394cfa0fdc9cf9ad8d4551df) |  | ||||||
| * tibiacom template: Fix account lost menu (https://github.com/slawkens/myaac/commit/ed9beaf2b6ca069e304e569c52e5b9188b58f05c) |  | ||||||
| * tibiacom template: Fix Menu div wrong tag/closing (#329) (https://github.com/slawkens/myaac/commit/85e7005fd3f0be51466151a3c122b96085fdfe68) |  | ||||||
| * tibiacom template: Replace firstChild with firstElementChild (Thanks to @un000000) (https://github.com/slawkens/myaac/commit/df7b6e29fb8875da97f431468c81ee99116271d9) |  | ||||||
|  |  | ||||||
| ## [1.8.1 - 05.09.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * New Commands: plugin:enable/disable/uninstall {plugin-name} (https://github.com/slawkens/myaac/commit/7a08f91d3fc0897c1ff76089ef3c649a2c6d2003, https://github.com/slawkens/myaac/commit/fec773ba4b740f35c0a3ef92ca8444a4c7d02082) |  | ||||||
| * Gifts: Added Transferable Coins to the store dropdown menu in the admin area (by @andreoam, #321) (https://github.com/slawkens/myaac/commit/42671c5c199dd9e91c774d8c9d30da9e12f1b695) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Commands: Allow settings to be changed/reset by plugin name (https://github.com/slawkens/myaac/commit/f8c4332e03e838d285ea0afb4b72b7c23e324d45, https://github.com/slawkens/myaac/commit/4b948e9510f7ba69d00f84d7fdaea8b3bf05b630) |  | ||||||
| * Templates: Menus should be saved for each template separately (https://github.com/slawkens/myaac/commit/482f4067b2a2e7513d9ba214274a361ffaf123d8) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Online: Fix skulls display (#320) (https://github.com/slawkens/myaac/commit/98073a110ae13f9592ec9d2c4d1d1aace87587a9) |  | ||||||
| * Online: Fix if there is no world_id in the server_record table (https://github.com/slawkens/myaac/commit/b6e1620f14c20eecfc9001a7d86dfb67942985c6) (Reported by @gesior in #318) |  | ||||||
| * tibiacom: some fixes to menus (https://github.com/slawkens/myaac/commit/20f99903ae80c74ad66c1cf5a5ea8d0b0fc2fd70, https://github.com/slawkens/myaac/commit/11dae90fa94fbbf47447017db5e5847c33d6aadf) |  | ||||||
| * Guilds: Fix for some servers that don't have guild_invites table (https://github.com/slawkens/myaac/commit/9725a3c2bdb7003f5cb48febb77604c31a9b805b) |  | ||||||
|  |  | ||||||
| ## [1.8 - 02.08.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Templates - Kathrine: Possibility to add custom menu categories (https://github.com/slawkens/myaac/commit/ec11c1402417c25980582467546d1c1e9bb8267f) |  | ||||||
| * Admin Panel - Accounts Editor: Add Coins Transferable (https://github.com/slawkens/myaac/commit/45d6047031c9c3a0e7e512dc5d15c75629aec5a2, https://github.com/slawkens/myaac/commit/bb097b69ce106500a49686d6f4fe604348eaa310) |  | ||||||
| * Highscores: |  | ||||||
|   * Revamped: (https://github.com/slawkens/myaac/commit/d8132d4d76e03d5aa0c042be426320655a601392) |  | ||||||
|     * Show real rank, if 2 or more players have the same skill, show them with same rank |  | ||||||
|     * New setting: highscores_online_status |  | ||||||
|     * Additional fields passed to twig: updatedAt, totalResults, page, baseLink |  | ||||||
|   * Add new Setting: Display Skills Box (https://github.com/slawkens/myaac/commit/36ca755243ef1c83f6ac87465b426d4d8d3b0bb9) |  | ||||||
| * Functions: Add getExperienceForLevel (level) (https://github.com/slawkens/myaac/commit/1566deb84a082176b8c683fda205d828bc38fbcc) |  | ||||||
| * Commands - cache:clear : Add warning about APCu clear in CLI (https://github.com/slawkens/myaac/commit/83f84172e02e8ea2ccb6dca29bc033e44c35aebc) |  | ||||||
| * Models - PlayerOnline: Add missing $fillable into model (https://github.com/slawkens/myaac/commit/43415cf35db1c1307f2684c1728693d65065ffff) |  | ||||||
| * Twig: add cache variable (https://github.com/slawkens/myaac/commit/0efe47ce71c4b364a9e96bc5a55b1655326ae6da) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * pages/online: add cache, resulting in 20x performance boost |  | ||||||
|   * (for an example server with 2k players) (https://github.com/slawkens/myaac/commit/c8363086015cbb6e8786c398c7b9ac3959a26ec4) |  | ||||||
| * Admin Bar: Move admin bar code into body_start place_holder (https://github.com/slawkens/myaac/commit/f17269e44ce9dd38447bd2e2a8e1bdb065d4161f) |  | ||||||
| * Cache::remember: $ttl = 0 means no cache (https://github.com/slawkens/myaac/commit/3b47e9df2f4051807c5ff87892f7fa3d348f9c55) |  | ||||||
| * Templates: Load config.ini with $process_sections set to true (https://github.com/slawkens/myaac/commit/a89f9a84847630eb75b4890fdcc8b7a7bfa6b8ac) |  | ||||||
| * Twig: Allow for timestamp as integer in the timeago twig function |  | ||||||
|   (https://github.com/slawkens/myaac/commit/34fead906ea13b9f09d7a3c41ed88109d34d386c) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Settings: Fixed two exceptions (https://github.com/slawkens/myaac/commit/6e5a4ff8c78ff5373aba091baa66cae029557643, https://github.com/slawkens/myaac/commit/20d69a641c0a933d14889a89da6d32f6a4bc6c7d) |  | ||||||
| * Models\Account + OTS_Account -> isPremium -> ignore config.freePremium (https://github.com/slawkens/myaac/commit/5271633bdbfbbfed0b1d59c403093ce6fc2b7d20) |  | ||||||
| * Admin Panel - Mailer: |  | ||||||
|   * Fix send to email link redirecting from accounts page (https://github.com/slawkens/myaac/commit/080cc2781f034c844af658229e495e9a47fd2298) |  | ||||||
|   * Option to send only to verified accounts - only if setting('core.account_mail_verify') enabled (https://github.com/slawkens/myaac/commit/cf7fd20452e863980045bb5d6012ec86c6e8e01f) |  | ||||||
|  |  | ||||||
| ### Internal |  | ||||||
| * Rewrite to use constants (account transferable coins) (https://github.com/slawkens/myaac/commit/bccf8e056df985bbe1bab5f7ab5492f714d6b62b) |  | ||||||
| * Refactor to use HAS_ACCOUNT_COINS (https://github.com/slawkens/myaac/commit/caf326a6584a234775ebc6c8000ea02b3fecd160) |  | ||||||
|  |  | ||||||
| ## [1.7.1 - 27.06.2025] |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Rename plugin:install:install to plugin:setup, also add alias to previous command (https://github.com/slawkens/myaac/commit/13d33822b59df349199e885a78a3d6beb0863d0b) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fix commands: setup + cache:clear (https://github.com/slawkens/myaac/commit/0da524fefe93b3028392e9014550eea3324d3a22, https://github.com/slawkens/myaac/commit/fe8281594e989f00280ba1adc734a9198c6b5cc1) |  | ||||||
| * Fix polls link in tibiacom template (https://github.com/slawkens/myaac/commit/d90fa323d7c77d81768df60feeb1c374b1650a0c) |  | ||||||
|  |  | ||||||
| ## [1.7 - 22.06.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Feature: plugins versions check (#310) |  | ||||||
| * New hooks: HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS, HOOK_GUILDS_AFTER_MANAGE_BUTTON (https://github.com/slawkens/myaac/commit/c074a48f245df55646b6705737f667b6a84149b2, https://github.com/slawkens/myaac/commit/e6100a1b72de8695bba1dae9ba4e28bfdce47b10) |  | ||||||
| * Add OTS_Toolbox::getVocationName(id, promotion) + OTS_Player->isNameLocked() (https://github.com/slawkens/myaac/commit/e222957893c4a1de0dc8dbba55bce1a43418d275, https://github.com/slawkens/myaac/commit/522f6c11d835afd36fd07a07074d96d7e219b488) |  | ||||||
| * Add missing csrf in more places, causing white page with error about Request (https://github.com/slawkens/myaac/commit/dca904e61d21d856bf809070e7652803a2df0f58, https://github.com/slawkens/myaac/commit/c720ccc451ff90ef40b2a1595468d061ffd7e1e4) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Revamped online page (https://github.com/slawkens/myaac/commit/9a90e4aae280e607430511c6727d9a714b11f4c5, https://github.com/slawkens/myaac/commit/4767120043b09141870383e249f3729638d53dc2) |  | ||||||
| * Better $title inventing (https://github.com/slawkens/myaac/commit/0c95bcfd06b68b21512e477646ef7bd3a0d4912b) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Use apcu cache clear (https://github.com/slawkens/myaac/commit/b329da52aae9d0e21120a6444d3caf442420ce50, https://github.com/slawkens/myaac/commit/566c2a9151ab6392286f74e26853faa19a1b4f24) |  | ||||||
| * fix: boostedcreatures for 13.40 (by @GooseWithAKnife) (#307) |  | ||||||
|  |  | ||||||
| ## [1.6.1 - 11.06.2025] |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fixed "Request has been cancelled due to security reasons", cause of missing csrf() in twig files (https://github.com/slawkens/myaac/commit/10cd71a6630ffec91b43a26a6d685b66c5836a6a) |  | ||||||
| * Fix: Ignore duplicated route exception (https://github.com/slawkens/myaac/commit/9d8e9d27bd87167d8d4005942a6af62bfe4c0892) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Move counter & visitors code before router (In case someone wants to include that info on page) (https://github.com/slawkens/myaac/commit/f78285030708ad3c74ab048711f73bbf3ee5281e) |  | ||||||
| * Set TinyMCE license key to gpl (Avoid warning message in browser console) (https://github.com/slawkens/myaac/commit/8d29fdb98b92dbc3d2853ef88a185c67036b4a77) |  | ||||||
|  |  | ||||||
| ### Removed |  | ||||||
| * Remove deprecated TinyMCE plugin - template (https://github.com/slawkens/myaac/commit/309c1fb715b882e67cb673b1544a03befbf64a22) |  | ||||||
|  |  | ||||||
| ## [1.6 - 03.06.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Add new setting/configurable: site_url, prevents domain spoofing (https://github.com/slawkens/myaac/commit/d8a6090be382c35c19117cfef964b594ed02b8d4) |  | ||||||
| * Add new account coins setting (https://github.com/slawkens/myaac/commit/28886551e86fe562172c4c7f2afb89a2e7672c2e) |  | ||||||
| * autoload: settings/install/init.php (https://github.com/slawkens/myaac/commit/e5749437074c3b3556628a2aeb5bad2edf97bde0, https://github.com/slawkens/myaac/commit/7d213f479a7e40c6254069b5fc4e578dc32bf8d9, https://github.com/slawkens/myaac/commit/207d6bc69120aba1af2b51808f17e0059b571fed) |  | ||||||
| * Protect against csrf in more places (accounts & guilds & forums pages) (https://github.com/slawkens/myaac/commit/6eda38603c8ed7e99b92a78a4600b1245377f74d, https://github.com/slawkens/myaac/commit/e776bd52beb3064a9e694efd1b9021ec972ee2f6, https://github.com/slawkens/myaac/commit/84d502bf105f2a789481fba1acc820d236b4de66) |  | ||||||
| * Added two new hooks for pages loaded from database (custom pages): HOOK_BEFORE_PAGE_CUSTOM, HOOK_AFTER_PAGE_CUSTOM (https://github.com/slawkens/myaac/commit/c961a1ebf837f2ab1734a825ff2c57b4937610c9) |  | ||||||
| * Add global variables into $hooks->executeFilter (https://github.com/slawkens/myaac/commit/8fdea943768b20193eede99d60313ee84511a0be) |  | ||||||
| * Add getNPCsCount() to OTS_InfoRespond (https://github.com/slawkens/myaac/commit/7d435ff6433ef1fb2295ee79ed043ee10dc725e9) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Allow [] in character name (https://github.com/slawkens/myaac/commit/de6603a51347b9e656c58637ed9971fffdd7cedd) |  | ||||||
| * Do not allow access to tools/ folder after install (https://github.com/slawkens/myaac/commit/6e0f5913831f8dba69fd2d1505be3e2a303c6324) |  | ||||||
| * Fix CHANGELOG-1.x.md loading in admin panel (https://github.com/slawkens/myaac/commit/4a30fb495dbfbe1d434e8d52419eaf44fe517aee) |  | ||||||
| * Fix links not working in admin dashboard modules (https://github.com/slawkens/myaac/commit/be7b27c31aa3bbd6c0289c34d1e61139a3fe015c) |  | ||||||
| * Fix twig variables: logged + account_logged being not set directly after login (https://github.com/slawkens/myaac/commit/1e9b10d6489c488cadf7f6ed17b42f1ea6c767a8) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * OTS_ServerInfo -> move setTimeout out of class - Possibility to use the class without MyAAC (https://github.com/slawkens/myaac/commit/40d65a6613149fda51bdceb82c807e5301a3388b) |  | ||||||
|  |  | ||||||
| ## [1.5 - 14.05.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Feature/twig hooks filters (#258) |  | ||||||
| * Add latest client versions (14.00 - 15.01) (https://github.com/slawkens/myaac/commit/5367df23812c6182863353c9a39fd7fb0b743f4b) |  | ||||||
| * db variable to twig (https://github.com/slawkens/myaac/commit/5ed1aec28e146b871a75597411d12e42a067f4e6) |  | ||||||
| * New filter: HOOK_FILTER_ROUTES (https://github.com/slawkens/myaac/commit/9b75011224f385db8b27e109bfeb28e75b9d779c) |  | ||||||
| * Allow optionally separate folder for views (thanks @Scrollog for idea) (https://github.com/slawkens/myaac/commit/03e275213901a89edb0ebb8974b776a992ab391f) |  | ||||||
| * Add float & double types to the Settings (https://github.com/slawkens/myaac/commit/67ab425bb9796d9d123296e3fda542fa8f7f05ee) |  | ||||||
| * Add optional param _page_only for single-page apps etc. (https://github.com/slawkens/myaac/commit/113473f2560aab6d364c301cc14a8b5ba8f309f4) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Change OTS_Account->getPremDays to not return -1 in case of freePremium (https://github.com/slawkens/myaac/commit/3befde2a1e4d24a011311e785f15185db57e19b8) |  | ||||||
| * Add note about highscores being updated x minutes + allow ttl 0 to disable cache (https://github.com/slawkens/myaac/commit/a161cff00329da6f970f3a70967fe8346fe92bbc) |  | ||||||
| * Better monster images (no image not found anymore) + use cache (https://github.com/slawkens/myaac/commit/73a5829974ceca3f02d7925d5cfbd5fa50b1bbd2) |  | ||||||
| * Rename server-info -> ots-info, changelog -> change-log (Due to conflict with apache2 server-info mod) (https://github.com/slawkens/myaac/commit/3949d84e5d7631f332111b6d00278bddbd0ad10a) |  | ||||||
| * Move rules page to admin panel (https://github.com/slawkens/myaac/commit/3949d84e5d7631f332111b6d00278bddbd0ad10a) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * php 8.4 warnings |  | ||||||
| * Visitors counter not working properly on dev mode (https://github.com/slawkens/myaac/commit/da151051186c913dd0dd091aabe893649c2b9ee7) |  | ||||||
| * Fix login.php boosted creature & boss (not sure exact version, but should be 14.12 or around) (https://github.com/slawkens/myaac/commit/c48b8006319f6c3b5f082befd16785420bb98110) |  | ||||||
| * Fix installMenus when theme/template was removed from disc (https://github.com/slawkens/myaac/commit/c24c580796bccd54bf9e95b864763f4642684d55) |  | ||||||
| * Fix if user removes the menu category (https://github.com/slawkens/myaac/commit/dbea69f31478391dacfbbc02c8353c39b4245daf) |  | ||||||
|  |  | ||||||
| ### Updated: |  | ||||||
| * Update cypress from version ^13.17.0 to ^14.3.3 (https://github.com/slawkens/myaac/commit/629fd18ea166860d5898a822f44f9277da6ce43d) |  | ||||||
|  |  | ||||||
| ## [1.4 - 22.04.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * feat: admin-pages (can add admin pages through plugins) (https://github.com/slawkens/myaac/commit/ceaa0639e66d31e8177ff90791463470367aa45d) |  | ||||||
| 	* just place the page in admin-pages folder in the plugin |  | ||||||
| 	* Also, possibility to overwrite default myaac admin pages |  | ||||||
| * Add db->hasTableAndColumns(table, columns), credits to @opentibiabr Team (https://github.com/slawkens/myaac/commit/82a533d88c8a342076891d132b4b409ed9a1fe72) |  | ||||||
| * Add noSubmit option to buttons.base (https://github.com/slawkens/myaac/commit/64f6d3abcada3bf9fd7599f50d2fac0a1367f383) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fix: display 404 error instead of 500 when page has been removed from filesystem (https://github.com/slawkens/myaac/commit/c2bf94fb2370d2009a2eb907f818955132cf8611) |  | ||||||
| * Fix headline.php: change image format to .png cause of black background (https://github.com/slawkens/myaac/commit/b618084d50918539d9a70abd97e764137b966067) |  | ||||||
| * Clear cache on plugin enable/disable, fixes some issues with plugin pages being cached (https://github.com/slawkens/myaac/commit/1d0c173e7d000aecbd432800941fc3e38a0e50f2) |  | ||||||
| * Do not autoload sub-folders if autoload pages is disabled (https://github.com/slawkens/myaac/commit/d47195a7878095336f9c9edc6f96244257f67eec) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * SQL Syntax Standardization (by @JoaozinhoBrasil, #298) |  | ||||||
| * Pages in theme/template folder will now have precedence over normal pages (https://github.com/slawkens/myaac/commit/6d8f4718a1d349fba8f0ebc39cfd3a1a84d104b0) |  | ||||||
| * Small changes in account.login.html.twig (https://github.com/slawkens/myaac/commit/f40b986b59d4c8fa89ab4745731bf366f8619976) |  | ||||||
| * Plugin name is required, version is optional (https://github.com/slawkens/myaac/commit/e6f05a2731c61d931be49e121c068e49c0ad5e01) |  | ||||||
|  |  | ||||||
| ## [1.3.3 - 04.04.2025] |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fix uninstall plugin when plugin is disabled (https://github.com/slawkens/myaac/commit/6c568fd36a271270684fc412ccd556b230273a6d) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Display more useful info when error parsing config.lua (https://github.com/slawkens/myaac/commit/fa6b6aa153ffc131e0d1631a4dcd9012a5850c2e) |  | ||||||
|  |  | ||||||
| ### Other |  | ||||||
| * Small adjustments (https://github.com/slawkens/myaac/commit/35e2483de86e295bdf089cceffa25842eeb2e34c, https://github.com/slawkens/myaac/commit/ae639d65b0bfa491e747e907e2ebc77f83f47981) |  | ||||||
|  |  | ||||||
| ## [1.3.2 - 01.04.2025] |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fix debugBar/admin panel menu when using custom base_dir (https://github.com/slawkens/myaac/commit/65696f63e3aac02ff952ea81279e7cb2fa7570fb) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Settings: Show/hide IP Ban Protection options depending on the value (enabled/disabled) (https://github.com/slawkens/myaac/commit/dbf73d0b61b45601ae95e51b23c051c2704169c5) |  | ||||||
| * Do not require init.php in cache:clear command (https://github.com/slawkens/myaac/commit/d25c71857f767834239bbffacd00fdc671adb157) |  | ||||||
|  |  | ||||||
| ## [1.3.1 - 19.03.2025] |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fixed migrate:run command (https://github.com/slawkens/myaac/commit/1a5771ad51e595fe13368a0721b059c4ecefb17d) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Small adjustments (https://github.com/slawkens/myaac/commit/6fac883659f581baac1361826d046410156f1e58, https://github.com/slawkens/myaac/commit/4a6896b4469968b9904292734cf6c14ba5eeef14) |  | ||||||
|  |  | ||||||
| ## [1.3 - 10.03.2025] |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Use latest outfit-images host from @gesior (https://github.com/slawkens/myaac/commit/529bdcf016dd0f9dffbc34d81f99a046a9ddb70d) |  | ||||||
| * Change monster link to $_GET ?name= (https://github.com/slawkens/myaac/commit/4c5cc8b573b2b3e7ec00a22b7ede30a68083a924) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Fixed house links (https://github.com/slawkens/myaac/commit/887b5068ad11c4cdab614afd34525caba785ce13) |  | ||||||
| * Fixed long title on headline.php (https://github.com/slawkens/myaac/commit/3e3f4bb5a514158ec8777684ca6c7f1c2a37bed5) |  | ||||||
| * Fixed menu colors once again, plus add !important tag (https://github.com/slawkens/myaac/commit/aa52df6e2ec92cafc25b655ae907bf2e1746d9cc) |  | ||||||
| * Fix: add possibility to remove all menu items in admin panel (https://github.com/slawkens/myaac/commit/00fe1adc15ea7646596d755f6e6e1f7854ffc1d5, https://github.com/slawkens/myaac/commit/9239a4f4198c3ad260802ac3b47e9c41b80b754e) |  | ||||||
|  |  | ||||||
| ## [1.2 - 09.02.2025] |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Twig session(key) function + reworked session functions to accept multi-array like in Laravel (https://github.com/slawkens/myaac/commit/b46ddb43d03ef7e5fc34e555e92e856bdc905691) |  | ||||||
| * add template_name to twig variables (https://github.com/slawkens/myaac/commit/ae1161d77050bda181802b4496c9de920a7bb1bc) |  | ||||||
| * add HOOK_INIT, executed just after $hooks are loaded (https://github.com/slawkens/myaac/commit/19686725dc810f63a07f049f82c66cf336d90ca6) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * settings: password input hide/show, enable Save button only if changes has been made, save settings in transaction (https://github.com/slawkens/myaac/commit/4fda4f643b60a151179e5dd4f04912fb2618d98f, https://github.com/slawkens/myaac/commit/28fef952f857b79d64bc7495ffa5e1999e68e192, https://github.com/slawkens/myaac/commit/4b6024dc451accadb6c469fa282a9a764c1c0a81) |  | ||||||
| * rework menus: Different categories can have different colors + Option to reset menus (https://github.com/slawkens/myaac/commit/73de93a561f6b13111e019075724357d8a617249, https://github.com/slawkens/myaac/commit/3da3e62c5b12390d75de9b3320729bcca6e0b458) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * highscores: Fix online status + vocation for TFS 0.x (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0) |  | ||||||
| * clear cache button in admin bar needed to be clicked twice until it worked (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0) |  | ||||||
| * HOOK_STARTUP location (https://github.com/slawkens/myaac/commit/a73fb1003ee3f812cf182d1834d65f08e6f60d1f) |  | ||||||
| * if vocation name has more words (https://github.com/slawkens/myaac/commit/9d7fc98e1e0a96b59ecc1a7c39800a64445db364) |  | ||||||
|  |  | ||||||
| ### Updated |  | ||||||
| * Bump twig/twig from 3.18.0 to 3.19.0 (#284) |  | ||||||
|  |  | ||||||
| ## [1.1 - 27.01.2025] |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * adjust mailer settings descriptions to latest gmail (https://github.com/slawkens/myaac/commit/c5d5bb80671db135e6b503f53684771c7272e05d) |  | ||||||
| * optimize $player->isOnline() function, thanks @gesior (https://github.com/slawkens/myaac/commit/10dd818b139d5e1bb1ca9ec81edfb083ba9316b4) |  | ||||||
| * make players.comment and guilds.description VARCHAR (https://github.com/slawkens/myaac/commit/a45ceab83a74bee2b89cdb72baceda75e577e3cf) |  | ||||||
| * add lua/ folder to .gitignore (https://github.com/slawkens/myaac/commit/07012f786b1114cb6ab2f064f82c645b136a375a) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * general fixes in the tibiacom template menus, better support for custom menus |  | ||||||
| * make functions_custom.php optional (https://github.com/slawkens/myaac/commit/dc2b5afd9980984e2b259c9fc99f2ade46f70a5a) |  | ||||||
| * error in CLI, where BASE_URL is not defined (https://github.com/slawkens/myaac/commit/4d749b881582f64b5a46196dbbb5ee8097127f03) |  | ||||||
| * hook ACCOUNT_LOGIN_BEFORE_ACCOUNT location (https://github.com/slawkens/myaac/commit/669c447fca8643ce56d9ef8c1374ec647c780998) |  | ||||||
|  |  | ||||||
| ## [1.0.1 - 14.01.2025] |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * tibiacom account & news menu links not auto expanding |  | ||||||
|  |  | ||||||
| ### Updated (Thanks dependabot) |  | ||||||
| * twig from ^2.0 to ^3.11 |  | ||||||
| * tinymce from ^6.8.3 to ^7.2.0 |  | ||||||
| * cypress from ^12.12.0 to ^13.17.0 |  | ||||||
| * nesbot/carbon from 2.72.5 to 2.72.6 |  | ||||||
|  |  | ||||||
| ## [1.0 - 12.01.2025] |  | ||||||
|  |  | ||||||
| First stable release in the v1.0 series. |  | ||||||
|  |  | ||||||
| Minimum PHP 8.1 is required. |  | ||||||
|  |  | ||||||
| Changes since RC.2: |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * feature: migrations up/down. Allows to downgrade/upgrade database to specified version (https://github.com/slawkens/myaac/commit/3f6ff3a3326b0475d28d11ffd7fff51f362d799f) |  | ||||||
| * new hooks for news management (https://github.com/slawkens/myaac/commit/011a85d8ae34283ded6999882833f9d4797028ec, https://github.com/slawkens/myaac/commit/36bd3eb846e829b45313e10f7568dc4e95841143) |  | ||||||
| * None Vocation to highscores (can be changed to RookStayer in Admin Panel) (https://github.com/slawkens/myaac/commit/a4a248099521bb5b8b2aa5bd592138debd2f19d5) |  | ||||||
| * support for button_color (green, red, blue) (https://github.com/slawkens/myaac/commit/d8b6b749ee62e88b6af4a05d3d7557f90b94d94e) |  | ||||||
| * add $whoopsHandler as variable, can be used by plugins (https://github.com/slawkens/myaac/commit/b0c8cf2ecda23045d725aaf43cfb3852ed766a4b) |  | ||||||
| * PlayerModel->outfit_url attribute (https://github.com/slawkens/myaac/commit/3b5be1a8db5dceecaa388e2925a5536d13b38881) |  | ||||||
| * support for selecting plugin themes in Admin menus.php (https://github.com/slawkens/myaac/commit/77a2c1cec343ffe4be5c2c2503ee81bc32a14ca1) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * schema: Change character set to utf8mb4 (support for Emojis in Menus/Pages/News/Forum etc.) (https://github.com/slawkens/myaac/commit/27c44f1bdfb6234cf0c9d5b4b491123bb205b08f) |  | ||||||
| * prefer get_browser_real_ip() over REMOTE_ADDR (https://github.com/slawkens/myaac/commit/941846605c00cee83168d2f916410b8ba8d4b7b9) |  | ||||||
| * automatically set selected current one on highscores filters (https://github.com/slawkens/myaac/commit/e96227fbe41ae281783b2d49edb169a603601813) |  | ||||||
| * rewrite towns loading code, removed OTBM loader (was too slow) (https://github.com/slawkens/myaac/commit/c980a0914632e7b27f718464f669a200707d217e) |  | ||||||
| * allow OTS_Player to be passed as object to getPlayerLink (https://github.com/slawkens/myaac/commit/84d37c5a8f2c4535a41c8aa8264752969d3f3a3d) |  | ||||||
| * do not clear menus by default on install (https://github.com/slawkens/myaac/commit/12d8faa3eda5e798f97b71e941c035187daad96e) |  | ||||||
| * display warning in admin panel - plugins - if zip extension is not installed (https://github.com/slawkens/myaac/commit/e3ffe5d9e11d78ab064a370d8541bac351c9bcd9) |  | ||||||
| * set default_socket_timeout for ipinfo.io checkup to 5 seconds (https://github.com/slawkens/myaac/commit/783d96fc6568a607d3198b832fed3a0dd06c4ebb) |  | ||||||
| * refactor getTopPlayers function (support for balance) (https://github.com/slawkens/myaac/commit/c769962e39fe8dfb72ecd5be1864e145696be794) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * XSS in forum (https://github.com/slawkens/myaac/commit/c2b7286d20d4b579171540f7a774e8a0995d5e8f, https://github.com/slawkens/myaac/commit/8fb643596f9586005976e7bdb484a541a9d8715e) |  | ||||||
| * price deducted when changing sex (https://github.com/slawkens/myaac/commit/16671ea40b72dcf74037c359ad572f9eb825edf9) |  | ||||||
| * move_thread by unauthorized user (https://github.com/slawkens/myaac/commit/d6c40c836a53cb1710f911f77f45f28b54ea1b54, thanks @anyeor) |  | ||||||
| * TFS 1.4.2 where conditions is NULL (https://github.com/slawkens/myaac/commit/b8396d4c8482e951da538b13f2296123732c4545) |  | ||||||
| * do not show forum new thread show button if not logged in (https://github.com/slawkens/myaac/commit/507402171ba3b6e7ee184bd7fa73e0d55e0cad7a, @anyeor) |  | ||||||
| * login if limiter is disabled (https://github.com/slawkens/myaac/commit/a0f1971583f0f790013e2145fb5ac573c59fbdef) |  | ||||||
| * fixes to installMenus function (https://github.com/slawkens/myaac/commit/a2fadc5945fe0a5e39f740827f6ffbda1bb501e2) |  | ||||||
| * many PHP exceptions in different places |  | ||||||
| * fixes to tibiacom menus ActiveSubmenuItem |  | ||||||
|  |  | ||||||
| ### Removed |  | ||||||
| * bugtracker SQL table code as the page has been removed/moved to plugins (https://github.com/slawkens/myaac/commit/5782772b901b05fb814bc718d062f6e2cd71df8c) |  | ||||||
|  |  | ||||||
| ## [1.0-RC.2 - 25.10.2024] |  | ||||||
|  |  | ||||||
| Still waiting for your reports about bugs found in this release. We are very close to stable release. |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * feat: rate limit settings for blocking accounts login attempts (@gpedro, #266) |  | ||||||
| * search by email in accounts editor (https://github.com/slawkens/myaac/commit/c2ec46824621468f2a1cb4046805c485ed13fea5) |  | ||||||
| * New hooks in account manage + create (https://github.com/slawkens/myaac/commit/93641fc68ac9a5f1479329e2bd41380c19534d5d) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * chore: drop raw queries + accounts - search by email + accounts - required min size for search by account number (@gpedro, #266) |  | ||||||
| * Use https for outfit & item images (https://github.com/slawkens/myaac/commit/71c00aa5e01fbdfd88802912e200dd1025976231) |  | ||||||
| * Do not require players & guilds tables on install (https://github.com/slawkens/myaac/commit/779aa152fa940261c9b161533946f44e288597a2) |  | ||||||
| * Do not create player if there is no players table in db (https://github.com/slawkens/myaac/commit/201f95caa8b70e88fa651eac8c3c3aa7cd765bd0) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Highscore frags fixed for TFS 0.3 (@Scrollog, #263) |  | ||||||
| * Missing groups variable #262. thanks, @Scrollog for reporting (https://github.com/slawkens/myaac/commit/8d8bdb6dac6df21672ac77288fff2f2f8d6eb665) |  | ||||||
| * Verified email for login.php (@gpedro, #265) |  | ||||||
| * Warning if core.account_country is disabled (https://github.com/slawkens/myaac/commit/ab73d60c61e14a1cacdb6cfbf7f89f4bf3be0833) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## [1.0-RC.1 - 23.07.2024] |  | ||||||
|  |  | ||||||
| Changes since 1.0-beta: |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * Feat: Hooks priority (https://github.com/slawkens/myaac/commit/dc17b701da053e04bfa64e21be9247a4f07505e1) |  | ||||||
| * Make autoload of pages, commands and themes configurable (https://github.com/slawkens/myaac/commit/c1d4b4f80cd6bb85507ee9471e47013955a26a91) |  | ||||||
| * Fraggers in characters page for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/42f99c3edc8de39cccc5632cb42e88b24579c5a6) |  | ||||||
| * New hooks: HOOK_INSTALL_FINISH, HOOK_ACCOUNT_CREATE_CHARACTER_* (https://github.com/slawkens/myaac/commit/08ac8ebade106521a5c7396faa5ce7006e629f7c, https://github.com/slawkens/myaac/commit/45dda5e834ff2059faea6ef9be2efa76f1723cbd) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Allow account_create_character_create even if account_mail_verify is activated (https://github.com/slawkens/myaac/commit/203e411b626fe62401a4b74a48420769e512aa39) |  | ||||||
| * Create guild_rank entries, in case MySQL trigger not loaded (https://github.com/slawkens/myaac/commit/d9c1b2507c81f306970642b35e4bf5f7cc04a6f2, https://github.com/slawkens/myaac/commit/47a19e85dd84e9f3b39a1b29cfc2c04b004832b9) |  | ||||||
| * Set Admin Account verified by default (https://github.com/slawkens/myaac/commit/cd49dfc79942f3301ce9c0b8d899b9f39bda9a41) |  | ||||||
| * Refactor account routes into sub folders (https://github.com/slawkens/myaac/commit/bdc0c43d3fd3a51030c3e916bdb9f008468f5ecd) |  | ||||||
| * Order towns by id (https://github.com/slawkens/myaac/commit/9ea2a5067fc4b75de395f381577b18914132ad84) |  | ||||||
| * Do not create news about myaac, if any news already exist (on installation (https://github.com/slawkens/myaac/commit/504242fb846b73b56b87bc1e39d070687ad7f5b4) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * Not working google recaptcha plugin (https://github.com/slawkens/myaac/commit/a1bcb217ecf4e21fd58da4ba491da1852029898a) |  | ||||||
| * Not working account create if account_country is disabled (https://github.com/slawkens/myaac/commit/933b681a9fcdbb6283e0469b3806d2ded492d232) |  | ||||||
| * Account verify - do not allow login without verified email (Thanks @anyeor, https://github.com/slawkens/myaac/commit/fcb13f3c0fb8ceafda0bd614a229a26a269432bd) |  | ||||||
| * Detect tools/ext exists on install to prevent broken installs (https://github.com/slawkens/myaac/commit/10a739773c4f2911876bc802a0ee0537c3e00a92) |  | ||||||
| * Cache reloading each time page refreshes (https://github.com/slawkens/myaac/commit/ec96985872057340112f65073efc0c4bf86dddb0) |  | ||||||
| * Highscores frags for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/a04d186c22912915f0a7873dfe677ef3b5a23c79) |  | ||||||
| * Monsters page: monster not found exception (https://github.com/slawkens/myaac/commit/ef79b99b8acc179f14b8475547347d9daca27512) |  | ||||||
| * Fixed bug if \<flags\> are not present in monster.xml (https://github.com/slawkens/myaac/commit/57b47ab7983f625c7c0ef4f5303a4d07ef172786) |  | ||||||
| * fastRoute duplicate errors (https://github.com/slawkens/myaac/commit/4c0739d3e93812dff0c33849ea3f38e4e49113ac) |  | ||||||
| * useGuildNick displaying (https://github.com/slawkens/myaac/commit/0db0ec1aa47e044c26bc403ff5078a2115d086f8) |  | ||||||
|  |  | ||||||
| ## [1.0-beta - 18.05.2024] |  | ||||||
|  |  | ||||||
| Minimum PHP version for this release is 8.1. |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * reworked Admin Panel (@Leesneaks, @gpedro, @slawkens) |  | ||||||
|   * updated to Bootstrap v4 |  | ||||||
|   * new Menu |  | ||||||
|   * new Dashboard: statistics, server status |  | ||||||
|   * new Admin Bar showed on top when admin logged in |  | ||||||
|   * new page: Server Data, to reload server data |  | ||||||
|     * Towns, NPCs & Items are stored in permanent cache |  | ||||||
|   * new pages: mass account & teleport tools |  | ||||||
|   * changelogs editor |  | ||||||
|   * revised Accounts & Players editors |  | ||||||
|   * option to add/modify admin menus with plugins |  | ||||||
|   * option to enable/disable plugins |  | ||||||
|   * better, updated TinyMCE editor (v6.x) |  | ||||||
|     * with option to upload images |  | ||||||
|   * list of open source libraries used in project page |  | ||||||
| * auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole. |  | ||||||
| * config.php moved to Admin Panel -> Settings page |  | ||||||
| * new console script: aac - using symfony/console |  | ||||||
|   * usage: `php aac` (will list all commands by default) |  | ||||||
|   * example: `php aac cache:clear` |  | ||||||
|   * example: `php aac plugin:install theme-example.zip` |  | ||||||
| * replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230) |  | ||||||
| * brand new charming installation page (by @fernandomatos) |  | ||||||
|   * using Bootstrap |  | ||||||
| * new pages router: nikic/fast-route, allowing for better customisation |  | ||||||
| * Plugin cronjobs: central control of the cronjobs |  | ||||||
| * Guild Wars support (available as plugin) |  | ||||||
| * support for login and create account only by email (configurable) |  | ||||||
|   * with no need for account name |  | ||||||
| * Google ReCAPTCHA v3 support (available as plugin) |  | ||||||
| * support for Account Number |  | ||||||
|   * suggest account number option |  | ||||||
| * many new functions, hooks and configurables |  | ||||||
| * better Exception Handler (Whoops - https://github.com/filp/whoops) |  | ||||||
| * automated website tests (using Cypress) |  | ||||||
| * csrf protection (https://github.com/slawkens/myaac/pull/235) |  | ||||||
| * option to restrict Page view to specified group of users (Not-Logged in, logged-in players, tutors, gamemasters etc.) |  | ||||||
| * phpdebug bar (http://phpdebugbar.com/). Activated if env == 'dev', can be also activated in production by enabling "enable_debugbar" in local config |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * Composer and NPM is now used for external libraries like: Twig, PHPMailer, fast-route, jQuery, Bootstrap etc. |  | ||||||
| * mail support is disabled on fresh install, can be manually enabled by user |  | ||||||
| * disable add php pages in admin panel for security. Option to disable plugins upload |  | ||||||
| * visitors counter shows now user browser, and also if its bot |  | ||||||
| * changes in required and optional PHP extensions |  | ||||||
| * reworked Pages: |  | ||||||
| 	* Bans |  | ||||||
| 		* works now for TFS 1.x |  | ||||||
| 	* Highscores |  | ||||||
| 		* frags works for TFS 1.x |  | ||||||
| 		* cached |  | ||||||
| 	* Monsters |  | ||||||
| * moved pages to Twig: |  | ||||||
|   * experience stages |  | ||||||
| * update player_deaths entries on name change |  | ||||||
| * change_password email to be more informal |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * hundreds of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here |  | ||||||
							
								
								
									
										1019
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -8,11 +8,7 @@ Fernando Matos <fernando@pixele.com.br> | |||||||
| Lee <42119604+Leesneaks@users.noreply.github.com> | Lee <42119604+Leesneaks@users.noreply.github.com> | ||||||
| caio <caio.zucoli@gmail.com> | caio <caio.zucoli@gmail.com> | ||||||
| slawkens <slawkens@gmail.com> | slawkens <slawkens@gmail.com> | ||||||
| tobi132 <tobi132@gmx.net> | tobi132 <52947952+tobi132@users.noreply.github.com> | ||||||
| vankk <nwtr.otland@hotmail.com> | vankk <nwtr.otland@hotmail.com> | ||||||
| whiteblXK <krzys16001@gmail.com> | whiteblXK <krzys16001@gmail.com> | ||||||
| xitobuh <jonas.hockert92@gmail.com> | xitobuh <jonas.hockert92@gmail.com> | ||||||
| Danilo Pucci <dnlps@hotmail.com> |  | ||||||
| gpedro <gpedro831@gmail.com> |  | ||||||
| Matheus Collier <matheuscollier@gmail.com> |  | ||||||
| SRNT-GG <95472530+SRNT-GG@users.noreply.github.com> |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								CREDITS
									
									
									
									
									
								
							
							
						
						| @@ -1,3 +1,3 @@ | |||||||
| * Gesior.pl (2007 - 2008) | * Gesior.pl (2007 - 2008) | ||||||
| * Slawkens (2009 - 2025) | * Slawkens (2009 - 2023) | ||||||
| * Contributors listed in CONTRIBUTORS.txt | * Contributors listed in CONTRIBUTORS.txt | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| # [MyAAC](https://my-aac.org) | # [MyAAC](https://my-aac.org) | ||||||
|  |  | ||||||
| MyAAC is a free and open-source Automatic Account Creator (AAC) for Open Tibia Servers written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases. | MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases. | ||||||
|  |  | ||||||
| Official website: https://my-aac.org | Official website: https://my-aac.org | ||||||
|  |  | ||||||
| @@ -80,7 +80,7 @@ Pull requests should be made to the *develop* branch as that is the working bran | |||||||
|  |  | ||||||
| Bug fixes to current release should be done to master branch. | Bug fixes to current release should be done to master branch. | ||||||
|  |  | ||||||
| Look: [Contributing](https://docs.my-aac.org/misc/contributing) in our wiki. | Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our wiki. | ||||||
|  |  | ||||||
| ### Other Notes | ### Other Notes | ||||||
|  |  | ||||||
| @@ -95,4 +95,4 @@ Many thanks to Jetbrains for kindly providing a license for me to work on this a | |||||||
| ### License | ### License | ||||||
|  |  | ||||||
| This program and all associated files are released under the GNU Public License.   | This program and all associated files are released under the GNU Public License.   | ||||||
| See [LICENSE](https://github.com/slawkens/myaac/blob/main/LICENSE) for details. | See [LICENSE](https://github.com/slawkens/myaac/blob/master/LICENSE) for details. | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								SECURITY.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,16 @@ | |||||||
|  | # Security Policy | ||||||
|  |  | ||||||
|  | ## Supported Versions | ||||||
|  |  | ||||||
|  | | Version | Supported          | | ||||||
|  | | ------- | ------------------ | | ||||||
|  | | 1.x.y   | :white_check_mark: | | ||||||
|  | | 0.9.x   | :x:                | | ||||||
|  | | 0.8.x   | :white_check_mark: | | ||||||
|  | | < 0.7   | :x:                | | ||||||
|  |  | ||||||
|  | ## Reporting a Vulnerability | ||||||
|  |  | ||||||
|  | If you found a security vulnerability, please write an email to security@my-aac.org | ||||||
|  |  | ||||||
|  | All reports will be taken very seriously, and a fix will be posted as soon as possible. | ||||||
							
								
								
									
										38
									
								
								aac
									
									
									
									
									
								
							
							
						
						| @@ -1,38 +0,0 @@ | |||||||
| #!/usr/bin/env php |  | ||||||
| <?php |  | ||||||
|  |  | ||||||
| require_once __DIR__ . '/common.php'; |  | ||||||
|  |  | ||||||
| if(!IS_CLI) { |  | ||||||
| 	echo 'This script can be run only in command line mode.'; |  | ||||||
| 	exit(1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| require_once SYSTEM . 'functions.php'; |  | ||||||
|  |  | ||||||
| define('SELF_NAME', basename(__FILE__)); |  | ||||||
|  |  | ||||||
| use MyAAC\Plugins; |  | ||||||
| use Symfony\Component\Console\Application; |  | ||||||
|  |  | ||||||
| $application = new Application('MyAAC', MYAAC_VERSION); |  | ||||||
|  |  | ||||||
| $commandsGlob = glob(SYSTEM . 'src/Commands/*.php'); |  | ||||||
| foreach ($commandsGlob as $item) { |  | ||||||
| 	$name = pathinfo($item, PATHINFO_FILENAME); |  | ||||||
| 	if ($name == 'Command') { // ignore base Command class |  | ||||||
| 		continue; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$commandPre = '\\MyAAC\Commands\\'; |  | ||||||
| 	if (!trait_exists($class = $commandPre . $name)) { |  | ||||||
| 		$application->add(new $class); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $pluginCommands = Plugins::getCommands(); |  | ||||||
| foreach ($pluginCommands as $item) { |  | ||||||
| 	$application->add(require $item); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $application->run(); |  | ||||||
| Before Width: | Height: | Size: 4.3 KiB | 
| @@ -1,22 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| $hooks->register('debugbar_admin_head_end', HOOK_ADMIN_HEAD_END, function ($params) { |  | ||||||
| 	global $debugBar; |  | ||||||
|  |  | ||||||
| 	if (!isset($debugBar)) { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$debugBarRenderer = $debugBar->getJavascriptRenderer(BASE_URL . 'vendor/maximebf/debugbar/src/DebugBar/Resources/'); |  | ||||||
| 	echo $debugBarRenderer->renderHead(); |  | ||||||
| }); |  | ||||||
| $hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($params) { |  | ||||||
| 	global $debugBar; |  | ||||||
|  |  | ||||||
| 	if (!isset($debugBar)) { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$debugBarRenderer = $debugBar->getJavascriptRenderer(BASE_URL . 'vendor/maximebf/debugbar/src/DebugBar/Resources/'); |  | ||||||
| 	echo $debugBarRenderer->render(); |  | ||||||
| }); |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| use MyAAC\Plugins; |  | ||||||
|  |  | ||||||
| $order = 10; |  | ||||||
|  |  | ||||||
| $settingsMenu = []; |  | ||||||
|  |  | ||||||
| $settingsMenu[] = [ |  | ||||||
| 	'name' => 'MyAAC', |  | ||||||
| 	'link' => 'settings&plugin=core', |  | ||||||
| 	'icon' => 'list', |  | ||||||
| 	'order' => $order, |  | ||||||
| ]; |  | ||||||
|  |  | ||||||
| foreach (Plugins::getAllPluginsSettings() as $setting) { |  | ||||||
| 	$file = BASE . $setting['settingsFilename']; |  | ||||||
| 	if (!file_exists($file)) { |  | ||||||
| 		warning('Plugin setting: ' . $file . ' - cannot be loaded.'); |  | ||||||
| 		continue; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$order += 10; |  | ||||||
|  |  | ||||||
| 	$settings = require $file; |  | ||||||
|  |  | ||||||
| 	$settingsMenu[] = [ |  | ||||||
| 		'name' => $settings['name'], |  | ||||||
| 		'link' => 'settings&plugin=' . $setting['pluginFilename'], |  | ||||||
| 		'icon' => 'list', |  | ||||||
| 		'order' => $order, |  | ||||||
| 	]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| unset($settings, $file, $order); |  | ||||||
|  |  | ||||||
| return $settingsMenu; |  | ||||||
| @@ -1,12 +1,13 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| // few things we'll need | // few things we'll need | ||||||
| use MyAAC\Plugins; |  | ||||||
|  |  | ||||||
| require '../common.php'; | require '../common.php'; | ||||||
|  |  | ||||||
| const ADMIN_PANEL = true; | define('ADMIN_PANEL', true); | ||||||
| const MYAAC_ADMIN = true; | define('MYAAC_ADMIN', true); | ||||||
|  |  | ||||||
|  | if(file_exists(BASE . 'config.local.php')) { | ||||||
|  | 	require_once BASE . 'config.local.php'; | ||||||
|  | } | ||||||
|  |  | ||||||
| if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed'])) | if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed'])) | ||||||
| { | { | ||||||
| @@ -17,8 +18,8 @@ if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['i | |||||||
| $content = ''; | $content = ''; | ||||||
|  |  | ||||||
| // validate page | // validate page | ||||||
| $page = $_GET['p'] ?? ''; | $page = isset($_GET['p']) ? $_GET['p'] : ''; | ||||||
| if(empty($page) || preg_match("/[^a-zA-Z0-9_\-\/.]/", $page)) | if(empty($page) || preg_match("/[^a-zA-Z0-9_\-]/", $page)) | ||||||
| 	$page = 'dashboard'; | 	$page = 'dashboard'; | ||||||
|  |  | ||||||
| $page = strtolower($page); | $page = strtolower($page); | ||||||
| @@ -27,49 +28,39 @@ define('PAGE', $page); | |||||||
| require SYSTEM . 'functions.php'; | require SYSTEM . 'functions.php'; | ||||||
| require SYSTEM . 'init.php'; | require SYSTEM . 'init.php'; | ||||||
|  |  | ||||||
| require __DIR__ . '/includes/debugbar.php'; | if(config('env') === 'dev') { | ||||||
|  | 	ini_set('display_errors', 1); | ||||||
|  | 	ini_set('display_startup_errors', 1); | ||||||
|  | 	error_reporting(E_ALL); | ||||||
|  | } | ||||||
|  |  | ||||||
| require SYSTEM . 'status.php'; | require SYSTEM . 'status.php'; | ||||||
| require SYSTEM . 'login.php'; | require SYSTEM . 'login.php'; | ||||||
| require __DIR__ . '/includes/functions.php'; | require SYSTEM . 'migrate.php'; | ||||||
|  | require ADMIN . 'includes/functions.php'; | ||||||
|  |  | ||||||
| $twig->addGlobal('config', $config); | $twig->addGlobal('config', $config); | ||||||
| $twig->addGlobal('status', $status); | $twig->addGlobal('status', $status); | ||||||
|  |  | ||||||
| if (ACTION == 'logout') { |  | ||||||
| 	require SYSTEM . 'logout.php'; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // if we're not logged in - show login box | // if we're not logged in - show login box | ||||||
| if(!$logged || !admin()) { | if(!$logged || !admin()) { | ||||||
| 	$page = 'login'; | 	$page = 'login'; | ||||||
| } | } | ||||||
|  |  | ||||||
| $pluginsAdminPages = Plugins::getAdminPages(); |  | ||||||
| if(isset($pluginsAdminPages[$page]) && file_exists(BASE . $pluginsAdminPages[$page])) { |  | ||||||
| 	$file = BASE . $pluginsAdminPages[$page]; |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| // include our page | // include our page | ||||||
| 	$file = __DIR__ . '/pages/' . $page . '.php'; | $file = ADMIN . 'pages/' . $page . '.php'; | ||||||
| if(!@file_exists($file)) { | if(!@file_exists($file)) { | ||||||
| 		if (str_contains($page, 'plugins/')) { |  | ||||||
| 			$file = BASE . $page; |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 	$page = '404'; | 	$page = '404'; | ||||||
| 	$file = SYSTEM . 'pages/404.php'; | 	$file = SYSTEM . 'pages/404.php'; | ||||||
| } | } | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ob_start(); | ob_start(); | ||||||
| if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) { | include($file); | ||||||
| 	require $file; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $content .= ob_get_contents(); | $content .= ob_get_contents(); | ||||||
| ob_end_clean(); | ob_end_clean(); | ||||||
|  |  | ||||||
| // template | // template | ||||||
| $template_path = 'template/'; | $template_path = 'template/'; | ||||||
| require __DIR__ . '/' . $template_path . 'template.php'; | require ADMIN . $template_path . 'template.php'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,33 +4,46 @@ | |||||||
|  * |  * | ||||||
|  * @package   MyAAC |  * @package   MyAAC | ||||||
|  * @author    Lee |  * @author    Lee | ||||||
|  * @copyright 2020 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Models\Account as AccountModel; |  | ||||||
| use MyAAC\Models\Player; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| $title = 'Account editor'; | $title = 'Account editor'; | ||||||
|  | $base = BASE_URL . 'admin/?p=accounts'; | ||||||
|  |  | ||||||
| csrfProtect(); | if ($config['account_country']) | ||||||
|  |  | ||||||
| $admin_base = ADMIN_URL . '?p=accounts'; |  | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| if (setting('core.account_country')) |  | ||||||
| 	require SYSTEM . 'countries.conf.php'; | 	require SYSTEM . 'countries.conf.php'; | ||||||
|  |  | ||||||
| $nameOrNumberColumn = getAccountIdentityColumn(); | function echo_success($message) | ||||||
|  | { | ||||||
|  | 	echo '<p class="success">' . $message . '</p>'; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function echo_error($message) | ||||||
|  | { | ||||||
|  | 	global $error; | ||||||
|  | 	echo '<p class="error">' . $message . '</p>'; | ||||||
|  | 	$error = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function verify_number($number, $name, $max_length) | ||||||
|  | { | ||||||
|  | 	if (!Validator::number($number)) | ||||||
|  | 		echo_error($name . ' can contain only numbers.'); | ||||||
|  |  | ||||||
|  | 	$number_length = strlen($number); | ||||||
|  | 	if ($number_length <= 0 || $number_length > $max_length) | ||||||
|  | 		echo_error($name . ' cannot be longer than ' . $max_length . ' digits.'); | ||||||
|  | } | ||||||
|  |  | ||||||
| $hasSecretColumn = $db->hasColumn('accounts', 'secret'); | $hasSecretColumn = $db->hasColumn('accounts', 'secret'); | ||||||
|  | $hasCoinsColumn = $db->hasColumn('accounts', 'coins'); | ||||||
| $hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); | $hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); | ||||||
| $hasTypeColumn = $db->hasColumn('accounts', 'type'); | $hasTypeColumn = $db->hasColumn('accounts', 'type'); | ||||||
| $hasGroupColumn = $db->hasColumn('accounts', 'group_id'); | $hasGroupColumn = $db->hasColumn('accounts', 'group_id'); | ||||||
|  |  | ||||||
| if (setting('core.account_country')) { | if ($config['account_country']) { | ||||||
| 	$countries = array(); | 	$countries = array(); | ||||||
| 	foreach (array('pl', 'se', 'br', 'us', 'gb') as $c) | 	foreach (array('pl', 'se', 'br', 'us', 'gb') as $c) | ||||||
| 		$countries[$c] = $config['countries'][$c]; | 		$countries[$c] = $config['countries'][$c]; | ||||||
| @@ -39,8 +52,6 @@ if (setting('core.account_country')) { | |||||||
| 	foreach ($config['countries'] as $code => $c) | 	foreach ($config['countries'] as $code => $c) | ||||||
| 		$countries[$code] = $c; | 		$countries[$code] = $c; | ||||||
| } | } | ||||||
| $web_acc = ACCOUNT_WEB_FLAGS; |  | ||||||
| $acc_type = setting('core.account_types'); |  | ||||||
| ?> | ?> | ||||||
|  |  | ||||||
| <link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ > | <link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ > | ||||||
| @@ -48,56 +59,38 @@ $acc_type = setting('core.account_types'); | |||||||
|  |  | ||||||
| <?php | <?php | ||||||
| $id = 0; | $id = 0; | ||||||
| $search_account = $search_account_email = ''; |  | ||||||
| if (isset($_REQUEST['id'])) | if (isset($_REQUEST['id'])) | ||||||
| 	$id = (int)$_REQUEST['id']; | 	$id = (int)$_REQUEST['id']; | ||||||
| else if (isset($_REQUEST['search_email'])) { | else if (isset($_REQUEST['search_name'])) { | ||||||
| 	$search_account_email = $_REQUEST['search_email']; | 	if (strlen($_REQUEST['search_name']) < 3 && !Validator::number($_REQUEST['search_name'])) { | ||||||
| 	$accountModel = AccountModel::where('email', $search_account_email)->limit(11)->get(['email', 'id']); | 		echo 'Player name is too short.'; | ||||||
| 	if (count($accountModel) == 0) { |  | ||||||
| 		echo_error('No entries found.'); |  | ||||||
| 	} else if (count($accountModel) == 1) { |  | ||||||
| 		$id = $accountModel->first()->getKey(); |  | ||||||
| 	} else if (count($accountModel) > 10) { |  | ||||||
| 		echo_error('Specified e-mail resulted with too many accounts.'); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| else if (isset($_REQUEST['search'])) { |  | ||||||
| 	$search_account = $_REQUEST['search']; |  | ||||||
| 	$min_size = 3; |  | ||||||
| 	if (in_array($nameOrNumberColumn, ['id', 'number'])) { |  | ||||||
| 		$min_size = 1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (strlen($search_account) < $min_size && !Validator::number($search_account)) { |  | ||||||
| 		echo_error('Account ' . $nameOrNumberColumn . ' is too short.'); |  | ||||||
| 	} else { | 	} else { | ||||||
| 		$query = AccountModel::where($nameOrNumberColumn, '=', $search_account)->limit(11)->get(['id', $nameOrNumberColumn]); | 		if (Validator::number($_REQUEST['search_name'])) | ||||||
| 		if (count($query) == 0) { | 			$id = $_REQUEST['search_name']; | ||||||
| 			echo_error('No entries found.'); | 		else { | ||||||
| 		} else if (count($query) == 1) { | 			$query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($_REQUEST['search_name'])); | ||||||
| 			$id = $query->first()->getKey(); | 			if ($query->rowCount() == 1) { | ||||||
| 		} else if (count($query) > 10) { | 				$query = $query->fetch(); | ||||||
| 			echo_error('Specified name resulted with too many accounts.'); | 				$id = $query['id']; | ||||||
| 			} else { | 			} else { | ||||||
| 			$str_construct = 'Do you mean?<ul class="mb-0">'; | 				$query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $_REQUEST['search_name'] . '%')); | ||||||
| 			foreach ($query as $row) { | 				if ($query->rowCount() > 0 && $query->rowCount() <= 10) { | ||||||
| 				$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row->getKey() . '">' . $row->attributes[$nameOrNumberColumn] . '</a></li>'; | 					echo 'Do you mean?<ul>'; | ||||||
| 			} | 					foreach ($query as $row) | ||||||
| 			$str_construct .= '</ul>'; | 						echo '<li><a href="' . $base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>'; | ||||||
| 			echo_error($str_construct); | 					echo '</ul>'; | ||||||
|  | 				} else if ($query->rowCount() > 10) | ||||||
|  | 					echo 'Specified name resulted with too many accounts.'; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| ?> |  | ||||||
| <div class="row"> |  | ||||||
| 	<?php |  | ||||||
| $groups = new OTS_Groups_List(); | $groups = new OTS_Groups_List(); | ||||||
| if ($id > 0) { | if ($id > 0) { | ||||||
| 	$account = new OTS_Account(); | 	$account = new OTS_Account(); | ||||||
| 	$account->load($id); | 	$account->load($id); | ||||||
|  |  | ||||||
| 		if (isset($_POST['save']) && $account->isLoaded()) { | 	if (isset($account, $_POST['save']) && $account->isLoaded()) {// we want to save | ||||||
| 		$error = false; | 		$error = false; | ||||||
|  |  | ||||||
| 		$_error = ''; | 		$_error = ''; | ||||||
| @@ -136,17 +129,10 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 			$errors['email'] = Validator::getLastError(); | 			$errors['email'] = Validator::getLastError(); | ||||||
|  |  | ||||||
| 		//tibia coins | 		//tibia coins | ||||||
| 			if (HAS_ACCOUNT_COINS) { | 		if ($hasCoinsColumn) { | ||||||
| 			$t_coins = $_POST['t_coins']; | 			$t_coins = $_POST['t_coins']; | ||||||
| 			verify_number($t_coins, 'Tibia coins', 12); | 			verify_number($t_coins, 'Tibia coins', 12); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 			// transferable tibia coins |  | ||||||
| 			if (HAS_ACCOUNT_COINS_TRANSFERABLE || HAS_ACCOUNT_TRANSFERABLE_COINS) { |  | ||||||
| 				$t_coins_transferable = $_POST['t_coins_transferable']; |  | ||||||
| 				verify_number($t_coins_transferable, 'Transferable Tibia coins', 12); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 		// prem days | 		// prem days | ||||||
| 		$p_days = (int)$_POST['p_days']; | 		$p_days = (int)$_POST['p_days']; | ||||||
| 		verify_number($p_days, 'Prem days', 11); | 		verify_number($p_days, 'Prem days', 11); | ||||||
| @@ -162,22 +148,20 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 		$rl_loca = $_POST['rl_loca']; | 		$rl_loca = $_POST['rl_loca']; | ||||||
|  |  | ||||||
| 		//country | 		//country | ||||||
| 			if(setting('core.account_country')) { |  | ||||||
| 		$rl_country = $_POST['rl_country']; | 		$rl_country = $_POST['rl_country']; | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 		$web_flags = $_POST['web_flags']; | 		$web_flags = $_POST['web_flags']; | ||||||
| 		verify_number($web_flags, 'Web Flags', 1); | 		verify_number($web_flags, 'Web Flags', 1); | ||||||
|  |  | ||||||
| 		//created | 		//created | ||||||
| 			$created = strtotime($_POST['created']); | 		$created = $_POST['created']; | ||||||
| 		verify_number($created, 'Created', 11); | 		verify_number($created, 'Created', 11); | ||||||
|  |  | ||||||
| 		//web last login | 		//web last login | ||||||
| 			$web_lastlogin = strtotime($_POST['web_lastlogin']); | 		$web_lastlogin = $_POST['web_lastlogin']; | ||||||
| 			verify_number($web_lastlogin, 'Web Last login', 11); | 		verify_number($web_lastlogin, 'Web Last logout', 11); | ||||||
|  |  | ||||||
| 			if (!$error && $hooks->trigger(HOOK_ADMIN_ACCOUNTS_SAVE_POST, ['account_id' => $account->getId(), 'account_email' =>  $account->getEMail()])) { | 		if (!$error) { | ||||||
| 			if(USE_ACCOUNT_NAME) { | 			if(USE_ACCOUNT_NAME) { | ||||||
| 				$account->setName($name); | 				$account->setName($name); | ||||||
| 			} | 			} | ||||||
| @@ -191,18 +175,12 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 			if($hasSecretColumn) { | 			if($hasSecretColumn) { | ||||||
| 				$account->setCustomField('secret', $secret); | 				$account->setCustomField('secret', $secret); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			$account->setCustomField('key', $key); | 			$account->setCustomField('key', $key); | ||||||
| 			$account->setEMail($email); | 			$account->setEMail($email); | ||||||
|  | 			if ($hasCoinsColumn) { | ||||||
| 				if (HAS_ACCOUNT_COINS) { |  | ||||||
| 				$account->setCustomField('coins', $t_coins); | 				$account->setCustomField('coins', $t_coins); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 				if (HAS_ACCOUNT_COINS_TRANSFERABLE || HAS_ACCOUNT_TRANSFERABLE_COINS) { |  | ||||||
| 					$account->setCustomField(ACCOUNT_COINS_TRANSFERABLE_COLUMN, $t_coins_transferable); |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 			$lastDay = 0; | 			$lastDay = 0; | ||||||
| 			if($p_days != 0 && $p_days != OTS_Account::GRATIS_PREMIUM_DAYS) { | 			if($p_days != 0 && $p_days != OTS_Account::GRATIS_PREMIUM_DAYS) { | ||||||
| 				$lastDay = time(); | 				$lastDay = time(); | ||||||
| @@ -217,458 +195,296 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 			} | 			} | ||||||
| 			$account->setRLName($rl_name); | 			$account->setRLName($rl_name); | ||||||
| 			$account->setLocation($rl_loca); | 			$account->setLocation($rl_loca); | ||||||
|  |  | ||||||
| 				if(setting('core.account_country')) { |  | ||||||
| 			$account->setCountry($rl_country); | 			$account->setCountry($rl_country); | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 			$account->setCustomField('created', $created); | 			$account->setCustomField('created', $created); | ||||||
| 			$account->setWebFlags($web_flags); | 			$account->setWebFlags($web_flags); | ||||||
| 			$account->setCustomField('web_lastlogin', $web_lastlogin); | 			$account->setCustomField('web_lastlogin', $web_lastlogin); | ||||||
|  |  | ||||||
| 			if (isset($password)) { | 			if (isset($password)) { | ||||||
| 					if (USE_ACCOUNT_SALT) { | 				$config_salt_enabled = $db->hasColumn('accounts', 'salt'); | ||||||
|  | 				if ($config_salt_enabled) { | ||||||
| 					$salt = generateRandomString(10, false, true, true); | 					$salt = generateRandomString(10, false, true, true); | ||||||
| 					$password = $salt . $password; | 					$password = $salt . $password; | ||||||
| 						$account->setCustomField('salt', $salt); | 					$account_logged->setCustomField('salt', $salt); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				$password = encrypt($password); | 				$password = encrypt($password); | ||||||
| 				$account->setPassword($password); | 				$account->setPassword($password); | ||||||
|  |  | ||||||
|  | 				if ($config_salt_enabled) | ||||||
|  | 					$account->setCustomField('salt', $salt); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			$account->save(); | 			$account->save(); | ||||||
| 			echo_success('Account saved at: ' . date('G:i')); | 			echo_success('Account saved at: ' . date('G:i')); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} else if ($id == 0) { | } | ||||||
| 		$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ', email FROM `accounts` ORDER BY `id` ASC'); |  | ||||||
|  | $search_account = ''; | ||||||
|  | if (isset($_REQUEST['search_name'])) | ||||||
|  | 	$search_account = $_REQUEST['search_name']; | ||||||
|  | else if (isset($_REQUEST['search_account'])) | ||||||
|  | 	$search_account = $_REQUEST['search_account']; | ||||||
|  | else if ($id > 0 && isset($account) && $account->isLoaded()) { | ||||||
|  | 	if(USE_ACCOUNT_NAME) { | ||||||
|  | 		$search_account = $account->getName(); | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		$search_account = $account->getId(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| ?> | ?> | ||||||
| 		<div class="col-12 col-sm-12 col-lg-10"> | <div class="row"> | ||||||
| 			<div class="card card-info card-outline"> |  | ||||||
| 				<div class="card-header"> |  | ||||||
| 					<h5 class="m-0">Accounts</h5> |  | ||||||
| 				</div> |  | ||||||
| 				<div class="card-body"> |  | ||||||
| 					<table class="acc_datatable table table-striped table-bordered table-responsive d-md-table"> |  | ||||||
| 						<thead> |  | ||||||
| 						<tr> |  | ||||||
| 							<th>ID</th> |  | ||||||
| 							<th><?= ($nameOrNumberColumn == 'name' ? 'Name' : 'Number'); ?></th> |  | ||||||
| 							<?php if($hasTypeColumn || $hasGroupColumn): ?> |  | ||||||
| 							<th>E-Mail</th> |  | ||||||
| 							<th>Position</th> |  | ||||||
| 							<?php endif; ?> |  | ||||||
| 							<th style="width: 40px">Edit</th> |  | ||||||
| 						</tr> |  | ||||||
| 						</thead> |  | ||||||
| 						<tbody> |  | ||||||
| 						<?php foreach ($accounts_db as $account_lst): ?> |  | ||||||
| 							<tr> |  | ||||||
| 								<th><?php echo $account_lst['id']; ?></th> |  | ||||||
| 								<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td> |  | ||||||
| 								<td><?php echo $account_lst['email']; ?></td> |  | ||||||
| 								<?php if($hasTypeColumn || $hasGroupColumn): ?> |  | ||||||
| 								<td> |  | ||||||
| 									<?php if ($hasTypeColumn) { |  | ||||||
| 										echo $acc_type[$account_lst['type']]; |  | ||||||
| 									} elseif ($hasGroupColumn) { |  | ||||||
| 										$group = $groups->getGroups(); |  | ||||||
| 										echo $group[$account_lst['group_id']]; |  | ||||||
| 									} ?> |  | ||||||
| 								</td> |  | ||||||
| 								<?php endif; ?> |  | ||||||
| 								<td><a href="?p=accounts&id=<?php echo $account_lst['id']; ?>" class="btn btn-success btn-sm" title="Edit"> |  | ||||||
| 										<i class="fas fa-pencil-alt"></i> |  | ||||||
| 									</a> |  | ||||||
| 								</td> |  | ||||||
| 							</tr> |  | ||||||
| 						<?php endforeach; ?> |  | ||||||
| 						</tbody> |  | ||||||
| 					</table> |  | ||||||
| 				</div> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	<?php } ?> |  | ||||||
|  |  | ||||||
| 	<?php if (isset($account) && $account->isLoaded()) { ?> | 	<?php if (isset($account) && $account->isLoaded()) { ?> | ||||||
| 		<div class="col-12 col-sm-12 col-lg-10"> |  | ||||||
| 			<div class="card card-primary card-outline card-outline-tabs"> |  | ||||||
| 				<div class="card-header p-0 border-bottom-0"> |  | ||||||
| 					<ul class="nav nav-tabs" id="accounts-tab" role="tablist"> |  | ||||||
| 						<li class="nav-item"> |  | ||||||
| 							<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a> |  | ||||||
| 						</li> |  | ||||||
| 						<li class="nav-item"> |  | ||||||
| 							<a class="nav-link" id="accounts-logs-tab" data-toggle="pill" href="#accounts-logs">Logs</a> |  | ||||||
| 						</li> |  | ||||||
| 						<li class="nav-item"> |  | ||||||
| 							<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a> |  | ||||||
| 						</li> |  | ||||||
| 						<?php if ($db->hasTable('bans')) : ?> |  | ||||||
| 							<li class="nav-item"> |  | ||||||
| 								<a class="nav-link" id="accounts-bans-tab" data-toggle="pill" href="#accounts-bans">Bans</a> |  | ||||||
| 							</li> |  | ||||||
| 						<?php endif; |  | ||||||
|  |  | ||||||
| 						if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?> | 	<form action="<?php echo $base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post" | ||||||
| 							<li class="nav-item"> | 		  class="form-horizontal"> | ||||||
| 								<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a> | 		<div class="col-md-8"> | ||||||
| 							</li> | 			<div class="box box-primary"> | ||||||
| 						<?php endif; ?> | 				<div class="box-body"> | ||||||
| 					</ul> | 					<div class="row"> | ||||||
| 				</div> |  | ||||||
| 				<div class="card-body"> |  | ||||||
| 					<div class="tab-content" id="accounts-tabContent"> |  | ||||||
| 						<div class="tab-pane fade active show" id="accounts-acc"> |  | ||||||
| 							<form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post"> |  | ||||||
| 								<?php csrf(); ?> |  | ||||||
| 								<div class="form-group row"> |  | ||||||
| 						<?php if(USE_ACCOUNT_NAME): ?> | 						<?php if(USE_ACCOUNT_NAME): ?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-4"> | 						<div class="col-xs-4"> | ||||||
| 											<label for="name">Account Name:</label> | 							<label for="name" class="control-label">Account Name:</label> | ||||||
| 											<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/> | 							<input type="text" class="form-control" id="name" name="name" | ||||||
| 										</div> | 								   autocomplete="off" style="cursor: auto;" | ||||||
| 									<?php elseif (USE_ACCOUNT_NUMBER): ?> | 								   value="<?php echo $account->getName(); ?>"/> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-4"> |  | ||||||
| 											<label for="name">Account Number:</label> |  | ||||||
| 											<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getNumber(); ?>"/> |  | ||||||
| 						</div> | 						</div> | ||||||
| 						<?php endif; ?> | 						<?php endif; ?> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-5"> | 						<div class="col-xs-5"> | ||||||
| 										<div class="form-check"> | 							<label for="c_pass" class="control-label">Password: (check to change)</label> | ||||||
|  | 							<div class="input-group"> | ||||||
|  |                             <span class="input-group-addon"> | ||||||
|                               <input type="checkbox" |                               <input type="checkbox" | ||||||
| 									 name="c_pass" | 									 name="c_pass" | ||||||
| 									 id="c_pass" | 									 id="c_pass" | ||||||
| 									 value="false" | 									 value="false" | ||||||
| 												   class="form-check-input"/> | 									 class="input_control"/> | ||||||
| 											<label for="c_pass">Password: (check to change)</label> |                             </span> | ||||||
| 										</div> | 								<input type="text" class="form-control" id="pass" name="pass" | ||||||
| 										<div class="input-group"> | 									   autocomplete="off" maxlength="20" | ||||||
| 											<input type="text" class="form-control" id="pass" name="pass" autocomplete="off" maxlength="20" value=""/> | 									   value=""/> | ||||||
| 							</div> | 							</div> | ||||||
| 						</div> | 						</div> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-3"> | 						<div class="col-xs-3"> | ||||||
| 							<label for="account_id" class="control-label">Account ID:</label> | 							<label for="account_id" class="control-label">Account ID:</label> | ||||||
| 										<input type="text" class="form-control" id="account_id" name="account_id" autocomplete="off" size="8" maxlength="11" disabled value="<?php echo $account->getId(); ?>"/> | 							<input type="text" class="form-control" id="account_id" name="account_id" | ||||||
|  | 								   autocomplete="off" style="cursor: auto;" size="8" maxlength="11" disabled | ||||||
|  | 								   value="<?php echo $account->getId(); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 								<div class="form-group row"> | 					<div class="row"> | ||||||
| 						<?php | 						<?php | ||||||
| 						$acc_group = $account->getAccGroupId(); | 						$acc_group = $account->getAccGroupId(); | ||||||
| 						if ($hasTypeColumn) { | 						if ($hasTypeColumn) { | ||||||
|  | 							$groups = new OTS_Groups_List(); | ||||||
|  |  | ||||||
|  | 							$acc_type = array("Normal", "Tutor", "Senior Tutor", "Gamemaster", "God"); | ||||||
|  | 							if ($groups->getHighestId() == 6) { | ||||||
|  | 								$acc_type = array("Normal", "Tutor", "Senior Tutor", "Gamemaster", "Community Manager", "God"); | ||||||
|  | 							} | ||||||
| 						?> | 						?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-6"> | 							<div class="col-xs-6"> | ||||||
| 											<label for="group">Account Type:</label> | 								<label for="group" class="control-label">Account Type:</label> | ||||||
| 								<select name="group" id="group" class="form-control"> | 								<select name="group" id="group" class="form-control"> | ||||||
| 												<?php foreach ($acc_type as $_id => $a_type): ?> | 									<?php foreach ($acc_type as $id => $a_type): ?> | ||||||
| 													<option value="<?php echo($_id); ?>" <?php echo($acc_group == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> | 										<option value="<?php echo($id + 1); ?>" <?php echo($acc_group == ($id + 1) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> | ||||||
| 									<?php endforeach; ?> | 									<?php endforeach; ?> | ||||||
| 								</select> | 								</select> | ||||||
| 							</div> | 							</div> | ||||||
| 							<?php | 							<?php | ||||||
| 						} elseif ($hasGroupColumn) { | 						} elseif ($hasGroupColumn) { | ||||||
| 							?> | 							?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-6"> | 							<div class="col-xs-6"> | ||||||
| 											<label for="group">Account Type:</label> | 								<label for="group" class="control-label">Account Type:</label> | ||||||
| 								<select name="group" id="group" class="form-control"> | 								<select name="group" id="group" class="form-control"> | ||||||
| 												<?php foreach ($groups->getGroups() as $_id => $group): ?> | 									<?php | ||||||
| 													<option value="<?php echo $_id; ?>" <?php echo($acc_group == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> | 									foreach ($groups->getGroups() as $id => $group): ?> | ||||||
|  | 										<option value="<?php echo $id; ?>" <?php echo($acc_group == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> | ||||||
| 									<?php endforeach; ?> | 									<?php endforeach; ?> | ||||||
| 								</select> | 								</select> | ||||||
| 							</div> | 							</div> | ||||||
| 						<?php } ?> | 						<?php } ?> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-6"> | 						<div class="col-xs-6"> | ||||||
| 										<label for="web_flags">Website Access:</label> | 							<label for="web_flags" class="control-label">Website Access:</label> | ||||||
| 							<select name="web_flags" id="web_flags" class="form-control"> | 							<select name="web_flags" id="web_flags" class="form-control"> | ||||||
| 											<?php foreach ($web_acc as $_id => $a_type): ?> | 								<?php $web_acc = array("None", "Admin", "Super Admin", "(Admin + Super Admin)"); | ||||||
| 												<option value="<?php echo($_id); ?>" <?php echo($account->getWebFlags() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> | 								foreach ($web_acc as $id => $a_type): ?> | ||||||
|  | 									<option value="<?php echo($id); ?>" <?php echo($account->getWebFlags() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> | ||||||
| 								<?php endforeach; ?> | 								<?php endforeach; ?> | ||||||
| 							</select> | 							</select> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 								<div class="form-group row"> | 					<div class="row"> | ||||||
| 						<?php if($hasSecretColumn): ?> | 						<?php if($hasSecretColumn): ?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-6"> | 						<div class="col-xs-6"> | ||||||
| 											<label for="secret">Secret:</label> | 							<label for="secret" class="control-label">Secret:</label> | ||||||
| 											<input type="text" class="form-control" id="secret" name="secret" autocomplete="off" value="<?php echo $account->getCustomField('secret'); ?>"/> | 							<input type="text" class="form-control" id="secret" name="secret" | ||||||
|  | 								   autocomplete="off" style="cursor: auto;" size="8" maxlength="11" | ||||||
|  | 								   value="<?php echo $account->getCustomField('secret'); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 						<?php endif; ?> | 						<?php endif; ?> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-6"> | 						<div class="col-xs-6"> | ||||||
| 										<label for="key">Recovery Key:</label> | 							<label for="key" class="control-label">Key:</label> | ||||||
| 										<input type="text" class="form-control" id="key" name="key" autocomplete="off" value="<?php echo $account->getCustomField('key'); ?>"/> | 							<input type="text" class="form-control" id="key" name="key" | ||||||
|  | 								   autocomplete="off" style="cursor: auto;" size="8" maxlength="11" | ||||||
|  | 								   value="<?php echo $account->getCustomField('key'); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 								<div class="form-group row"> | 					<div class="row"> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-6"> | 						<div class="col-xs-6"> | ||||||
| 										<label for="email">Email:</label><?php echo (setting('core.mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?> | 							<label for="email" class="control-label">Email:</label> | ||||||
| 										<input type="text" class="form-control" id="email" name="email" autocomplete="off" value="<?php echo $account->getEMail(); ?>"/> | 							<input type="text" class="form-control" id="email" name="email" | ||||||
|  | 								   autocomplete="off" maxlength="20" | ||||||
|  | 								   value="<?php echo $account->getEMail(); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 									<?php if (HAS_ACCOUNT_COINS): ?> | 						<?php if ($hasCoinsColumn): ?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-6"> | 							<div class="col-xs-6"> | ||||||
| 											<label for="t_coins">Tibia Coins:</label> | 								<label for="t_coins" class="control-label">Tibia Coins:</label> | ||||||
| 											<input type="text" class="form-control" id="t_coins" name="t_coins" autocomplete="off" maxlength="11" value="<?php echo $account->getCustomField('coins') ?>"/> | 								<input type="text" class="form-control" id="t_coins" name="t_coins" | ||||||
|  | 									   autocomplete="off" maxlength="8" | ||||||
|  | 									   value="<?php echo $account->getCustomField('coins') ?>"/> | ||||||
| 							</div> | 							</div> | ||||||
| 						<?php endif; ?> | 						<?php endif; ?> | ||||||
| 									<?php if (HAS_ACCOUNT_COINS_TRANSFERABLE || HAS_ACCOUNT_TRANSFERABLE_COINS): ?> | 						<div class="col-xs-6"> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-6"> | 							<label for="p_days" class="control-label">Premium Days:</label> | ||||||
| 											<label for="t_coins_transferable">Transferable Tibia Coins:</label> | 							<input type="text" class="form-control" id="p_days" name="p_days" | ||||||
| 											<input type="text" class="form-control" id="t_coins_transferable" name="t_coins_transferable" autocomplete="off" maxlength="11" value="<?php echo $account->getCustomField(ACCOUNT_COINS_TRANSFERABLE_COLUMN) ?>"/> | 								   autocomplete="off" maxlength="11" | ||||||
| 										</div> | 								   value="<?php echo $account->getPremDays(); ?>"/> | ||||||
| 									<?php endif; ?> |  | ||||||
| 									<div class="col-12 col-sm-12 col-lg-6"> |  | ||||||
| 										<label for="p_days">Premium Days:</label> |  | ||||||
| 										<input type="text" class="form-control" id="p_days" name="p_days" autocomplete="off" maxlength="11" value="<?php echo $account->getPremDays(); ?>"/> |  | ||||||
| 						</div> | 						</div> | ||||||
| 						<?php if ($hasPointsColumn): ?> | 						<?php if ($hasPointsColumn): ?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-6"> | 							<div class="col-xs-6"> | ||||||
| 								<label for="p_points" class="control-label">Premium Points:</label> | 								<label for="p_points" class="control-label">Premium Points:</label> | ||||||
| 											<input type="text" class="form-control" id="p_points" name="p_points" autocomplete="off" maxlength="8" value="<?php echo $account->getCustomField('premium_points') ?>"/> | 								<input type="text" class="form-control" id="p_points" name="p_points" | ||||||
|  | 									   autocomplete="off" maxlength="8" | ||||||
|  | 									   value="<?php echo $account->getCustomField('premium_points') ?>"/> | ||||||
| 							</div> | 							</div> | ||||||
| 						<?php endif; ?> | 						<?php endif; ?> | ||||||
| 					</div> | 					</div> | ||||||
| 								<div class="form-group row"> | 					<div class="row"> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-4"> | 						<div class="col-xs-4"> | ||||||
| 										<label for="rl_name">RL Name:</label> | 							<label for="rl_name" class="control-label">RL Name:</label> | ||||||
| 							<input type="text" class="form-control" id="rl_name" name="rl_name" | 							<input type="text" class="form-control" id="rl_name" name="rl_name" | ||||||
| 								   autocomplete="off" maxlength="20" | 								   autocomplete="off" maxlength="20" | ||||||
| 								   value="<?php echo $account->getRLName(); ?>"/> | 								   value="<?php echo $account->getRLName(); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-4"> | 						<div class="col-xs-4"> | ||||||
| 										<label for="rl_loca">Location:</label> | 							<label for="rl_loca" class="control-label">Location:</label> | ||||||
| 							<input type="text" class="form-control" id="rl_loca" name="rl_loca" | 							<input type="text" class="form-control" id="rl_loca" name="rl_loca" | ||||||
| 								   autocomplete="off" maxlength="20" | 								   autocomplete="off" maxlength="20" | ||||||
| 								   value="<?php echo $account->getLocation(); ?>"/> | 								   value="<?php echo $account->getLocation(); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 									<?php if(setting('core.account_country')): ?> | 						<div class="col-xs-4"> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-4"> | 							<label for="rl_country" class="control-label">Country:</label> | ||||||
| 										<label for="rl_country">Country:</label> |  | ||||||
| 							<select name="rl_country" id="rl_country" class="form-control"> | 							<select name="rl_country" id="rl_country" class="form-control"> | ||||||
| 											<?php foreach ($countries as $_id => $a_type): ?> | 								<?php foreach ($countries as $id => $a_type): ?> | ||||||
| 												<option value="<?php echo($_id); ?>" <?php echo($account->getCountry() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> | 									<option value="<?php echo($id); ?>" <?php echo($account->getCountry() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> | ||||||
| 								<?php endforeach; ?> | 								<?php endforeach; ?> | ||||||
| 							</select> | 							</select> | ||||||
| 						</div> | 						</div> | ||||||
| 									<?php endif; ?> |  | ||||||
| 					</div> | 					</div> | ||||||
| 								<div class="form-group row"> | 					<div class="row"> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-6"> | 						<div class="col-xs-4"> | ||||||
| 							<label for="created" class="control-label">Created:</label> | 							<label for="created" class="control-label">Created:</label> | ||||||
| 										<input type="text" class="form-control" id="created" name="created" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $account->getCustomField('created')); ?>"/> | 							<input type="text" class="form-control" id="created" name="created" | ||||||
|  | 								   autocomplete="off" maxlength="20" | ||||||
|  | 								   value="<?php echo $account->getCustomField('created'); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 									<div class="col-12 col-sm-12 col-lg-6"> | 						<div class="col-xs-4"> | ||||||
| 							<label for="web_lastlogin" class="control-label">Web Last Login:</label> | 							<label for="web_lastlogin" class="control-label">Web Last Login:</label> | ||||||
| 										<input type="text" class="form-control" id="web_lastlogin" name="web_lastlogin" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $account->getCustomField('web_lastlogin')); ?>"/> | 							<input type="text" class="form-control" id="web_lastlogin" name="web_lastlogin" | ||||||
|  | 								   autocomplete="off" maxlength="20" | ||||||
|  | 								   value="<?php echo $account->getCustomField('web_lastlogin'); ?>"/> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
|  |  | ||||||
| 					<input type="hidden" name="save" value="yes"/> | 					<input type="hidden" name="save" value="yes"/> | ||||||
|  | 					<div class="box-footer"> | ||||||
|  | 						<a href="<?php echo ADMIN_URL; ?>?p=accounts"><span class="btn btn-danger">Cancel</span></a> | ||||||
|  | 						<div class="pull-right"> | ||||||
|  | 							<input type="submit" class="btn btn-primary" value="Update"> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  |  | ||||||
| 								<button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Update</button> | 				</div> | ||||||
| 								<a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a> | 			</div> | ||||||
| 	</form> | 	</form> | ||||||
| </div> | </div> | ||||||
| 						<div class="tab-pane fade" id="accounts-logs"> | <?php } ?> | ||||||
| 							<div class="row"> | <div class="col-md-4"> | ||||||
| 								<table class="table table-striped table-condensed table-responsive d-md-table"> | 	<div class="box box-primary"> | ||||||
| 									<thead> | 		<div class="box-header with-border"> | ||||||
| 										<tr> | 			<h3 class="box-title">Search Account:</h3> | ||||||
| 											<th>#</th> | 			<div class="box-tools pull-right"> | ||||||
| 											<th>Date</th> | 				<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i> | ||||||
| 											<th>Action</th> | 				</button> | ||||||
| 											<th>IP</th> | 			</div> | ||||||
| 										</tr> | 		</div> | ||||||
| 									</thead> |  | ||||||
| 									<tbody> | 		<div class="box-body"> | ||||||
| 										<?php | 			<form action="<?php echo $base; ?>" method="post"> | ||||||
| 											$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get(); | 				<div class="input-group input-group-sm"> | ||||||
| 											foreach ($accountActions as $i => $log): | 					<input type="text" class="form-control" name="search_name" value="<?php echo escapeHtml($search_account); ?>" | ||||||
| 												$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6)); | 						   maxlength="32" size="32"> | ||||||
| 												?> | 					<span class="input-group-btn"> | ||||||
| 											<tr> |                           <button type="submit" type="button" class="btn btn-info btn-flat">Search</button> | ||||||
| 												<td><?php echo $i + 1; ?></td> |                         </span> | ||||||
| 												<td><?= date("M d Y, H:i:s", $log->date); ?></td> | 				</div> | ||||||
| 												<td><?= $log->action; ?></td> | 			</form> | ||||||
| 												<td><?= $log->ip; ?></td> |  | ||||||
| 											</tr> |  | ||||||
| 											<?php endforeach; ?> |  | ||||||
| 									</tbody> |  | ||||||
| 								</table> |  | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| 						<div class="tab-pane fade" id="accounts-chars"> |  | ||||||
| 							<div class="row"> |  | ||||||
| 	<?php | 	<?php | ||||||
| 	if (isset($account) && $account->isLoaded()) { | 	if (isset($account) && $account->isLoaded()) { | ||||||
| 									$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get(); | 		$account_players = array(); | ||||||
| 									if (isset($account_players)) { ?> | 		$query = $db->query('SELECT `name`,`level`,`vocation`  FROM `players` WHERE `account_id` = ' . $account->getId() . ' ORDER BY `name`')->fetchAll(); | ||||||
| 										<table class="table table-striped table-condensed table-responsive d-md-table"> | 		if (isset($query)) { | ||||||
| 											<thead> | 			?> | ||||||
|  | 			<div class="box"> | ||||||
|  | 				<div class="box-header"> | ||||||
|  | 					<h3 class="box-title">Character List:</h3> | ||||||
|  | 				</div> | ||||||
|  | 				<div class="box-body no-padding"> | ||||||
|  | 					<table class="table table-striped"> | ||||||
|  | 						<tbody> | ||||||
| 						<tr> | 						<tr> | ||||||
| 												<th>#</th> | 							<th style="width: 10px">#</th> | ||||||
| 							<th>Name</th> | 							<th>Name</th> | ||||||
| 							<th>Level</th> | 							<th>Level</th> | ||||||
| 												<th>Vocation</th> |  | ||||||
| 							<th style="width: 40px">Edit</th> | 							<th style="width: 40px">Edit</th> | ||||||
| 						</tr> | 						</tr> | ||||||
| 											</thead> |  | ||||||
| 											<tbody> |  | ||||||
| 											<?php foreach ($account_players as $i => $player): ?> |  | ||||||
| 												<tr> |  | ||||||
| 													<th><?php echo $i + 1; ?></th> |  | ||||||
| 													<td><?php echo $player->name; ?></td> |  | ||||||
| 													<td><?php echo $player->level; ?></td> |  | ||||||
| 													<td><?php echo $player->vocation_name; ?></td> |  | ||||||
| 													<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td> |  | ||||||
| 												</tr> |  | ||||||
| 											<?php endforeach ?> |  | ||||||
| 											</tbody> |  | ||||||
| 										</table> |  | ||||||
| 						<?php | 						<?php | ||||||
| 									} | 						$i = 1; | ||||||
|  | 						foreach ($query as $p) { | ||||||
|  | 							$account_players[] = $p; | ||||||
|  | 							echo '<tr> | ||||||
|  |                             <td>' . $i . '.</td> | ||||||
|  |                             <td>' . $p['name'] . '</td> | ||||||
|  |                             <td>' . $p['level'] . '</td> | ||||||
|  |                             <td><a href="?p=players&search_name=' . $p['name'] . '"><span class="btn btn-success btn-sm edit btn-flat"><i class="fa fa-edit"></i></span></a></span></td> | ||||||
|  |                         </tr>'; | ||||||
|  | 							$i++; | ||||||
| 						} ?> | 						} ?> | ||||||
| 							</div> |  | ||||||
| 						</div> |  | ||||||
| 						<?php if ($db->hasTable('bans')) : ?> |  | ||||||
| 							<div class="tab-pane fade" id="accounts-bans"> |  | ||||||
| 								<?php |  | ||||||
| 								$bans = $db->query('SELECT * FROM ' . $db->tableName('bans') . ' WHERE ' . $db->fieldName('active') . ' = 1 AND ' . $db->fieldName('id') . ' = ' . $account->getId() . ' ORDER BY ' . $db->fieldName('added') . ' DESC LIMIT 10'); |  | ||||||
| 								if ($bans->rowCount()) { |  | ||||||
| 									?> |  | ||||||
| 									<table class="table table-striped table-condensed table-responsive d-md-table"> |  | ||||||
| 										<thead> |  | ||||||
| 										<tr> |  | ||||||
| 											<th>Nick</th> |  | ||||||
| 											<th>Type</th> |  | ||||||
| 											<th>Expires</th> |  | ||||||
| 											<th>Reason</th> |  | ||||||
| 											<th>Comment</th> |  | ||||||
| 											<th>Added by:</th> |  | ||||||
| 										</tr> |  | ||||||
| 										</thead> |  | ||||||
| 										<tbody> |  | ||||||
| 										<?php |  | ||||||
| 										foreach ($bans as $ban) { |  | ||||||
| 											?> |  | ||||||
| 											<tr> |  | ||||||
| 												<td><?php |  | ||||||
| 													$pName = getPlayerNameByAccount($ban['value']); |  | ||||||
| 													echo '<a href="?p=players&search=' . $pName . '">' . $pName . '</a>'; ?> |  | ||||||
| 												</td> |  | ||||||
| 												<td><?php echo getBanType($ban['type']); ?></td> |  | ||||||
| 												<td> |  | ||||||
| 													<?php |  | ||||||
| 													if ($ban['expires'] == "-1") |  | ||||||
| 														echo 'Never'; |  | ||||||
| 													else |  | ||||||
| 														echo date("H:i:s", $ban['expires']) . '<br/>' . date("d M Y", $ban['expires']); |  | ||||||
| 													?> |  | ||||||
| 												</td> |  | ||||||
| 												<td><?php echo getBanReason($ban['reason']); ?></td> |  | ||||||
| 												<td><?php echo $ban['comment']; ?></td> |  | ||||||
| 												<td> |  | ||||||
| 													<?php |  | ||||||
| 													if ($ban['admin_id'] == "0") |  | ||||||
| 														echo 'Autoban'; |  | ||||||
| 													else |  | ||||||
| 														$aName = getPlayerNameByAccount($ban['admin_id']); |  | ||||||
| 													echo '<a href="?p=players&search=' . $aName . '">' . $aName . '</a>'; |  | ||||||
| 													echo '<br/>' . date("d.m.Y", $ban['added']); |  | ||||||
| 													?> |  | ||||||
| 												</td> |  | ||||||
| 											</tr> |  | ||||||
| 										<?php } ?> |  | ||||||
| 										</tbody> |  | ||||||
| 									</table> |  | ||||||
| 									<?php |  | ||||||
| 								} else { |  | ||||||
| 									echo 'No Account bans.'; |  | ||||||
| 								} ?> |  | ||||||
| 							</div> |  | ||||||
| 						<?php endif; |  | ||||||
| 						if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) { ?> |  | ||||||
| 							<div class="tab-pane fade" id="accounts-store"> |  | ||||||
| 								<?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?> |  | ||||||
| 								<table class="table table-striped table-condensed table-responsive d-md-table"> |  | ||||||
| 									<thead> |  | ||||||
| 									<tr> |  | ||||||
| 										<th>Description</th> |  | ||||||
| 										<th>Coins</th> |  | ||||||
| 										<th>Date</th> |  | ||||||
| 									</tr> |  | ||||||
| 									</thead> |  | ||||||
| 									<tbody> |  | ||||||
| 									<?php foreach ($store_history as $p): ?> |  | ||||||
| 										<tr> |  | ||||||
| 											<td><?php echo $p['description']; ?></td> |  | ||||||
| 											<td><?php echo $p['coin_amount']; ?></td> |  | ||||||
| 											<td><?php echo date('d M y H:i:s', $p['time']); ?></td> |  | ||||||
| 										</tr> |  | ||||||
| 									<?php endforeach; ?> |  | ||||||
| 						</tbody> | 						</tbody> | ||||||
| 					</table> | 					</table> | ||||||
| 				</div> | 				</div> | ||||||
| 						<?php } ?> |  | ||||||
| 			</div> | 			</div> | ||||||
|  |  | ||||||
|  | 			<?php | ||||||
|  | 		}; | ||||||
|  | 	}; | ||||||
|  | 	?> | ||||||
| </div> | </div> | ||||||
| 			</div> |  | ||||||
| 		</div> | <script type="text/javascript"> | ||||||
| 	<?php } ?> | 	$('#lastlogout').datetimepicker({format: 'unixtime'}); | ||||||
| 	<div class="col-12 col-sm-12 col-lg-2"> | 	$('#created').datetimepicker({format: 'unixtime'}); | ||||||
| 		<div class="card card-info card-outline"> | 	$('#web_lastlogin').datetimepicker({format: 'unixtime'}); | ||||||
| 			<div class="card-header"> |  | ||||||
| 				<h5 class="m-0">Search Accounts</h5> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="card-body"> |  | ||||||
| 				<div class="row"> |  | ||||||
| 					<div class="col-6 col-lg-12"> |  | ||||||
| 						<form action="<?php echo $admin_base; ?>" method="post"> |  | ||||||
| 							<?php csrf(); ?> |  | ||||||
| 							<label for="search">Account E-Mail:</label> |  | ||||||
| 							<div class="input-group input-group-sm"> |  | ||||||
| 								<input type="email" class="form-control" id="search_email" name="search_email" value="<?= escapeHtml($search_account_email); ?>" maxlength="255" size="255"> |  | ||||||
| 								<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> |  | ||||||
| 							</div> |  | ||||||
| 						</form> |  | ||||||
| 					</div> |  | ||||||
| 					<div class="col-6 col-lg-12"> |  | ||||||
| 						<form action="<?php echo $admin_base; ?>" method="post"> |  | ||||||
| 							<?php csrf(); ?> |  | ||||||
| 							<label for="search">Account Name:</label> |  | ||||||
| 							<div class="input-group input-group-sm"> |  | ||||||
| 								<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32"> |  | ||||||
| 								<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> |  | ||||||
| 							</div> |  | ||||||
| 						</form> |  | ||||||
| 					</div> |  | ||||||
| 					<div class="col-6 col-lg-12"> |  | ||||||
| 						<form action="<?php echo $admin_base; ?>" method="post"> |  | ||||||
| 							<?php csrf(); ?> |  | ||||||
| 							<label for="id">Account ID:</label> |  | ||||||
| 							<div class="input-group input-group-sm"> |  | ||||||
| 								<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> |  | ||||||
| 								<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> |  | ||||||
| 							</div> |  | ||||||
| 						</form> |  | ||||||
| 					</div> |  | ||||||
| 				</div> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
| <script> |  | ||||||
| 	$(document).ready(function () { | 	$(document).ready(function () { | ||||||
| 		$('#created').datetimepicker({format: "M d Y, H:i:s",}); | 		$('.input_control').change(function () { | ||||||
| 		$('#web_lastlogin').datetimepicker({format: 'M d Y, H:i:s'}); | 			$('input[name=pass]')[0].disabled = !this.checked; | ||||||
|  | 			$('input[name=pass]')[0].value = ''; | ||||||
| 		$('#c_pass').change(function () { |  | ||||||
| 			const ipass = $('input[name=pass]'); |  | ||||||
| 			ipass[0].disabled = !this.checked; |  | ||||||
| 			ipass[0].value = ''; |  | ||||||
| 		}).change(); | 		}).change(); | ||||||
|  |  | ||||||
| 		$('.acc_datatable').DataTable({ |  | ||||||
| 			"order": [[0, "asc"]] |  | ||||||
| 		}); |  | ||||||
| 	}); | 	}); | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -1,131 +1,26 @@ | |||||||
| <?php | <?php | ||||||
| /** | /** | ||||||
|  * CHANGELOG modifier |  * CHANGELOG viewer | ||||||
|  * |  * | ||||||
|  * @package   MyAAC |  * @package   MyAAC | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  * @author    Slawkens <slawkens@gmail.com> | ||||||
|  * @author    Lee |  * @copyright 2019 MyAAC | ||||||
|  * @copyright 2020 MyAAC |  | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Changelog; |  | ||||||
| use MyAAC\Models\Changelog as ModelsChangelog; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  | $title = 'MyAAC Changelog'; | ||||||
|  |  | ||||||
| $title = 'Changelog'; | if (!file_exists(BASE . 'CHANGELOG.md')) { | ||||||
|  | 	echo 'File CHANGELOG.md doesn\'t exist.'; | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { |  | ||||||
| 	echo 'Access denied.'; |  | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $use_datatable = true; | require LIBS . 'Parsedown.php'; | ||||||
| const CL_LIMIT = 600; // maximum changelog body length |  | ||||||
|  |  | ||||||
| $id = $_GET['id'] ?? 0; | $changelog = file_get_contents(BASE . 'CHANGELOG.md'); | ||||||
|  |  | ||||||
| if(!empty($action) && isRequestMethod('post')) | $Parsedown = new Parsedown(); | ||||||
| { |  | ||||||
| 	$id = $_POST['id'] ?? null; |  | ||||||
| 	$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; |  | ||||||
| 	$create_date = isset($_POST['createdate']) ? (int)strtotime($_POST['createdate'] ): null; |  | ||||||
| 	$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null; |  | ||||||
| 	$type = isset($_POST['type']) ? (int)$_POST['type'] : null; |  | ||||||
| 	$where = isset($_POST['where']) ? (int)$_POST['where'] : null; |  | ||||||
|  |  | ||||||
| 	$errors = array(); | $changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p> | ||||||
|  |  | ||||||
| 	if($action == 'new') { | echo '<div>' . $changelog . '</div>'; | ||||||
|  |  | ||||||
| 		if(isset($body) && Changelog::add($body, $type, $where, $player_id, $create_date, $errors)) { |  | ||||||
| 			$body = ''; |  | ||||||
| 			$type = $where = $player_id = $create_date = 0; |  | ||||||
|  |  | ||||||
| 			success('Added successful.'); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if($action == 'delete') { |  | ||||||
| 		if (Changelog::delete($id, $errors)) { |  | ||||||
| 			success('Deleted successful.'); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if($action == 'edit') |  | ||||||
| 	{ |  | ||||||
| 		if(isset($id) && !isset($body)) { |  | ||||||
| 			$cl = Changelog::get($id); |  | ||||||
| 			$body = $cl['body']; |  | ||||||
| 			$type = $cl['type']; |  | ||||||
| 			$where = $cl['where']; |  | ||||||
| 			$create_date = $cl['date']; |  | ||||||
| 			$player_id = $cl['player_id']; |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			if(Changelog::update($id, $body, $type, $where, $player_id, $create_date,$errors)) { |  | ||||||
| 				$action = $body = ''; |  | ||||||
| 				$type = $where = $player_id = $create_date = 0; |  | ||||||
|  |  | ||||||
| 				success('Updated successful.'); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if($action == 'hide') { |  | ||||||
| 		if (Changelog::toggleHide($id, $errors, $status)) { |  | ||||||
| 			success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if(!empty($errors)) |  | ||||||
| 		error(implode(", ", $errors)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $changelogs = ModelsChangelog::orderBy('id')->get()->toArray(); |  | ||||||
|  |  | ||||||
| $i = 0; |  | ||||||
|  |  | ||||||
| $log_type = [ |  | ||||||
| 	['id' => 1, 'icon' => 'added'], |  | ||||||
| 	['id' => 2, 'icon' => 'removed'], |  | ||||||
| 	['id' => 3, 'icon' => 'changed'], |  | ||||||
| 	['id' => 4, 'icon' => 'fixed'], |  | ||||||
| ]; |  | ||||||
|  |  | ||||||
| $log_where = [ |  | ||||||
| 	['id' => 1, 'icon' => 'server'], |  | ||||||
| 	['id' => 2, 'icon' => 'website'], |  | ||||||
| ]; |  | ||||||
|  |  | ||||||
| foreach($changelogs as $key => &$log) |  | ||||||
| { |  | ||||||
| 	$log['type'] = getChangelogType($log['type']); |  | ||||||
| 	$log['where'] = getChangelogWhere($log['where']); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if($action == 'edit' || $action == 'new') { |  | ||||||
| 	if($action == 'edit') { |  | ||||||
| 		$player = new OTS_Player(); |  | ||||||
| 		$player->load($player_id); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$account_players = $account_logged->getPlayersList(); |  | ||||||
| 	$account_players->orderBy('group_id', POT::ORDER_DESC); |  | ||||||
| 	$twig->display('admin.changelog.form.html.twig', array( |  | ||||||
| 		'action' => $action, |  | ||||||
| 		'cl_link_form' => constant('ADMIN_URL').'?p=changelog', |  | ||||||
| 		'cl_id' => $id ?? null, |  | ||||||
| 		'body' => isset($body) ? escapeHtml($body) : '', |  | ||||||
| 		'create_date' => $create_date ?? '', |  | ||||||
| 		'player_id' => $player_id ?? null, |  | ||||||
| 		'account_players' => $account_players, |  | ||||||
| 		'type' => $type ?? 0, |  | ||||||
| 		'where' => $where ?? 0, |  | ||||||
| 		'log_type' => $log_type, |  | ||||||
| 		'log_where' => $log_where, |  | ||||||
| 	)); |  | ||||||
| } |  | ||||||
| $twig->display('admin.changelog.html.twig', array( |  | ||||||
| 	'changelogs' => $changelogs, |  | ||||||
| )); |  | ||||||
|   | |||||||
| @@ -1,25 +0,0 @@ | |||||||
| <?php |  | ||||||
| /** |  | ||||||
|  * CHANGELOG viewer |  | ||||||
|  * |  | ||||||
|  * @package   MyAAC |  | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  | ||||||
|  * @author    Lee |  | ||||||
|  * @copyright 2020 MyAAC |  | ||||||
|  * @link      https://my-aac.org |  | ||||||
|  */ |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
| $title = 'MyAAC Changelog'; |  | ||||||
|  |  | ||||||
| if (!file_exists(BASE . 'CHANGELOG-1.x.md')) { |  | ||||||
| 	echo 'File CHANGELOG.md doesn\'t exist.'; |  | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $changelog = file_get_contents(BASE . 'CHANGELOG-1.x.md'); |  | ||||||
|  |  | ||||||
| $Parsedown = new Parsedown(); |  | ||||||
|  |  | ||||||
| $changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p> |  | ||||||
|  |  | ||||||
| echo '<div>' . $changelog . '</div>'; |  | ||||||
| @@ -10,9 +10,7 @@ | |||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Dashboard'; | $title = 'Dashboard'; | ||||||
|  |  | ||||||
| csrfProtect(); | if (isset($_GET['clear_cache'])) { | ||||||
|  |  | ||||||
| if (isset($_POST['clear_cache'])) { |  | ||||||
| 	if (clearCache()) { | 	if (clearCache()) { | ||||||
| 		success('Cache cleared.'); | 		success('Cache cleared.'); | ||||||
| 	} else { | 	} else { | ||||||
| @@ -20,11 +18,9 @@ if (isset($_POST['clear_cache'])) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| if (isset($_POST['maintenance'])) { | if (isset($_GET['maintenance'])) { | ||||||
| 	$message = (!empty($_POST['message']) ? $_POST['message'] : null); | 	$_status = (int)$_POST['status']; | ||||||
| 	$_status = (isset($_POST['status']) && $_POST['status'] == 'true'); | 	$message = $_POST['message']; | ||||||
| 	$_status = ($_status ? '0' : '1'); |  | ||||||
|  |  | ||||||
| 	if (empty($message)) { | 	if (empty($message)) { | ||||||
| 		error('Message cannot be empty.'); | 		error('Message cannot be empty.'); | ||||||
| 	} else if (strlen($message) > 255) { | 	} else if (strlen($message) > 255) { | ||||||
| @@ -49,15 +45,47 @@ $tmp = ''; | |||||||
| if (fetchDatabaseConfig('site_closed_message', $tmp)) | if (fetchDatabaseConfig('site_closed_message', $tmp)) | ||||||
| 	$closed_message = $tmp; | 	$closed_message = $tmp; | ||||||
|  |  | ||||||
| $settingAdminPanelModules = setting('core.admin_panel_modules'); | $query = $db->query('SELECT count(*) as `how_much` FROM `accounts`;'); | ||||||
| if (count($settingAdminPanelModules) > 0) { | $query = $query->fetch(); | ||||||
|  | $total_accounts = $query['how_much']; | ||||||
|  |  | ||||||
|  | $query = $db->query('SELECT count(*) as `how_much` FROM `players`;'); | ||||||
|  | $query = $query->fetch(); | ||||||
|  | $total_players = $query['how_much']; | ||||||
|  |  | ||||||
|  | $query = $db->query('SELECT count(*) as `how_much` FROM `guilds`;'); | ||||||
|  | $query = $query->fetch(); | ||||||
|  | $total_guilds = $query['how_much']; | ||||||
|  |  | ||||||
|  | $query = $db->query('SELECT count(*) as `how_much` FROM `houses`;'); | ||||||
|  | $query = $query->fetch(); | ||||||
|  | $total_houses = $query['how_much']; | ||||||
|  |  | ||||||
|  | $twig->display('admin.statistics.html.twig', array( | ||||||
|  | 	'total_accounts' => $total_accounts, | ||||||
|  | 	'total_players' => $total_players, | ||||||
|  | 	'total_guilds' => $total_guilds, | ||||||
|  | 	'total_houses' => $total_houses | ||||||
|  | )); | ||||||
|  |  | ||||||
|  | $twig->display('admin.dashboard.html.twig', array( | ||||||
|  | 	'is_closed' => $is_closed, | ||||||
|  | 	'closed_message' => $closed_message, | ||||||
|  | 	'status' => $status, | ||||||
|  | 	'account_type' => USE_ACCOUNT_NAME ? 'name' : 'number' | ||||||
|  | )); | ||||||
|  |  | ||||||
| echo '<div class="row">'; | echo '<div class="row">'; | ||||||
|  |  | ||||||
|  | $configAdminPanelModules = config('admin_panel_modules'); | ||||||
|  | if(isset($configAdminPanelModules)) | ||||||
|  | 	$configAdminPanelModules = explode(',', $configAdminPanelModules); | ||||||
|  |  | ||||||
| $twig_loader->prependPath(__DIR__ . '/modules/templates'); | $twig_loader->prependPath(__DIR__ . '/modules/templates'); | ||||||
| 	foreach ($settingAdminPanelModules as $box) { | foreach($configAdminPanelModules as $box) { | ||||||
| 	$file = __DIR__ . '/modules/' . $box . '.php'; | 	$file = __DIR__ . '/modules/' . $box . '.php'; | ||||||
| 	if(file_exists($file)) { | 	if(file_exists($file)) { | ||||||
| 		include($file); | 		include($file); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| echo '</div>'; | echo '</div>'; | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								admin/pages/items.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,35 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Load items.xml | ||||||
|  |  * | ||||||
|  |  * @package   MyAAC | ||||||
|  |  * @author    Slawkens <slawkens@gmail.com> | ||||||
|  |  * @copyright 2019 MyAAC | ||||||
|  |  * @link      https://my-aac.org | ||||||
|  |  */ | ||||||
|  | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  | $title = 'Load items.xml'; | ||||||
|  |  | ||||||
|  | require_once LIBS . 'items.php'; | ||||||
|  | require_once LIBS . 'weapons.php'; | ||||||
|  |  | ||||||
|  | $twig->display('admin.items.html.twig'); | ||||||
|  |  | ||||||
|  | $reload = isset($_REQUEST['reload']) && (int)$_REQUEST['reload'] === 1; | ||||||
|  | if ($reload) { | ||||||
|  | 	$items_start_time = microtime(true); | ||||||
|  | 	if (Items::loadFromXML(true)) { | ||||||
|  | 		success('Successfully loaded items (in ' . round(microtime(true) - $items_start_time, 4) . ' seconds).'); | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		error(Items::getError()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$weapons_start_time = microtime(true); | ||||||
|  | 	if (Weapons::loadFromXML(true)) { | ||||||
|  | 		success('Successfully loaded weapons (in ' . round(microtime(true) - $weapons_start_time, 4) . ' seconds).'); | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		error(Weapons::getError()); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -9,18 +9,18 @@ | |||||||
|  */ |  */ | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Login'; | $title = 'Login'; | ||||||
|  | $logout = ''; | ||||||
| csrfProtect(); | if ($action == 'logout') { | ||||||
|  | 	$logout = "You have  been logged out!"; | ||||||
| require PAGES . 'account/login.php'; |  | ||||||
| if ($logged) { |  | ||||||
| 	header('Location: ' . (admin() ? ADMIN_URL : BASE_URL)); |  | ||||||
| 	return; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('admin.login.html.twig', [ | if (isset($errors)) { | ||||||
| 	'logout' => (ACTION == 'logout' ? 'You have  been logged out!'  : ''), | 	foreach ($errors as $error) { | ||||||
|  | 		error($error); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $twig->display('admin.login.html.twig', array( | ||||||
|  | 	'logout' => $logout, | ||||||
| 	'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', | 	'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', | ||||||
| 	'account_login_by' => getAccountLoginByLabel(), | )); | ||||||
| 	'errors' => $errors ?? '' |  | ||||||
| ]); |  | ||||||
| @@ -4,17 +4,16 @@ | |||||||
|  * |  * | ||||||
|  * @package   MyAAC |  * @package   MyAAC | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  * @author    Slawkens <slawkens@gmail.com> | ||||||
|  * @copyright 2020 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Logs Viewer'; | $title = 'Logs Viewer'; | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| $files = array(); | $files = array(); | ||||||
| $aac_path_logs = BASE . 'system/logs/'; | $aac_path_logs = BASE . 'system/logs/'; | ||||||
| foreach (scandir($aac_path_logs, SCANDIR_SORT_ASCENDING) as $f) { | foreach (scandir($aac_path_logs, SCANDIR_SORT_ASCENDING) as $f) { | ||||||
| 	if ($f[0] === '.' || is_dir($aac_path_logs . $f) || $f === 'index.html') { |     if ($f[0] === '.' || is_dir($aac_path_logs . $f)) { | ||||||
| 	    continue; | 	    continue; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -54,6 +53,7 @@ foreach ($files as &$f) { | |||||||
| } | } | ||||||
| unset($f); | unset($f); | ||||||
|  |  | ||||||
|  | $twig->display('admin.logs.html.twig', array('files' => $files)); | ||||||
|  |  | ||||||
| define('EXIST_NONE', 0); | define('EXIST_NONE', 0); | ||||||
| define('EXIST_SERVER_LOG', 1); | define('EXIST_SERVER_LOG', 1); | ||||||
| @@ -72,12 +72,10 @@ if (!empty($file)) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ($exist !== EXIST_NONE) { | 		if ($exist !== EXIST_NONE) { | ||||||
| 			$file_content = nl2br(file_get_contents(($exist === EXIST_SERVER_LOG ? $server_path_logs : $aac_path_logs) . $file)); | 			$content = nl2br(file_get_contents(($exist === EXIST_SERVER_LOG ? $server_path_logs : $aac_path_logs) . $file)); | ||||||
| 			$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $file_content)); | 			$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $content)); | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		echo 'Invalid file name specified.'; | 		echo 'Invalid file name specified.'; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('admin.logs.html.twig', array('files' => $files)); |  | ||||||
|   | |||||||
| @@ -7,84 +7,63 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Mailer'; | $title = 'Mailer'; | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| if (!setting('core.mail_enabled')) { | if (!$config['mail_enabled']) { | ||||||
| 	echo 'Mail support disabled in config.'; | 	echo 'Mail support disabled.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $mail_to = isset($_REQUEST['mail_to']) ? stripslashes(trim($_REQUEST['mail_to'])) : null; | $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : NULL; | ||||||
| $mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null; | $mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : NULL; | ||||||
| $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null; | $preview = isset($_REQUEST['preview']); | ||||||
| $mail_verified_only = $_POST['mail_verified_only'] ?? false; |  | ||||||
|  |  | ||||||
| if (isset($_POST['submit'])) { | $preview_done = false; | ||||||
| 	if (empty($mail_subject)) { | if ($preview) { | ||||||
| 		warning('Please enter subject of the message.'); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (empty($mail_content)) { |  | ||||||
| 		warning('Please enter content of the message.'); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| if (!empty($mail_to)) { |  | ||||||
| 	if(!Validator::email($mail_to)) { |  | ||||||
| 		warning('E-Mail is invalid.'); |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 	if (!empty($mail_content) && !empty($mail_subject)) { | 	if (!empty($mail_content) && !empty($mail_subject)) { | ||||||
| 			if (_mail($mail_to, $mail_subject, $mail_content)) { | 		$preview_done = _mail($account_logged->getCustomField('email'), $mail_subject, $mail_content); | ||||||
| 				success("Successfully mailed <strong>$mail_to</strong>"); |  | ||||||
| 			} | 		if (!$preview_done) | ||||||
| 			else { | 			error('Error while sending preview mail. More info can be found in system/logs/mailer-error.log'); | ||||||
| 				error("Error while sending mail to <strong>$mail_to</strong>. More info can be found in system/logs/mailer-error.log"); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| if (!empty($mail_content) && !empty($mail_subject) && empty($mail_to)) { |  | ||||||
|  | $twig->display('admin.mailer.html.twig', array( | ||||||
|  | 	'mail_subject' => $mail_subject, | ||||||
|  | 	'mail_content' => $mail_content, | ||||||
|  | 	'preview_done' => $preview_done | ||||||
|  | )); | ||||||
|  |  | ||||||
|  | if (empty($mail_content) || empty($mail_subject) || $preview) | ||||||
|  | 	return; | ||||||
|  |  | ||||||
| $success = 0; | $success = 0; | ||||||
| $failed = 0; | $failed = 0; | ||||||
|  |  | ||||||
| 	$query = Account::where('email', '!=', ''); | $add = ''; | ||||||
|  | if ($config['account_mail_verify']) { | ||||||
| 	if ($mail_verified_only) { | 	note('Note: Sending only to users with verified E-Mail.'); | ||||||
| 		info('Note: Sending only to users with verified E-Mail.'); | 	$add = ' AND ' . $db->fieldName('email_verified') . ' = 1'; | ||||||
| 		$query->where('email_verified', 1); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| 	foreach ($query->get(['email']) as $email) { | $query = $db->query('SELECT ' . $db->fieldName('email') . ' FROM ' . $db->tableName('accounts') . ' WHERE ' . $db->fieldName('email') . ' != ""' . $add); | ||||||
| 		if (_mail($email->email, $mail_subject, $mail_content)) { | foreach ($query as $email) { | ||||||
|  | 	if (_mail($email['email'], $mail_subject, $mail_content)) | ||||||
| 		$success++; | 		$success++; | ||||||
| 		} |  | ||||||
| 	else { | 	else { | ||||||
| 		$failed++; | 		$failed++; | ||||||
| 		echo '<br />'; | 		echo '<br />'; | ||||||
| 			error('An error occorred while sending email to <b>' . $email->email . '</b>. For Admin: More info can be found in system/logs/mailer-error.log'); | 		error('An error occorred while sending email to <b>' . $email['email'] . '</b>. For Admin: More info can be found in system/logs/mailer-error.log'); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| success('Mailing finished.'); | success('Mailing finished.'); | ||||||
| success("$success emails delivered."); | success("$success emails delivered."); | ||||||
| warning("$failed emails failed."); | warning("$failed emails failed."); | ||||||
| } |  | ||||||
|  |  | ||||||
| $twig->display('admin.mailer.html.twig', [ |  | ||||||
| 	'mail_to' => $mail_to, |  | ||||||
| 	'mail_subject' => $mail_subject, |  | ||||||
| 	'mail_content' => $mail_content, |  | ||||||
| 	'mail_verified_only' => $mail_verified_only, |  | ||||||
| ]); |  | ||||||
|   | |||||||
| @@ -1,174 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Account Admin Tool |  | ||||||
|  * |  | ||||||
|  * @package   MyAAC |  | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  | ||||||
|  * @author    Lee |  | ||||||
|  * @author    gpedro |  | ||||||
|  * @copyright 2020 MyAAC |  | ||||||
|  * @link      https://my-aac.org |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $title = 'Mass Account Actions'; |  | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| $hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); |  | ||||||
| $freePremium = getBoolean(configLua('freePremium')); |  | ||||||
|  |  | ||||||
| function admin_give_points($points): void |  | ||||||
| { |  | ||||||
| 	global $hasPointsColumn; |  | ||||||
|  |  | ||||||
| 	if (!$hasPointsColumn) { |  | ||||||
| 		displayMessage('Points not supported.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (!Account::query()->increment('premium_points', $points)) { |  | ||||||
| 		displayMessage('Failed to add points.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 	displayMessage($points . ' points added to all accounts.', true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function admin_give_coins($coins): void |  | ||||||
| { |  | ||||||
| 	if (!HAS_ACCOUNT_COINS) { |  | ||||||
| 		displayMessage('Coins not supported.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (!Account::query()->increment('coins', $coins)) { |  | ||||||
| 		displayMessage('Failed to add coins.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	displayMessage($coins . ' coins added to all accounts.', true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function admin_give_premdays($days): void |  | ||||||
| { |  | ||||||
| 	global $db, $freePremium; |  | ||||||
|  |  | ||||||
| 	if ($freePremium) { |  | ||||||
| 		displayMessage('Premium days not supported. Free Premium enabled.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$value = $days * 86400; |  | ||||||
| 	$now = time(); |  | ||||||
|  |  | ||||||
| 	// othire |  | ||||||
| 	if ($db->hasColumn('accounts', 'premend')) { |  | ||||||
| 		// append premend |  | ||||||
| 		if (Account::where('premend', '>', $now)->increment('premend', $value)) { |  | ||||||
| 			// set premend |  | ||||||
| 			if (Account::where('premend', '<=', $now)->update(['premend' => $now + $value])) { |  | ||||||
| 				displayMessage($days . ' premium days added to all accounts.', true); |  | ||||||
| 			} else { |  | ||||||
| 				displayMessage('Failed to execute set query.'); |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			displayMessage('Failed to execute append query.'); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// tfs 0.x |  | ||||||
| 	if ($db->hasColumn('accounts', 'premdays')) { |  | ||||||
| 		// append premdays |  | ||||||
| 		if (Account::query()->update(['premdays' => $days])) { |  | ||||||
| 			// append lastday |  | ||||||
| 			if (Account::where('lastday', '>', $now)->increment('lastday', $value)) { |  | ||||||
| 				// set lastday |  | ||||||
| 				if (Account::where('lastday', '<=', $now)->update(['lastday' => $now + $value])) { |  | ||||||
| 					displayMessage($days . ' premium days added to all accounts.', true); |  | ||||||
| 				} else { |  | ||||||
| 					displayMessage('Failed to execute set query.'); |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				displayMessage('Failed to execute append query.'); |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			displayMessage('Failed to execute set days query.'); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// tfs 1.x |  | ||||||
| 	if ($db->hasColumn('accounts', 'premium_ends_at')) { |  | ||||||
| 		// append premium_ends_at |  | ||||||
| 		if (Account::where('premium_ends_at', '>', $now)->increment('premium_ends_at', $value)) { |  | ||||||
| 			// set premium_ends_at |  | ||||||
| 			if (Account::where('premium_ends_at', '<=', $now)->update(['premium_ends_at' => $now + $value])) { |  | ||||||
| 				displayMessage($days . ' premium days added to all accounts.', true); |  | ||||||
| 			} else { |  | ||||||
| 				displayMessage('Failed to execute set query.'); |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			displayMessage('Failed to execute append query.'); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	displayMessage('Premium Days not supported.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (!empty(ACTION) && isRequestMethod('post')) { |  | ||||||
|  |  | ||||||
| 	$action = ACTION; |  | ||||||
|  |  | ||||||
| 	if (preg_match("/[^A-z0-9_\-]/", $action)) { |  | ||||||
| 		displayMessage('Invalid action.'); |  | ||||||
| 	} else { |  | ||||||
| 		$value = isset($_POST['value']) ? intval($_POST['value']) : 0; |  | ||||||
|  |  | ||||||
| 		if (!$value) { |  | ||||||
| 			displayMessage('Please fill all inputs'); |  | ||||||
| 		} else { |  | ||||||
| 			switch ($action) { |  | ||||||
| 				case 'give-points': |  | ||||||
| 					admin_give_points($value); |  | ||||||
| 					break; |  | ||||||
| 				case 'give-coins': |  | ||||||
| 					admin_give_coins($value); |  | ||||||
| 					break; |  | ||||||
| 				case 'give-premdays': |  | ||||||
| 					admin_give_premdays($value); |  | ||||||
| 					break; |  | ||||||
| 				default: |  | ||||||
| 					displayMessage('Action ' . $action . 'not found.'); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| 	$twig->display('admin.tools.account.html.twig', array( |  | ||||||
| 		'hasCoinsColumn' => HAS_ACCOUNT_COINS, |  | ||||||
| 		'hasPointsColumn' => $hasPointsColumn, |  | ||||||
| 		'freePremium' => $freePremium, |  | ||||||
| 	)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function displayMessage($message, $success = false): void |  | ||||||
| { |  | ||||||
| 	global $twig, $hasPointsColumn, $freePremium; |  | ||||||
|  |  | ||||||
| 	$success ? success($message): error($message); |  | ||||||
|  |  | ||||||
| 	$twig->display('admin.tools.account.html.twig', array( |  | ||||||
| 		'hasCoinsColumn' => HAS_ACCOUNT_COINS, |  | ||||||
| 		'hasPointsColumn' => $hasPointsColumn, |  | ||||||
| 		'freePremium' => $freePremium, |  | ||||||
| 	)); |  | ||||||
| } |  | ||||||
| @@ -1,107 +0,0 @@ | |||||||
| <?php |  | ||||||
| /** |  | ||||||
|  * Teleport Admin Tool |  | ||||||
|  * |  | ||||||
|  * @package   MyAAC |  | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  | ||||||
|  * @author    Lee |  | ||||||
|  * @copyright 2020 MyAAC |  | ||||||
|  * @link      https://my-aac.org |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| use MyAAC\Models\Player; |  | ||||||
| use MyAAC\Models\PlayerOnline; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $title = 'Mass Teleport Actions'; |  | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| function admin_teleport_position($x, $y, $z) { |  | ||||||
| 	if (!Player::query()->update([ |  | ||||||
| 		'posx' => $x, 'posy' => $y, 'posz' => $z |  | ||||||
| 	])) { |  | ||||||
| 		displayMessage('Failed to execute query. Probably already updated.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	displayMessage('Player\'s position updated.', true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function admin_teleport_town($town_id) { |  | ||||||
| 	if (!Player::query()->update([ |  | ||||||
| 		'town_id' => $town_id, |  | ||||||
| 	])) { |  | ||||||
| 		displayMessage('Failed to execute query. Probably already updated.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	displayMessage('Player\'s town updated.', true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (!empty(ACTION) && isRequestMethod('post'))    { |  | ||||||
|  |  | ||||||
| 	$action = ACTION; |  | ||||||
|  |  | ||||||
| 	if (preg_match("/[^A-z0-9_\-]/", $action)) { |  | ||||||
| 		displayMessage('Invalid action.'); |  | ||||||
| 	} else { |  | ||||||
|  |  | ||||||
| 		$playersOnline = 0; |  | ||||||
| 		if($db->hasTable('players_online')) {// tfs 1.0 |  | ||||||
| 			$playersOnline = PlayerOnline::count(); |  | ||||||
| 		} else { |  | ||||||
| 			$playersOnline = Player::online()->count(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if ($playersOnline > 0) { |  | ||||||
| 			displayMessage('Please, close the server before execute this action otherwise players will not be affected.'); |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		$town_id = isset($_POST['town_id']) ? intval($_POST['town_id']) : null; |  | ||||||
| 		$posx = isset($_POST['posx']) ? intval($_POST['posx']) : null; |  | ||||||
| 		$posy = isset($_POST['posy']) ? intval($_POST['posy']) : null; |  | ||||||
| 		$posz = isset($_POST['posz']) ? intval($_POST['posz']) : null; |  | ||||||
| 		$to_temple = $_POST['to_temple'] ?? null; |  | ||||||
|  |  | ||||||
| 		switch ($action) { |  | ||||||
| 			case 'set-town': |  | ||||||
| 				if (!$town_id) { |  | ||||||
| 					displayMessage('Please fill all inputs'); |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				if (!isset($config['towns'][$town_id])) { |  | ||||||
| 					displayMessage('Specified town does not exist'); |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				admin_teleport_town($town_id); |  | ||||||
| 				break; |  | ||||||
| 			case 'set-position': |  | ||||||
| 				if (!$to_temple &&  ($posx < 0 || $posx > 65535 || $posy < 0 || $posy > 65535|| $posz < 0 || $posz > 16)) { |  | ||||||
| 					displayMessage('Invalid Position'); |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				admin_teleport_position($posx, $posy, $posz); |  | ||||||
| 				break; |  | ||||||
| 			default: |  | ||||||
| 				displayMessage('Action ' . $action . 'not found.'); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| 	$twig->display('admin.tools.teleport.html.twig', array()); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| function displayMessage($message, $success = false) { |  | ||||||
| 	global $twig; |  | ||||||
|  |  | ||||||
| 	$success ? success($message): error($message); |  | ||||||
| 	$twig->display('admin.tools.teleport.html.twig', array()); |  | ||||||
| } |  | ||||||
| @@ -7,72 +7,52 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Cache\Cache; |  | ||||||
| use MyAAC\Models\Menu; |  | ||||||
| use MyAAC\Plugins; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Menus'; | $title = 'Menus'; | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $pluginThemes = Plugins::getThemes(); | if (isset($_REQUEST['template'])) { | ||||||
|  | 	$template = $_REQUEST['template']; | ||||||
|  |  | ||||||
| if (isset($_POST['template'])) { | 	if (isset($_REQUEST['menu'])) { | ||||||
| 	$template = $_POST['template']; | 		$post_menu = $_REQUEST['menu']; | ||||||
|  | 		$post_menu_link = $_REQUEST['menu_link']; | ||||||
| 	if (isset($_POST['save'])) { | 		$post_menu_blank = $_REQUEST['menu_blank']; | ||||||
| 		$post_menu = $_POST['menu'] ?? []; | 		$post_menu_color = $_REQUEST['menu_color']; | ||||||
| 		$post_menu_link = $_POST['menu_link'] ?? []; |  | ||||||
| 		$post_menu_blank = $_POST['menu_blank'] ?? []; |  | ||||||
| 		$post_menu_color = $_POST['menu_color'] ?? []; |  | ||||||
| 		if (count($post_menu) != count($post_menu_link)) { | 		if (count($post_menu) != count($post_menu_link)) { | ||||||
| 			echo 'Menu count is not equal menu links. Something went wrong when sending form.'; | 			echo 'Menu count is not equal menu links. Something went wrong when sending form.'; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Menu::where('template', $template)->delete(); | 		$db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template)); | ||||||
| 		foreach ($post_menu as $category => $menus) { | 		foreach ($post_menu as $category => $menus) { | ||||||
| 			foreach ($menus as $i => $menu) { | 			foreach ($menus as $i => $menu) { | ||||||
| 				if (empty($menu)) // don't save empty menu item | 				if (empty($menu)) // don't save empty menu item | ||||||
| 					continue; | 					continue; | ||||||
|  |  | ||||||
| 				try { | 				try { | ||||||
| 					Menu::create([ | 					$db->insert(TABLE_PREFIX . 'menu', array('template' => $template, 'name' => $menu, 'link' => $post_menu_link[$category][$i], 'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, 'color' => str_replace('#', '', $post_menu_color[$category][$i]), 'category' => $category, 'ordering' => $i)); | ||||||
| 						'template' => $template, |  | ||||||
| 						'name' => $menu, |  | ||||||
| 						'link' => $post_menu_link[$category][$i], |  | ||||||
| 						'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, |  | ||||||
| 						'color' => str_replace('#', '', $post_menu_color[$category][$i]), |  | ||||||
| 						'category' => $category, |  | ||||||
| 						'ordering' => $i |  | ||||||
| 					]); |  | ||||||
| 				} catch (PDOException $error) { | 				} catch (PDOException $error) { | ||||||
| 					warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage()); | 					warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage()); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		onTemplateMenusChange(); | 		$cache = Cache::getInstance(); | ||||||
|  | 		if ($cache->enabled()) { | ||||||
|  | 			$cache->delete('template_menus'); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		success('Saved at ' . date('H:i')); | 		success('Saved at ' . date('H:i')); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	$path = TEMPLATES . $template; | 	$file = TEMPLATES . $template . '/config.php'; | ||||||
|  | 	if (file_exists($file)) { | ||||||
| 	if (isset($pluginThemes[$template])) { | 		require_once $file; | ||||||
| 		$path = BASE . $pluginThemes[$template]; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$path .= '/config.php'; |  | ||||||
|  |  | ||||||
| 	if (file_exists($path)) { |  | ||||||
| 		require_once $path; |  | ||||||
| 	} else { | 	} else { | ||||||
| 		echo 'Cannot find template config.php file.'; | 		echo 'Cannot find template config.php file.'; | ||||||
| 		return; | 		return; | ||||||
| @@ -83,115 +63,70 @@ if (isset($_POST['template'])) { | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (isset($_GET['reset_colors'])) { | 	echo 'Hint: You can drag menu items.<br/> | ||||||
| 		foreach ($config['menu_categories'] as $id => $options) { | 	Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/> | ||||||
| 			$color = $options['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff')); | 	Not all templates support blank and colorful links.<br/><br/> | ||||||
| 			Menu::where('template', $template)->where('category', $id)->update(['color' => str_replace('#', '', $color)]); |     <div class="row">'; | ||||||
|  | 	$menus = array(); | ||||||
|  | 	$menus_db = $db->query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll(); | ||||||
|  | 	foreach ($menus_db as $menu) { | ||||||
|  | 		$menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 		onTemplateMenusChange(); |  | ||||||
| 		success('Colors has been reset at ' . date('H:i')); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (isset($_GET['reset_menus'])) { |  | ||||||
| 		$configMenus = config('menus'); |  | ||||||
| 		if (isset($configMenus)) { |  | ||||||
| 			Plugins::installMenus($template, config('menus'), true); |  | ||||||
|  |  | ||||||
| 			onTemplateMenusChange(); |  | ||||||
| 			success('Menus has been reset at ' . date('H:i')); |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			error("This template don't support reinstalling menus."); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$title = 'Menus - ' . $template; |  | ||||||
|  |  | ||||||
| 	$canResetColors = isset($config['menu_default_color']) || isset($config['menu_default_links_color']); |  | ||||||
| 	foreach ($config['menu_categories'] as $id => $options) { |  | ||||||
| 		if (isset($options['default_links_color'])) { |  | ||||||
| 			$canResetColors = true; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$twig->display('admin.menus.header.html.twig', [ |  | ||||||
| 		'template' => $template, |  | ||||||
| 		'canResetColors' => $canResetColors |  | ||||||
| 	]); |  | ||||||
| 	?> |  | ||||||
| 	<?php |  | ||||||
| 	$menus = Menu::query() |  | ||||||
| 		->select('name', 'link', 'blank', 'color', 'category', 'ordering') |  | ||||||
| 		->where('enabled', 1) |  | ||||||
| 		->where('template', $template) |  | ||||||
| 		->orderBy('ordering') |  | ||||||
| 		->get() |  | ||||||
| 		->groupBy('category') |  | ||||||
| 		->toArray(); |  | ||||||
|  |  | ||||||
| 	$last_id = array(); | 	$last_id = array(); | ||||||
| 	?> | 	echo '<form method="post" id="menus-form" action="?p=menus">'; | ||||||
| 	<form method="post" id="menus-form" action="?p=menus"> | 	echo '<input type="hidden" name="template" value="' . $template . '"/>'; | ||||||
| 		<?php csrf(); ?> | 	foreach ($config['menu_categories'] as $id => $cat) { | ||||||
| 		<input type="hidden" name="template" value="<?php echo $template ?>"/> | 		echo '        <div class="col-md-12 col-lg-6"> | ||||||
| 		<button type="submit" name="save" class="btn btn-info">Save</button><br/><br/> |             <div class="box box-danger"> | ||||||
| 		<div class="row"> |                 <div class="box-header with-border"> | ||||||
| 			<?php foreach ($config['menu_categories'] as $id => $cat): ?> |                     <h3 class="box-title">' . $cat['name'] . ' <img class="add-button" id="add-button-' . $id . '" src="' . BASE_URL . 'images/plus.png" width="16" height="16"/></h3> | ||||||
| 				<div class="col-md-12 col-lg-6"> |  | ||||||
| 					<div class="card card-info card-outline"> |  | ||||||
| 						<div class="card-header"> |  | ||||||
| 							<h5 class="m-0"><?php echo $cat['name'] ?> <i class="far fa-plus-square add-button" id="add-button-<?php echo $id ?>"></i></h5> |  | ||||||
|                 </div> |                 </div> | ||||||
| 						<div class="card-body"> |                 <div class="box-body">'; | ||||||
| 							<ul class="sortable" id="sortable-<?php echo $id ?>"> |  | ||||||
| 								<?php |  | ||||||
|  | 		echo '<ul class="sortable" id="sortable-' . $id . '">'; | ||||||
| 		if (isset($menus[$id])) { | 		if (isset($menus[$id])) { | ||||||
| 			$i = 0; | 			$i = 0; | ||||||
| 									foreach ($menus[$id] as $menu): | 			foreach ($menus[$id] as $menu) { | ||||||
| 										$color = (empty($menu['color']) ? ($cat['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'))) : '#' . $menu['color']); | 				echo '<li class="ui-state-default" id="list-' . $id . '-' . $i . '"><label>Name:</label><input type="text" name="menu[' . $id . '][]" value="' . escapeHtml($menu['name']) . '"/> | ||||||
| 										?> | 				<label>Link:</label><input type="text" name="menu_link[' . $id . '][]" value="' . $menu['link'] . '"/> | ||||||
| 										<li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/> | 				<input type="hidden" name="menu_blank[' . $id . '][]" value="0" /> | ||||||
| 											<label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/> | 				<label><input class="blank-checkbox" type="checkbox" ' . ($menu['blank'] == 1 ? 'checked' : '') . '/><span title="Open in New Window">Open in New Window</span></label> | ||||||
| 											<input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/> |  | ||||||
| 											<label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label> |  | ||||||
| 											<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo $color; ?>"/> |  | ||||||
| 											<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li> |  | ||||||
| 										<?php $i++; $last_id[$id] = $i; |  | ||||||
| 									endforeach; |  | ||||||
| 								} ?> |  | ||||||
| 							</ul> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
| 				</div> |  | ||||||
| 			<?php endforeach ?> |  | ||||||
| 		</div> |  | ||||||
| 		<div class="row pb-2"> |  | ||||||
| 			<div class="col-md-12"> |  | ||||||
| 				<button type="submit" name="save" class="btn btn-info">Save</button> |  | ||||||
| 				<?php |  | ||||||
| 				echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>'; |  | ||||||
| 				?> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	</form> |  | ||||||
| 	<?php |  | ||||||
| 	$twig->display('admin.menus.js.html.twig', array( |  | ||||||
| 		'menus' => $menus, |  | ||||||
| 		'last_id' => $last_id, |  | ||||||
| 	)); |  | ||||||
| 	?> |  | ||||||
| 	<?php |  | ||||||
| } else { |  | ||||||
| 	$templates = Menu::select('template')->distinct()->get()->toArray(); |  | ||||||
| 	foreach ($templates as $key => $value) { |  | ||||||
| 		$path = TEMPLATES . $value['template']; |  | ||||||
| 				 | 				 | ||||||
| 		if (isset($pluginThemes[$value['template']])) { | 				<input class="color-picker" type="text" name="menu_color[' . $id . '][]" value="#' . $menu['color'] . '" /> | ||||||
| 			$path = BASE . $pluginThemes[$value['template']]; | 				 | ||||||
|  | 				<a class="remove-button" id="remove-button-' . $id . '-' . $i . '"><img src="' . BASE_URL . 'images/del.png"/></a></li>'; | ||||||
|  |  | ||||||
|  | 				$i++; | ||||||
|  | 				$last_id[$id] = $i; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (!file_exists($path . '/config.php')) { | 		echo '</ul>'; | ||||||
|  | 		echo '                </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  | '; | ||||||
|  | 	} | ||||||
|  | 	echo ' </div><div class="row"><div class="col-md-6">'; | ||||||
|  | 	echo '<input type="submit" class="btn btn-info" value="Save">'; | ||||||
|  | 	echo '<input type="button" class="btn btn-default pull-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus&template=' . $template . '\';">'; | ||||||
|  | 	echo '</div></div>'; | ||||||
|  | 	echo '</form>'; | ||||||
|  |  | ||||||
|  | 	$twig->display('admin.menus.js.html.twig', array( | ||||||
|  | 		'menus' => $menus, | ||||||
|  | 		'last_id' => $last_id | ||||||
|  | 	)); | ||||||
|  | 	?> | ||||||
|  |  | ||||||
|  | 	<?php | ||||||
|  | } else { | ||||||
|  | 	$templates = $db->query('SELECT `template` FROM `' . TABLE_PREFIX . 'menu` GROUP BY `template`;')->fetchAll(); | ||||||
|  | 	foreach ($templates as $key => $value) { | ||||||
|  | 		$file = TEMPLATES . $value['template'] . '/config.php'; | ||||||
|  | 		if (!file_exists($file)) { | ||||||
| 			unset($templates[$key]); | 			unset($templates[$key]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -200,11 +135,3 @@ if (isset($_POST['template'])) { | |||||||
| 		'templates' => $templates | 		'templates' => $templates | ||||||
| 	)); | 	)); | ||||||
| } | } | ||||||
|  |  | ||||||
| function onTemplateMenusChange(): void |  | ||||||
| { |  | ||||||
| 	$cache = Cache::getInstance(); |  | ||||||
| 	if ($cache->enabled()) { |  | ||||||
| 		$cache->delete('template_menus'); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,15 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| use MyAAC\Models\Player; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $balance = 0; |  | ||||||
|  |  | ||||||
| if ($db->hasColumn('players', 'balance')) { |  | ||||||
| 	$balance = Player::orderByDesc('balance')->limit(10)->get(['id', 'name', 'balance'])->toArray(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $twig->display('balance.html.twig', array( |  | ||||||
| 	'balance' => $balance |  | ||||||
| )); |  | ||||||
| @@ -1,18 +1,9 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; | if ($db->hasColumn('accounts', 'coins')) { | ||||||
|  | 	$coins = $db->query('SELECT `coins`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `coins` DESC LIMIT 10;'); | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | } else { | ||||||
|  |  | ||||||
| 	$coins = 0; | 	$coins = 0; | ||||||
|  |  | ||||||
| if (HAS_ACCOUNT_COINS) { |  | ||||||
| 	$whatToGet = ['id', 'coins']; |  | ||||||
| 	if (USE_ACCOUNT_NAME) { |  | ||||||
| 		$whatToGet[] = 'name'; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$coins = Account::orderByDesc('coins')->limit(10)->get($whatToGet)->toArray(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('coins.html.twig', array( | $twig->display('coins.html.twig', array( | ||||||
|   | |||||||
| @@ -1,15 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $accounts = 0; |  | ||||||
|  |  | ||||||
| if ($db->hasColumn('accounts', 'created')) { |  | ||||||
| 	$accounts = Account::orderByDesc('created')->limit(10)->get(['id', 'created'])->toArray(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $twig->display('created.html.twig', array( |  | ||||||
| 	'accounts' => $accounts, |  | ||||||
| )); |  | ||||||
| @@ -1,13 +1,9 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| use MyAAC\Models\Player; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $players = 0; |  | ||||||
|  |  | ||||||
| if ($db->hasColumn('players', 'lastlogin')) { | if ($db->hasColumn('players', 'lastlogin')) { | ||||||
| 	$players = Player::orderByDesc('lastlogin')->limit(10)->get(['id', 'name', 'level', 'lastlogin'])->toArray(); | 	$players = $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;'); | ||||||
|  | } else { | ||||||
|  | 	$players = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('lastlogin.html.twig', array( | $twig->display('lastlogin.html.twig', array( | ||||||
|   | |||||||
| @@ -1,13 +1,8 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $points = 0; |  | ||||||
|  |  | ||||||
| if ($db->hasColumn('accounts', 'premium_points')) { | if ($db->hasColumn('accounts', 'premium_points')) { | ||||||
| 	$coins = Account::orderByDesc('premium_points')->limit(10)->get(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray(); | 	$points = $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;'); | ||||||
|  | } else { | ||||||
|  | 	$points = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('points.html.twig', array( | $twig->display('points.html.twig', array( | ||||||
|   | |||||||
| @@ -1,46 +0,0 @@ | |||||||
| <?php |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
| if (isset($status)) { |  | ||||||
|  |  | ||||||
| 	$error_icon = '<i class="fas fa-exclamation-circle text-danger"></i>'; ?> |  | ||||||
| 	<div class=" col-md-6 col-lg-6"> |  | ||||||
| 		<div class="card card-info card-outline"> |  | ||||||
| 			<div class="card-header border-bottom-0"> |  | ||||||
| 				<span class="font-weight-bold m-0">Server Status</span> <span class="float-right small"><b>Last checked</b>: <?php echo(isset($status['lastCheck']) ? date("l, d.m.Y H:i:s", $status['lastCheck']) : $error_icon); ?></span> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="card-body p-0 "> |  | ||||||
| 				<table class="table"> |  | ||||||
| 					<tbody> |  | ||||||
| 					<tr> |  | ||||||
| 						<th width="30%">Server</th> |  | ||||||
| 						<td><?php echo(isset($status['server']) & isset($status['serverVersion']) ? $status['server'] . ' x ' . $status['serverVersion'] : $error_icon) ?></td> |  | ||||||
|  |  | ||||||
| 					</tr> |  | ||||||
| 					<tr> |  | ||||||
| 						<th>Client</th> |  | ||||||
| 						<td><?php echo(isset($status['clientVersion']) ? $status['clientVersion'] : $error_icon) ?></td> |  | ||||||
| 					</tr> |  | ||||||
| 					<tr> |  | ||||||
| 						<th>Map</th> |  | ||||||
| 						<td> |  | ||||||
| 							<?php if (isset($status['mapName']) & isset($status['mapAuthor']) & isset($status['mapWidth']) & isset($status['mapHeight'])) { |  | ||||||
| 								echo $status['mapName'] . ' by <b>' . $status['mapAuthor'] . '</b><br/>' . $status['mapWidth'] . ' x ' . $status['mapHeight']; |  | ||||||
| 							} else { |  | ||||||
| 								echo $error_icon; |  | ||||||
| 							} ?> |  | ||||||
| 						</td> |  | ||||||
| 					</tr> |  | ||||||
| 					<tr> |  | ||||||
| 						<th>Monsters</th> |  | ||||||
| 						<td><?php echo (isset($status['monsters']) ? $status['monsters'] : $error_icon); ?></td> |  | ||||||
| 					</tr> |  | ||||||
| 					<tr> |  | ||||||
| 						<th>MOTD:</th> |  | ||||||
| 						<td><?php echo(isset($status['motd']) ? $status['motd'] : $error_icon); ?></td> |  | ||||||
| 					</tr> |  | ||||||
| 					</tbody> |  | ||||||
| 				</table> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| <?php } ?> |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; |  | ||||||
| use MyAAC\Models\Guild; |  | ||||||
| use MyAAC\Models\House; |  | ||||||
| use MyAAC\Models\Monster; |  | ||||||
| use MyAAC\Models\Player; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
| $count = $eloquentConnection->query() |  | ||||||
| 	->select([ |  | ||||||
| 		'total_accounts' => Account::selectRaw('COUNT(id)'), |  | ||||||
| 		'total_players' => Player::selectRaw('COUNT(id)'), |  | ||||||
| 		'total_guilds' => Guild::selectRaw('COUNT(id)'), |  | ||||||
| 		'total_monsters' => Monster::selectRaw('COUNT(id)'), |  | ||||||
| 		'total_houses' => House::selectRaw('COUNT(id)'), |  | ||||||
| 	])->first(); |  | ||||||
|  |  | ||||||
| $twig->display('statistics.html.twig', array( |  | ||||||
| 	'count' => $count, |  | ||||||
| )); |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| {% if balance is iterable %} |  | ||||||
| 	<div class=" col-md-6 col-lg-3"> |  | ||||||
| 		<div class="card card-info card-outline"> |  | ||||||
| 			<div class="card-header"> |  | ||||||
| 				<h5 class="m-0">Top 10 - Balance</h5> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="card-body p-0"> |  | ||||||
| 				<table class="table table-striped table-condensed"> |  | ||||||
| 					<thead> |  | ||||||
| 					<tr> |  | ||||||
| 						<th>#</th> |  | ||||||
| 						<th>Player</th> |  | ||||||
| 						<th>Balance</th> |  | ||||||
| 					</tr> |  | ||||||
| 					</thead> |  | ||||||
| 					<tbody> |  | ||||||
| 					{% set i = 0 %} |  | ||||||
| 					{% for result in balance %} |  | ||||||
| 						{% set i = i + 1 %} |  | ||||||
| 						<tr> |  | ||||||
| 							<th>{{ i }}</th> |  | ||||||
| 							<td><a href="?p=players&id={{ result.id }}">{{ result.name }}</a></td> |  | ||||||
| 							<td>{{ result.balance }}</td> |  | ||||||
| 						</tr> |  | ||||||
| 					{% endfor %} |  | ||||||
| 					</tbody> |  | ||||||
| 				</table> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| {% endif %} |  | ||||||
| @@ -1,25 +1,23 @@ | |||||||
| {% if coins is iterable %} | {% if coins is iterable %} | ||||||
| 	<div class=" col-md-6 col-lg-3"> | 	<div class="col-md-3"> | ||||||
| 		<div class="card card-info card-outline"> | 		<div class="box"> | ||||||
| 			<div class="card-header"> | 			<div class="box-header"> | ||||||
| 				<h5 class="m-0">Top 10 - Most coins</h5> | 				<h3 class="box-title">Top 10 - Most coins</h3> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div class="card-body p-0"> | 			<div class="box-body no-padding"> | ||||||
| 				<table class="table table-striped table-condensed"> | 				<table class="table table-condensed"> | ||||||
| 					<thead> | 					<tbody> | ||||||
| 					<tr> | 					<tr> | ||||||
| 						<th>#</th> | 						<th>#</th> | ||||||
| 						<th>Account</th> | 						<th>Account {{ account_type }}</th> | ||||||
| 						<th>Tibia coins</th> | 						<th>Tibia coins</th> | ||||||
| 					</tr> | 					</tr> | ||||||
| 					</thead> |  | ||||||
| 					<tbody> |  | ||||||
| 					{% set i = 0 %} | 					{% set i = 0 %} | ||||||
| 					{% for result in coins %} | 					{% for result in coins %} | ||||||
| 						{% set i = i + 1 %} | 						{% set i = i + 1 %} | ||||||
| 						<tr> | 						<tr> | ||||||
| 							<th>{{ i }}</th> | 							<td>{{ i }}</td> | ||||||
| 							<td><a href="?p=accounts&id={{ result.id }}">{{ result.name ?? result.id }}</a></td> | 							<td>{{ result.name }}</td> | ||||||
| 							<td>{{ result.coins }}</td> | 							<td>{{ result.coins }}</td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{% endfor %} | 					{% endfor %} | ||||||
|   | |||||||
| @@ -1,31 +0,0 @@ | |||||||
| {% if accounts is iterable %} |  | ||||||
| 	<div class=" col-md-6 col-lg-3"> |  | ||||||
| 		<div class="card card-info card-outline"> |  | ||||||
| 			<div class="card-header"> |  | ||||||
| 				<h5 class="m-0">Last 10 created</h5> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="card-body p-0"> |  | ||||||
| 				<table class="table table-striped table-condensed"> |  | ||||||
| 					<thead> |  | ||||||
| 					<tr> |  | ||||||
| 						<th>#</th> |  | ||||||
| 						<th>Account</th> |  | ||||||
| 						<th>Creation Date</th> |  | ||||||
| 					</tr> |  | ||||||
| 					</thead> |  | ||||||
| 					<tbody> |  | ||||||
| 					{% set i = 0 %} |  | ||||||
| 					{% for result in accounts %} |  | ||||||
| 						{% set i = i + 1 %} |  | ||||||
| 						<tr> |  | ||||||
| 							<th>{{ i }}</th> |  | ||||||
| 							<td><a href="?p=accounts&id={{ result.id }}">{{ result.id }}</a></td> |  | ||||||
| 							<td>{{ result.created|date("M d Y, H:i:s") }}</td> |  | ||||||
| 						</tr> |  | ||||||
| 					{% endfor %} |  | ||||||
| 					</tbody> |  | ||||||
| 				</table> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| {% endif %} |  | ||||||
| @@ -1,25 +1,23 @@ | |||||||
| {% if players is iterable %} | {% if players is iterable %} | ||||||
| 	<div class=" col-md-6 col-lg-3"> | 	<div class="col-md-3"> | ||||||
| 		<div class="card card-info card-outline"> | 		<div class="box"> | ||||||
| 			<div class="card-header"> | 			<div class="box-header"> | ||||||
| 				<h5 class="m-0">Last 10 logins</h5> | 				<h3 class="box-title">Last 10 Logins</h3> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div class="card-body p-0"> | 			<div class="box-body no-padding"> | ||||||
| 				<table class="table table-striped table-condensed"> | 				<table class="table table-condensed"> | ||||||
| 					<thead> | 					<tbody> | ||||||
| 					<tr> | 					<tr> | ||||||
| 						<th>#</th> | 						<th>#</th> | ||||||
| 						<th>Player</th> | 						<th>Player</th> | ||||||
| 						<th>Login Date</th> | 						<th>Login Date</th> | ||||||
| 					</tr> | 					</tr> | ||||||
| 					</thead> |  | ||||||
| 					<tbody> |  | ||||||
| 					{% set i = 0 %} | 					{% set i = 0 %} | ||||||
| 					{% for result in players %} | 					{% for result in players %} | ||||||
| 						{% set i = i + 1 %} | 						{% set i = i + 1 %} | ||||||
| 						<tr> | 						<tr> | ||||||
| 							<th>{{ i }}</th> | 							<td>{{ i }}</td> | ||||||
| 							<td><a href="?p=players&id={{ result.id }}">{{ result.name }}</a></td> | 							<td>{{ result.name }}</td> | ||||||
| 							<td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td> | 							<td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{% endfor %} | 					{% endfor %} | ||||||
|   | |||||||
| @@ -1,25 +1,23 @@ | |||||||
| {% if points is iterable %} | {% if points is iterable %} | ||||||
| 	<div class=" col-md-6 col-lg-3"> | 	<div class="col-md-3"> | ||||||
| 		<div class="card card-info card-outline"> | 		<div class="box"> | ||||||
| 			<div class="card-header"> | 			<div class="box-header"> | ||||||
| 				<h5 class="m-0">Top 10 - Most premium points</h5> | 				<h3 class="box-title">Top 10 - Most premium points</h3> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div class="card-body p-0"> | 			<div class="box-body no-padding"> | ||||||
| 				<table class="table table-striped table-condensed"> | 				<table class="table table-condensed"> | ||||||
| 					<thead> | 					<tbody> | ||||||
| 					<tr> | 					<tr> | ||||||
| 						<th>#</th> | 						<th>#</th> | ||||||
| 						<th>Account</th> | 						<th>Account {{ account_type }}</th> | ||||||
| 						<th>Premium points</th> | 						<th>Premium points</th> | ||||||
| 					</tr> | 					</tr> | ||||||
| 					</thead> |  | ||||||
| 					<tbody> |  | ||||||
| 					{% set i = 0 %} | 					{% set i = 0 %} | ||||||
| 					{% for result in points %} | 					{% for result in points %} | ||||||
| 						{% set i = i + 1 %} | 						{% set i = i + 1 %} | ||||||
| 						<tr> | 						<tr> | ||||||
| 							<th>{{ i }}</th> | 							<td>{{ i }}</td> | ||||||
| 							<td><a href="?p=accounts&id={{ result.id }}">{{ result.name }}</a></td> | 							<td>{{ result.name }}</td> | ||||||
| 							<td>{{ result.premium_points }}</td> | 							<td>{{ result.premium_points }}</td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{% endfor %} | 					{% endfor %} | ||||||
|   | |||||||
| @@ -1,45 +0,0 @@ | |||||||
| <div class="col"> |  | ||||||
| 	<div class="info-box"> |  | ||||||
| 		<span class="info-box-icon bg-info elevation-1"><i class="fas fa-user-plus"></i></span> |  | ||||||
| 		<div class="info-box-content"> |  | ||||||
| 			<span class="info-box-text">Accounts:</span> |  | ||||||
| 			<span class="info-box-number">{{ count.total_accounts }}</span> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
| <div class="col"> |  | ||||||
| 	<div class="info-box"> |  | ||||||
| 		<span class="info-box-icon bg-red elevation-1"><i class="fas fa-user-plus"></i></span> |  | ||||||
| 		<div class="info-box-content"> |  | ||||||
| 			<span class="info-box-text">Players:</span> |  | ||||||
| 			<span class="info-box-number">{{ count.total_players }}</span> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
| <div class="col"> |  | ||||||
| 	<div class="info-box"> |  | ||||||
| 		<span class="info-box-icon bg-teal elevation-1"><i class="fas fa-pastafarianism"></i></span> |  | ||||||
| 		<div class="info-box-content"> |  | ||||||
| 			<span class="info-box-text">Monsters:</span> |  | ||||||
| 			<span class="info-box-number">{{ count.total_monsters }}</span> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
| <div class="col"> |  | ||||||
| 	<div class="info-box"> |  | ||||||
| 		<span class="info-box-icon bg-green elevation-1"><i class="fas fa-chart-pie"></i></span> |  | ||||||
| 		<div class="info-box-content"> |  | ||||||
| 			<span class="info-box-text">Guilds:</span> |  | ||||||
| 			<span class="info-box-number">{{ count.total_guilds }}</span> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
| <div class="col"> |  | ||||||
| 	<div class="info-box"> |  | ||||||
| 		<span class="info-box-icon bg-yellow elevation-1"><i class="fas fa-home"></i></span> |  | ||||||
| 		<div class="info-box-content"> |  | ||||||
| 			<span class="info-box-text">Houses:</span> |  | ||||||
| 			<span class="info-box-number">{{ count.total_houses }}</span> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| <div class="col-12 col-md-6"> |  | ||||||
| 	<div class="card card-warning card-outline"> |  | ||||||
| 		<div class="card-header"> |  | ||||||
| 			<span class="m-0">Website Status<span class="float-right"> |  | ||||||
| 			<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success"> |  | ||||||
| 				<input form="maintenance-form" type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}> |  | ||||||
| 				<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label> |  | ||||||
| 			</div></span> |  | ||||||
| 			</span> |  | ||||||
| 		</div> |  | ||||||
| 		<div class="card-body p-2"> |  | ||||||
| 			<div class="col-sm-12"> |  | ||||||
| 				<label for="message" class="col-form-label">Maintenance Message</label> |  | ||||||
| 				<textarea form="maintenance-form" name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea> |  | ||||||
| 				<small>(only visible if closed)</small> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 		<div class="card-footer"> |  | ||||||
| 			<form id="maintenance-form" method="post" action="?p=dashboard" class="float-left"> |  | ||||||
| 				{{ csrf() }} |  | ||||||
| 				<input type="hidden" name="maintenance" value="1" /> |  | ||||||
| 				<button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button> |  | ||||||
| 			</form> |  | ||||||
| 			<form method="post" action="?p=dashboard" class="float-right"> |  | ||||||
| 				{{ csrf() }} |  | ||||||
| 				<input type="hidden" name="clear_cache" value="1" /> |  | ||||||
| 				<button type="submit" onclick="return confirm('Are you sure that you want to clear cache?');" class="btn btn-danger" title="Clear Cache"><i class="fas fa-clear"></i>Clear cache</button> |  | ||||||
| 			</form> |  | ||||||
| 		</div> |  | ||||||
| 	</div> |  | ||||||
| </div> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| 	$(function() { |  | ||||||
| 		$("#status").change(function() { |  | ||||||
| 			$statusLabel = $("#status-label"); |  | ||||||
| 			$statusLabel.html("Closed"); |  | ||||||
| 			if ($(this).is(':checked')) { |  | ||||||
| 				$statusLabel.html("Open"); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| </script> |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| <?php |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
|  |  | ||||||
| $twig->display('web_status.twig', array( |  | ||||||
| 	'is_closed' => $is_closed, |  | ||||||
| 	'closed_message' => $closed_message, |  | ||||||
| 	'status' => $status, |  | ||||||
| 	'account_type' => USE_ACCOUNT_NAME ? 'name' : 'number' |  | ||||||
| )); |  | ||||||
| ?> |  | ||||||
| @@ -7,18 +7,13 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Forum; |  | ||||||
| use MyAAC\News; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
|  | require_once LIBS . 'forum.php'; | ||||||
|  | require_once LIBS . 'news.php'; | ||||||
|  |  | ||||||
| $title = 'News Panel'; | $title = 'News Panel'; | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| @@ -26,44 +21,45 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | |||||||
|  |  | ||||||
| header('X-XSS-Protection:0'); | header('X-XSS-Protection:0'); | ||||||
|  |  | ||||||
| // some constants, used mainly by database (cannot be modified without schema changes) | // some constants, used mainly by database (cannot by modified without schema changes) | ||||||
| const NEWS_TITLE_LIMIT = 100; | define('TITLE_LIMIT', 100); | ||||||
| const NEWS_BODY_LIMIT = 65535; // maximum news body length | define('BODY_LIMIT', 65535); // maximum news body length | ||||||
| const ARTICLE_TEXT_LIMIT = 300; | define('ARTICLE_TEXT_LIMIT', 300); | ||||||
| const ARTICLE_IMAGE_LIMIT = 100; | define('ARTICLE_IMAGE_LIMIT', 100); | ||||||
|  |  | ||||||
| $name = $p_title = ''; | $name = $p_title = ''; | ||||||
| if(!empty($action)) | if(!empty($action)) | ||||||
| { | { | ||||||
| 	$id = $_POST['id'] ?? null; | 	$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null; | ||||||
| 	$p_title = $_POST['title'] ?? null; | 	$p_title = isset($_REQUEST['title']) ? $_REQUEST['title'] : null; | ||||||
| 	$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; | 	$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null; | ||||||
| 	$comments = $_POST['comments'] ?? null; | 	$comments = isset($_REQUEST['comments']) ? $_REQUEST['comments'] : null; | ||||||
| 	$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : 1; | 	$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null; | ||||||
| 	$category = isset($_POST['category']) ? (int)$_POST['category'] : null; | 	$category = isset($_REQUEST['category']) ? (int)$_REQUEST['category'] : null; | ||||||
| 	$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null; | 	$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null; | ||||||
| 	$article_text = $_POST['article_text'] ?? null; | 	$article_text = isset($_REQUEST['article_text']) ? $_REQUEST['article_text'] : null; | ||||||
| 	$article_image = $_POST['article_image'] ?? null; | 	$article_image = isset($_REQUEST['article_image']) ? $_REQUEST['article_image'] : null; | ||||||
| 	$forum_section = $_POST['forum_section'] ?? null; | 	$forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null; | ||||||
| 	$errors = []; | 	$errors = array(); | ||||||
|  |  | ||||||
| 	if (isRequestMethod('post')) { | 	if($action == 'add') { | ||||||
| 		if ($action == 'new') { |  | ||||||
| 		if(isset($forum_section) && $forum_section != '-1') { | 		if(isset($forum_section) && $forum_section != '-1') { | ||||||
| 			$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); | 			$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 			if (isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { | 		if(News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { | ||||||
| 			$p_title = $body = $comments = $article_text = $article_image = ''; | 			$p_title = $body = $comments = $article_text = $article_image = ''; | ||||||
| 			$type = $category = $player_id = 0; | 			$type = $category = $player_id = 0; | ||||||
|  |  | ||||||
| 				success('Added successful.'); | 			success("Added successful."); | ||||||
| 		} | 		} | ||||||
| 		} else if ($action == 'delete') { |  | ||||||
| 			if (News::delete($id, $errors)) { |  | ||||||
| 				success('Deleted successful.'); |  | ||||||
| 	} | 	} | ||||||
| 		} else if ($action == 'edit') { | 	else if($action == 'delete') { | ||||||
|  | 		News::delete($id, $errors); | ||||||
|  | 		success("Deleted successful."); | ||||||
|  | 	} | ||||||
|  | 	else if($action == 'edit') | ||||||
|  | 	{ | ||||||
| 		if(isset($id) && !isset($p_title)) { | 		if(isset($id) && !isset($p_title)) { | ||||||
| 			$news = News::get($id); | 			$news = News::get($id); | ||||||
| 			$p_title = $news['title']; | 			$p_title = $news['title']; | ||||||
| @@ -74,7 +70,8 @@ if(!empty($action)) | |||||||
| 			$player_id = $news['player_id']; | 			$player_id = $news['player_id']; | ||||||
| 			$article_text = $news['article_text']; | 			$article_text = $news['article_text']; | ||||||
| 			$article_image = $news['article_image']; | 			$article_image = $news['article_image']; | ||||||
| 			} else { | 		} | ||||||
|  | 		else { | ||||||
| 			if(News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) { | 			if(News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) { | ||||||
| 				// update forum thread if exists | 				// update forum thread if exists | ||||||
| 				if(isset($forum_section) && Validator::number($forum_section)) { | 				if(isset($forum_section) && Validator::number($forum_section)) { | ||||||
| @@ -84,14 +81,13 @@ if(!empty($action)) | |||||||
| 				$action = $p_title = $body = $comments = $article_text = $article_image = ''; | 				$action = $p_title = $body = $comments = $article_text = $article_image = ''; | ||||||
| 				$type = $category = $player_id = 0; | 				$type = $category = $player_id = 0; | ||||||
|  |  | ||||||
| 					success('Updated successful.'); | 				success("Updated successful."); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		} else if ($action == 'hide') { |  | ||||||
| 			if (News::toggleHide($id, $errors, $status)) { |  | ||||||
| 				success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); |  | ||||||
| 			} |  | ||||||
| 	} | 	} | ||||||
|  | 	else if($action == 'hide') { | ||||||
|  | 		News::toggleHidden($id, $errors, $status); | ||||||
|  | 		success(($status == 1 ? 'Show' : 'Hide') . " successful."); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if(!empty($errors)) | 	if(!empty($errors)) | ||||||
| @@ -99,7 +95,7 @@ if(!empty($action)) | |||||||
| } | } | ||||||
|  |  | ||||||
| $categories = array(); | $categories = array(); | ||||||
| foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hide` != 1') as $cat) | foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hidden` != 1') as $cat) | ||||||
| { | { | ||||||
| 	$categories[$cat['id']] = array( | 	$categories[$cat['id']] = array( | ||||||
| 		'name' => $cat['name'], | 		'name' => $cat['name'], | ||||||
| @@ -117,46 +113,39 @@ if($action == 'edit' || $action == 'new') { | |||||||
| 	$account_players->orderBy('group_id', POT::ORDER_DESC); | 	$account_players->orderBy('group_id', POT::ORDER_DESC); | ||||||
| 	$twig->display('admin.news.form.html.twig', array( | 	$twig->display('admin.news.form.html.twig', array( | ||||||
| 		'action' => $action, | 		'action' => $action, | ||||||
| 		'news_id' => $id ?? null, | 		'news_link' => getLink(PAGE), | ||||||
| 		'title' => $p_title ?? '', | 		'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'add'), | ||||||
|  | 		'news_id' => isset($id) ? $id : null, | ||||||
|  | 		'title' => isset($p_title) ? $p_title : '', | ||||||
| 		'body' => isset($body) ? escapeHtml($body) : '', | 		'body' => isset($body) ? escapeHtml($body) : '', | ||||||
| 		'type' => $type, | 		'type' => isset($type) ? $type : null, | ||||||
| 		'player' => isset($player) && $player->isLoaded() ? $player : null, | 		'player' => isset($player) && $player->isLoaded() ? $player : null, | ||||||
| 		'player_id' => $player_id ?? null, | 		'player_id' => isset($player_id) ? $player_id : null, | ||||||
| 		'account_players' => $account_players, | 		'account_players' => $account_players, | ||||||
| 		'category' => $category ?? 0, | 		'category' => isset($category) ? $category : 0, | ||||||
| 		'categories' => $categories, | 		'categories' => $categories, | ||||||
| 		'forum_boards' => getForumBoards(), | 		'forum_boards' => getForumBoards(), | ||||||
| 		'forum_section' => $forum_section ?? null, | 		'forum_section' => isset($forum_section) ? $forum_section : null, | ||||||
| 		'comments' => $comments ?? null, | 		'comments' => isset($comments) ? $comments : null, | ||||||
| 		'article_text' => $article_text ?? null, | 		'article_text' => isset($article_text) ? $article_text : null, | ||||||
| 		'article_image' => $article_image ?? null | 		'article_image' => isset($article_image) ? $article_image : null | ||||||
| 	)); | 	)); | ||||||
| } | } | ||||||
|  |  | ||||||
| $query = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news')); | $query = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news')); | ||||||
| $newses = array(); | $newses = array(); | ||||||
|  |  | ||||||
| $cachePlayers = []; |  | ||||||
| foreach ($query as $_news) { | foreach ($query as $_news) { | ||||||
| 	$playerId = $_news['player_id']; |  | ||||||
| 	if (isset($cachePlayers[$playerId])) { |  | ||||||
| 		$_player = $cachePlayers[$playerId]; |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 	$_player = new OTS_Player(); | 	$_player = new OTS_Player(); | ||||||
| 		$_player->load($playerId); | 	$_player->load($_news['player_id']); | ||||||
| 		$cachePlayers[$playerId] = $_player; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$newses[$_news['type']][] = array( | 	$newses[$_news['type']][] = array( | ||||||
| 		'id' => $_news['id'], | 		'id' => $_news['id'], | ||||||
| 		'hide' => $_news['hide'], | 		'hidden' => $_news['hidden'], | ||||||
| 		'archive_link' => getLink('news') . '/archive/' . $_news['id'], | 		'archive_link' => getLink('news') . '/archive/' . $_news['id'], | ||||||
| 		'title' => $_news['title'], | 		'title' => $_news['title'], | ||||||
| 		'date' => $_news['date'], | 		'date' => $_news['date'], | ||||||
| 		'player_name' => $_player->isLoaded() ? $_player->getName() : '', | 		'player_name' => isset($_player) && $_player->isLoaded() ? $_player->getName() : '', | ||||||
| 		'player_link' => $_player->isLoaded() ? getPlayerLink($_player, false) : '', | 		'player_link' => isset($_player) && $_player->isLoaded() ? getPlayerLink($_player->getName(), false) : '', | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,35 +7,46 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Models\Notepad as ModelsNotepad; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Notepad'; | $title = 'Notepad'; | ||||||
|  |  | ||||||
| csrfProtect(); | $notepad_content = Notepad::get($account_logged->getId()); | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @var OTS_Account $account_logged |  | ||||||
|  */ |  | ||||||
| $_content = ''; |  | ||||||
| $notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first(); |  | ||||||
| if (isset($_POST['content'])) { | if (isset($_POST['content'])) { | ||||||
| 	$_content = html_entity_decode(stripslashes($_POST['content'])); | 	$_content = html_entity_decode(stripslashes($_POST['content'])); | ||||||
| 	if (!$notepad) { | 	if (!$notepad_content) | ||||||
| 		ModelsNotepad::create([ | 		Notepad::create($account_logged->getId(), $_content); | ||||||
| 			'account_id' => $account_logged->getId(), | 	else | ||||||
| 			'content' => $_content | 		Notepad::update($account_logged->getId(), $_content); | ||||||
| 		]); |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 		ModelsNotepad::where('account_id', $account_logged->getId())->update(['content' => $_content]); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	success('Saved at ' . date('H:i')); | 	echo '<div class="success" style="text-align: center;">Saved at ' . date('H:i') . '</div>'; | ||||||
| } else { | } else { | ||||||
| 	if ($notepad) | 	if ($notepad_content !== false) | ||||||
| 		$_content = $notepad->content; | 		$_content = $notepad_content; | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('admin.notepad.html.twig', ['content' => $_content]); | $twig->display('admin.notepad.html.twig', array('content' => isset($_content) ? $_content : null)); | ||||||
|  |  | ||||||
|  | class Notepad | ||||||
|  | { | ||||||
|  | 	static public function get($account_id) | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		$query = $db->select(TABLE_PREFIX . 'notepad', array('account_id' => $account_id)); | ||||||
|  | 		if ($query !== false) | ||||||
|  | 			return $query['content']; | ||||||
|  |  | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static public function create($account_id, $content = '') | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		$db->insert(TABLE_PREFIX . 'notepad', array('account_id' => $account_id, 'content' => $content)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static public function update($account_id, $content = '') | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		$db->update(TABLE_PREFIX . 'notepad', array('content' => $content), array('account_id' => $account_id)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -7,15 +7,8 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Models\Pages as ModelsPages; |  | ||||||
| use MyAAC\Admin\Pages; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Pages'; | $title = 'Pages'; | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| @@ -24,61 +17,50 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | |||||||
|  |  | ||||||
| header('X-XSS-Protection:0'); | header('X-XSS-Protection:0'); | ||||||
|  |  | ||||||
| $name = $p_title = null; | $name = $p_title = ''; | ||||||
| $groups = new OTS_Groups_List(); | $groups = new OTS_Groups_List(); | ||||||
|  |  | ||||||
| $php = false; | $php = false; | ||||||
| $enable_tinymce = true; | $enable_tinymce = true; | ||||||
| $access = 0; | $access = 0; | ||||||
|  |  | ||||||
| // some constants, used mainly by database (cannot by modified without schema changes) | if (!empty($action)) { | ||||||
| const PAGE_TITLE_LIMIT = 30; | 	if ($action == 'delete' || $action == 'edit' || $action == 'hide') | ||||||
| const PAGE_NAME_LIMIT = 30; | 		$id = $_REQUEST['id']; | ||||||
| const PAGE_BODY_LIMIT = 65535; // maximum page body length |  | ||||||
|  |  | ||||||
| if (!empty($action) && isRequestMethod('post')) { | 	if (isset($_REQUEST['name'])) | ||||||
| 	if ($action == 'delete' || $action == 'edit' || $action == 'hide') { | 		$name = $_REQUEST['name']; | ||||||
| 		$id = $_POST['id']; |  | ||||||
|  | 	if (isset($_REQUEST['title'])) | ||||||
|  | 		$p_title = $_REQUEST['title']; | ||||||
|  |  | ||||||
|  | 	$php = isset($_REQUEST['php']) && $_REQUEST['php'] == 1; | ||||||
|  | 	$enable_tinymce = isset($_REQUEST['enable_tinymce']) && $_REQUEST['enable_tinymce'] == 1; | ||||||
|  | 	if ($php) | ||||||
|  | 		$body = $_REQUEST['body']; | ||||||
|  | 	else if (isset($_REQUEST['body'])) { | ||||||
|  | 		//$body = $_REQUEST['body']; | ||||||
|  | 		$body = html_entity_decode(stripslashes($_REQUEST['body'])); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (isset($_POST['name'])) { | 	if (isset($_REQUEST['access'])) | ||||||
| 		$name = $_POST['name']; | 		$access = $_REQUEST['access']; | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (isset($_POST['title'])) { |  | ||||||
| 		$p_title = $_POST['title']; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$php = isset($_POST['php']) && $_POST['php'] == 1; |  | ||||||
| 	$enable_tinymce = (isset($_POST['enable_tinymce']) && $_POST['enable_tinymce'] == 1) ?: $enable_tinymce; |  | ||||||
| 	if ($php) { |  | ||||||
| 		$body = $_POST['body']; |  | ||||||
| 	} |  | ||||||
| 	else if (isset($_POST['body'])) { |  | ||||||
| 		//$body = $_POST['body']; |  | ||||||
| 		$body = html_entity_decode(stripslashes($_POST['body'])); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (isset($_POST['access'])) { |  | ||||||
| 		$access = $_POST['access']; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$errors = array(); | 	$errors = array(); | ||||||
| 	$player_id = 1; | 	$player_id = 1; | ||||||
|  |  | ||||||
| 	if ($action == 'new') { | 	if ($action == 'add') { | ||||||
| 		if (isset($p_title) && Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { | 		if (Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { | ||||||
| 			$name = $p_title = $body = ''; | 			$name = $p_title = $body = ''; | ||||||
| 			$player_id = $access = 0; | 			$player_id = $access = 0; | ||||||
| 			$php = false; | 			$php = false; | ||||||
| 			$enable_tinymce = true; | 			$enable_tinymce = true; | ||||||
| 			success('Added successful.'); |  | ||||||
| 		} | 		} | ||||||
| 	} else if ($action == 'delete') { | 	} else if ($action == 'delete') { | ||||||
| 		if (Pages::delete($id, $errors)) | 		if (Pages::delete($id, $errors)) | ||||||
| 			success('Page with id ' . $id . ' has been deleted'); | 			success('Page with id ' . $id . ' has been deleted'); | ||||||
| 	} else if ($action == 'edit') { | 	} else if ($action == 'edit') { | ||||||
| 		if (isset($id) && !isset($_POST['name'])) { | 		if (isset($id) && !isset($_REQUEST['name'])) { | ||||||
| 			$_page = Pages::get($id); | 			$_page = Pages::get($id); | ||||||
| 			$name = $_page['name']; | 			$name = $_page['name']; | ||||||
| 			$p_title = $_page['title']; | 			$p_title = $_page['title']; | ||||||
| @@ -87,36 +69,36 @@ if (!empty($action) && isRequestMethod('post')) { | |||||||
| 			$enable_tinymce = $_page['enable_tinymce'] == '1'; | 			$enable_tinymce = $_page['enable_tinymce'] == '1'; | ||||||
| 			$access = $_page['access']; | 			$access = $_page['access']; | ||||||
| 		} else { | 		} else { | ||||||
| 			if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { | 			Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access); | ||||||
| 			$action = $name = $p_title = $body = ''; | 			$action = $name = $p_title = $body = ''; | ||||||
| 			$player_id = 1; | 			$player_id = 1; | ||||||
| 			$access = 0; | 			$access = 0; | ||||||
| 			$php = false; | 			$php = false; | ||||||
| 			$enable_tinymce = true; | 			$enable_tinymce = true; | ||||||
| 				success('Updated successful.'); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} else if ($action == 'hide') { | 	} else if ($action == 'hide') { | ||||||
| 		if (Pages::toggleHide($id, $errors, $status)) { | 		Pages::toggleHidden($id, $errors); | ||||||
| 			success(($status == 0 ? 'Show' : 'Hide') . ' successful.'); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!empty($errors)) | 	if (!empty($errors)) | ||||||
| 		error(implode(", ", $errors)); | 		error(implode(", ", $errors)); | ||||||
| } | } | ||||||
|  |  | ||||||
| $pages = ModelsPages::all()->map(function ($e) { | $query = | ||||||
| 	return [ | 	$db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'pages')); | ||||||
| 		'link' => getFullLink($e->name, $e->name, true), |  | ||||||
| 		'title' => substr($e->title, 0, 20), |  | ||||||
| 		'php' => $e->php == '1', |  | ||||||
| 		'id' => $e->id, |  | ||||||
| 		'hide' => $e->hide |  | ||||||
| 	]; |  | ||||||
| })->toArray(); |  | ||||||
|  |  | ||||||
| $twig->display('admin.pages.form.html.twig', [ | $pages = array(); | ||||||
|  | foreach ($query as $_page) { | ||||||
|  | 	$pages[] = array( | ||||||
|  | 		'link' => getFullLink($_page['name'], $_page['name'], true), | ||||||
|  | 		'title' => substr($_page['title'], 0, 20), | ||||||
|  | 		'php' => $_page['php'] == '1', | ||||||
|  | 		'id' => $_page['id'], | ||||||
|  | 		'hidden' => $_page['hidden'] | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $twig->display('admin.pages.form.html.twig', array( | ||||||
| 	'action' => $action, | 	'action' => $action, | ||||||
| 	'id' => $action == 'edit' ? $id : null, | 	'id' => $action == 'edit' ? $id : null, | ||||||
| 	'name' => $name, | 	'name' => $name, | ||||||
| @@ -126,8 +108,91 @@ $twig->display('admin.pages.form.html.twig', [ | |||||||
| 	'body' => isset($body) ? escapeHtml($body) : '', | 	'body' => isset($body) ? escapeHtml($body) : '', | ||||||
| 	'groups' => $groups->getGroups(), | 	'groups' => $groups->getGroups(), | ||||||
| 	'access' => $access | 	'access' => $access | ||||||
| ]); | )); | ||||||
|  |  | ||||||
| $twig->display('admin.pages.html.twig', [ | $twig->display('admin.pages.html.twig', array( | ||||||
| 	'pages' => $pages | 	'pages' => $pages | ||||||
| ]); | )); | ||||||
|  |  | ||||||
|  | class Pages | ||||||
|  | { | ||||||
|  | 	static public function get($id) | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id)); | ||||||
|  | 		if ($query !== false) | ||||||
|  | 			return $query; | ||||||
|  |  | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static public function add($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		if (isset($name[0]) && isset($title[0]) && isset($body[0]) && $player_id != 0) { | ||||||
|  | 			$query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name)); | ||||||
|  | 			if ($query === false) | ||||||
|  | 				$db->insert(TABLE_PREFIX . 'pages', | ||||||
|  | 					array( | ||||||
|  | 						'name' => $name, | ||||||
|  | 						'title' => $title, | ||||||
|  | 						'body' => $body, | ||||||
|  | 						'player_id' => $player_id, | ||||||
|  | 						'php' => $php ? '1' : '0', | ||||||
|  | 						'enable_tinymce' => $enable_tinymce ? '1' : '0', | ||||||
|  | 						'access' => $access | ||||||
|  | 					) | ||||||
|  | 				); | ||||||
|  | 			else | ||||||
|  | 				$errors[] = 'Page with this link already exists.'; | ||||||
|  | 		} else | ||||||
|  | 			$errors[] = 'Please fill all inputs.'; | ||||||
|  |  | ||||||
|  | 		return !count($errors); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access) | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		$db->update(TABLE_PREFIX . 'pages', | ||||||
|  | 			array( | ||||||
|  | 				'name' => $name, | ||||||
|  | 				'title' => $title, | ||||||
|  | 				'body' => $body, | ||||||
|  | 				'player_id' => $player_id, | ||||||
|  | 				'php' => $php ? '1' : '0', | ||||||
|  | 				'enable_tinymce' => $enable_tinymce ? '1' : '0', | ||||||
|  | 				'access' => $access | ||||||
|  | 			), | ||||||
|  | 			array('id' => $id)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static public function delete($id, &$errors) | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		if (isset($id)) { | ||||||
|  | 			if ($db->select(TABLE_PREFIX . 'pages', array('id' => $id)) !== false) | ||||||
|  | 				$db->delete(TABLE_PREFIX . 'pages', array('id' => $id)); | ||||||
|  | 			else | ||||||
|  | 				$errors[] = 'Page with id ' . $id . ' does not exists.'; | ||||||
|  | 		} else | ||||||
|  | 			$errors[] = 'id not set'; | ||||||
|  |  | ||||||
|  | 		return !count($errors); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static public function toggleHidden($id, &$errors) | ||||||
|  | 	{ | ||||||
|  | 		global $db; | ||||||
|  | 		if (isset($id)) { | ||||||
|  | 			$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id)); | ||||||
|  | 			if ($query !== false) | ||||||
|  | 				$db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); | ||||||
|  | 			else | ||||||
|  | 				$errors[] = 'Page with id ' . $id . ' does not exists.'; | ||||||
|  | 		} else | ||||||
|  | 			$errors[] = 'id not set'; | ||||||
|  |  | ||||||
|  | 		return !count($errors); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -16,4 +16,4 @@ if (!function_exists('phpinfo')) { ?> | |||||||
| 	<?php return; | 	<?php return; | ||||||
| } | } | ||||||
| ?> | ?> | ||||||
| <iframe src="<?php echo ADMIN_URL; ?>tools/phpinfo.php" width="1024" height="550"></iframe> | <iframe src="<?php echo BASE_URL; ?>admin/tools/phpinfo.php" width="1024" height="550"/> | ||||||
|   | |||||||
| @@ -7,107 +7,26 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Plugins; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Plugin manager'; | $title = 'Plugin manager'; | ||||||
|  |  | ||||||
| csrfProtect(); | $twig->display('admin.plugins.form.html.twig'); | ||||||
|  |  | ||||||
| $use_datatable = true; | if (isset($_REQUEST['uninstall'])) { | ||||||
|  | 	$uninstall = $_REQUEST['uninstall']; | ||||||
| if (!setting('core.admin_plugins_manage_enable')) { |  | ||||||
| 	warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.'); |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| 	$pluginUploadEnabled = true; |  | ||||||
| 	if(!\class_exists('\ZipArchive')) { |  | ||||||
| 		error('Please install PHP zip extension. Plugins upload disabled until then.'); |  | ||||||
| 		$pluginUploadEnabled = false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$twig->display('admin.plugins.form.html.twig', ['pluginUploadEnabled' => $pluginUploadEnabled]); |  | ||||||
|  |  | ||||||
| 	if (isset($_POST['uninstall'])) { |  | ||||||
| 		$uninstall = $_POST['uninstall']; |  | ||||||
|  |  | ||||||
| 	if (Plugins::uninstall($uninstall)) { | 	if (Plugins::uninstall($uninstall)) { | ||||||
| 		success('Successfully uninstalled plugin ' . $uninstall); | 		success('Successfully uninstalled plugin ' . $uninstall); | ||||||
| 	} else { | 	} else { | ||||||
| 		error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); | 		error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); | ||||||
| 	} | 	} | ||||||
| 	} else if (isset($_POST['enable'])) { | } else if (isset($_FILES["plugin"]["name"])) { | ||||||
| 		$enable = $_POST['enable']; | 	$file = $_FILES["plugin"]; | ||||||
| 		if (Plugins::enable($enable)) { | 	$filename = $file["name"]; | ||||||
| 			success('Successfully enabled plugin ' . $enable); | 	$tmp_name = $file["tmp_name"]; | ||||||
| 		} else { | 	$type = $file["type"]; | ||||||
| 			error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError()); |  | ||||||
| 		} |  | ||||||
| 	} else if (isset($_POST['disable'])) { |  | ||||||
| 		$disable = $_POST['disable']; |  | ||||||
| 		if (Plugins::disable($disable)) { |  | ||||||
| 			success('Successfully disabled plugin ' . $disable); |  | ||||||
| 		} else { |  | ||||||
| 			error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError()); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if (isset($_GET['check-updates'])) { |  | ||||||
| 		$repoUri = $config['admin_plugins_api_uri'] ?? 'https://plugins.my-aac.org/api/'; |  | ||||||
| 		success("Fetching latest info from $repoUri.."); |  | ||||||
|  |  | ||||||
| 		$adminPlugins = new \MyAAC\Admin\Plugins(); | 	$name = explode(".", $filename); | ||||||
|  |  | ||||||
| 		$adminPlugins->setApiBaseUri($repoUri); |  | ||||||
|  |  | ||||||
| 		try { |  | ||||||
| 			$plugins = $adminPlugins->getLatestVersions(); |  | ||||||
| 		} |  | ||||||
| 		catch (Exception $e) { |  | ||||||
| 			error($e->getMessage()); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (isset($plugins) && count($plugins) > 0) { |  | ||||||
| 			$outdated = []; |  | ||||||
|  |  | ||||||
| 			foreach (get_plugins(true) as $plugin) { |  | ||||||
| 				$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json'); |  | ||||||
| 				$plugin_info = json_decode($string, true); |  | ||||||
|  |  | ||||||
| 				if (!$plugin_info) { |  | ||||||
| 					continue; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				$disabled = (str_contains($plugin, 'disabled.')); |  | ||||||
| 				$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); |  | ||||||
|  |  | ||||||
| 				$info = $plugins[$pluginOriginal] ?? false; |  | ||||||
| 				if ($info && version_compare($info['version'], $plugin_info['version'], '>')) { |  | ||||||
| 					$outdated[] = [ |  | ||||||
| 						'name' => $pluginOriginal, |  | ||||||
| 						'yourVersion' => $plugin_info['version'], |  | ||||||
| 						'latestVersion' => $info['version'], |  | ||||||
| 						'link' => $info['link'] ?? 'Unknown', |  | ||||||
| 						'download_link' => $info['download_link'] ?? 'Unknown', |  | ||||||
| 					]; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (count($outdated) > 0) { |  | ||||||
| 				info('Following updates have been found for your plugins:'); |  | ||||||
| 				$twig->display('admin.plugins.outdated.html.twig', ['plugins' => $outdated]); |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				success('All plugins up to date!'); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} else if (isset($_FILES['plugin']['name'])) { |  | ||||||
| 		$file = $_FILES['plugin']; |  | ||||||
| 		$filename = $file['name']; |  | ||||||
| 		$tmp_name = $file['tmp_name']; |  | ||||||
| 		$type = $file['type']; |  | ||||||
|  |  | ||||||
| 		$name = explode('.', $filename); |  | ||||||
| 	$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed'); | 	$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed'); | ||||||
|  |  | ||||||
| 	if (isset($file['error'])) { | 	if (isset($file['error'])) { | ||||||
| @@ -166,26 +85,23 @@ else { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| } |  | ||||||
|  |  | ||||||
| $plugins = array(); | $plugins = array(); | ||||||
| foreach (get_plugins(true) as $plugin) { | foreach (get_plugins() as $plugin) { | ||||||
| 	$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json'); | 	$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json'); | ||||||
|  | 	$string = Plugins::removeComments($string); | ||||||
| 	$plugin_info = json_decode($string, true); | 	$plugin_info = json_decode($string, true); | ||||||
|  |  | ||||||
| 	if (!$plugin_info) { | 	if ($plugin_info == false) { | ||||||
| 		warning('Cannot load plugin info ' . $plugin . '.json'); | 		warning('Cannot load plugin info ' . $plugin . '.json'); | ||||||
| 	} else { | 	} else { | ||||||
| 		$disabled = (str_contains($plugin, 'disabled.')); |  | ||||||
| 		$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); |  | ||||||
| 		$plugins[] = array( | 		$plugins[] = array( | ||||||
| 			'name' => $plugin_info['name'] ?? '', | 			'name' => isset($plugin_info['name']) ? $plugin_info['name'] : '', | ||||||
| 			'description' => $plugin_info['description'] ?? '', | 			'description' => isset($plugin_info['description']) ? $plugin_info['description'] : '', | ||||||
| 			'version' => $plugin_info['version'] ?? '', | 			'version' => isset($plugin_info['version']) ? $plugin_info['version'] : '', | ||||||
| 			'author' => $plugin_info['author'] ?? '', | 			'author' => isset($plugin_info['author']) ? $plugin_info['author'] : '', | ||||||
| 			'contact' => $plugin_info['contact'] ?? '', | 			'contact' => isset($plugin_info['contact']) ? $plugin_info['contact'] : '', | ||||||
| 			'file' => $pluginOriginal, | 			'file' => $plugin, | ||||||
| 			'enabled' => !$disabled, |  | ||||||
| 			'uninstall' => isset($plugin_info['uninstall']) | 			'uninstall' => isset($plugin_info['uninstall']) | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -4,12 +4,11 @@ | |||||||
|  * |  * | ||||||
|  * @package   MyAAC |  * @package   MyAAC | ||||||
|  * @author    Lee |  * @author    Lee | ||||||
|  * @copyright 2020 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Report Viewer'; | $title = 'Report Viewer'; | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| $files = array(); | $files = array(); | ||||||
| $server_path_reports = $config['data_path'] . 'reports/'; | $server_path_reports = $config['data_path'] . 'reports/'; | ||||||
| @@ -43,13 +42,16 @@ foreach ($files as &$f) { | |||||||
|  |  | ||||||
| unset($f); | unset($f); | ||||||
|  |  | ||||||
|  | $twig->display('admin.reports.html.twig', array('files' => $files)); | ||||||
|  |  | ||||||
|  |  | ||||||
| $file = isset($_GET['file']) ? $_GET['file'] : NULL; | $file = isset($_GET['file']) ? $_GET['file'] : NULL; | ||||||
| if (!empty($file)) { | if (!empty($file)) { | ||||||
| 	if (!preg_match('/[^A-z0-9\' _\/\-\.]/', $file)) { | 	if (!preg_match('/[^A-z0-9\' _\/\-\.]/', $file)) { | ||||||
| 		if (file_exists($server_path_reports . $file)) { | 		if (file_exists($server_path_reports . $file)) { | ||||||
| 			$file_content = nl2br(file_get_contents($server_path_reports . $file)); | 			$content = nl2br(file_get_contents($server_path_reports . $file)); | ||||||
|  |  | ||||||
| 			$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $file_content)); | 			$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $content)); | ||||||
| 		} else { | 		} else { | ||||||
| 			echo 'Specified file does not exist.'; | 			echo 'Specified file does not exist.'; | ||||||
| 		} | 		} | ||||||
| @@ -57,5 +59,3 @@ if (!empty($file)) { | |||||||
| 		echo 'Invalid file name specified.'; | 		echo 'Invalid file name specified.'; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('admin.reports.html.twig', array('files' => $files)); |  | ||||||
|   | |||||||
| @@ -1,60 +0,0 @@ | |||||||
| <?php |  | ||||||
| /** |  | ||||||
|  * Menus |  | ||||||
|  * |  | ||||||
|  * @package   MyAAC |  | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  | ||||||
|  * @copyright 2019 MyAAC |  | ||||||
|  * @link      https://my-aac.org |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| use MyAAC\Plugins; |  | ||||||
| use MyAAC\Settings; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); |  | ||||||
| $title = 'Settings'; |  | ||||||
|  |  | ||||||
| require_once SYSTEM . 'clients.conf.php'; |  | ||||||
| if (empty($_GET['plugin'])) { |  | ||||||
| 	error('Please select plugin from left Panel.'); |  | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $plugin = $_GET['plugin']; |  | ||||||
|  |  | ||||||
| if($plugin != 'core') { |  | ||||||
| 	$pluginSettings = Plugins::getPluginSettings($plugin); |  | ||||||
| 	if (!$pluginSettings) { |  | ||||||
| 		error('This plugin does not exist or does not have settings defined.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$settingsFilePath = BASE . $pluginSettings; |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| 	$settingsFilePath = SYSTEM . 'settings.php'; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (!file_exists($settingsFilePath)) { |  | ||||||
| 	error("Plugin $plugin does not exist or does not have settings defined."); |  | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $settingsFile = require $settingsFilePath; |  | ||||||
| if (!is_array($settingsFile)) { |  | ||||||
| 	error("Cannot load settings file for plugin $plugin"); |  | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $settingsKeyName = ($plugin == 'core' ? $plugin : $settingsFile['key']); |  | ||||||
|  |  | ||||||
| $title = ($plugin == 'core' ? 'Settings' : 'Plugin Settings - ' . $settingsFile['name']); |  | ||||||
|  |  | ||||||
| $settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']); |  | ||||||
|  |  | ||||||
| $twig->display('admin.settings.html.twig', [ |  | ||||||
| 	'settingsParsed' => $settingsParsed['content'], |  | ||||||
| 	'settings' => $settingsFile['settings'], |  | ||||||
| 	'script' => $settingsParsed['script'], |  | ||||||
| 	'settingsKeyName' => $settingsKeyName, |  | ||||||
| ]); |  | ||||||
| @@ -7,25 +7,26 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Models\Account; |  | ||||||
| use MyAAC\Models\Guild; |  | ||||||
| use MyAAC\Models\House; |  | ||||||
| use MyAAC\Models\Player; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Statistics'; | $title = 'Statistics'; | ||||||
|  |  | ||||||
| $total_accounts = Account::count(); | $query = $db->query('SELECT count(*) as `how_much` FROM `accounts`;'); | ||||||
| $total_players = Player::count(); | $query = $query->fetch(); | ||||||
| $total_guilds = Guild::count(); | $total_accounts = $query['how_much']; | ||||||
| $total_houses = House::count(); |  | ||||||
|  |  | ||||||
| $points = Account::select(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')]) | $query = $db->query('SELECT count(*) as `how_much` FROM `players`;'); | ||||||
| 	->orderByDesc('premium_points') | $query = $query->fetch(); | ||||||
| 	->limit(10) | $total_players = $query['how_much']; | ||||||
| 	->get() |  | ||||||
| 	->toArray(); | $query = $db->query('SELECT count(*) as `how_much` FROM `guilds`;'); | ||||||
|  | $query = $query->fetch(); | ||||||
|  | $total_guilds = $query['how_much']; | ||||||
|  |  | ||||||
|  | $query = $db->query('SELECT count(*) as `how_much` FROM `houses`;'); | ||||||
|  | $query = $query->fetch(); | ||||||
|  | $total_houses = $query['how_much']; | ||||||
|  |  | ||||||
|  | $points = $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;'); | ||||||
|  |  | ||||||
| $twig->display('admin.statistics.html.twig', array( | $twig->display('admin.statistics.html.twig', array( | ||||||
| 	'total_accounts' => $total_accounts, | 	'total_accounts' => $total_accounts, | ||||||
|   | |||||||
| @@ -10,24 +10,18 @@ | |||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Tools'; | $title = 'Tools'; | ||||||
|  |  | ||||||
| if (!isset($_GET['tool'])) { | $tool = $_GET['tool']; | ||||||
|  | if (!isset($tool)) { | ||||||
| 	echo 'Tool not set.'; | 	echo 'Tool not set.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $tool = $_GET['tool']; |  | ||||||
| if (preg_match("/[^A-z0-9_\-]/", $tool)) { | if (preg_match("/[^A-z0-9_\-]/", $tool)) { | ||||||
| 	echo 'Invalid tool.'; | 	echo 'Invalid tool.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $file = ADMIN . 'tools/' . $tool . '.php'; | $file = BASE . 'admin/pages/tools/' . $tool . '.php'; | ||||||
|  | if (!@file_exists($file)) | ||||||
| if (@file_exists($file)) { |  | ||||||
| 	require $file; | 	require $file; | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| echo 'Tool <strong>' . $tool . '</strong> not found.'; |  | ||||||
|  |  | ||||||
| ?> | ?> | ||||||
|   | |||||||
| @@ -24,10 +24,10 @@ if (!$myaac_version) { | |||||||
| $version_compare = version_compare($myaac_version, MYAAC_VERSION); | $version_compare = version_compare($myaac_version, MYAAC_VERSION); | ||||||
| if ($version_compare == 0) { | if ($version_compare == 0) { | ||||||
| 	success('MyAAC latest version is ' . $myaac_version . '. You\'re using the latest version. | 	success('MyAAC latest version is ' . $myaac_version . '. You\'re using the latest version. | ||||||
| 	<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here')); | 	<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=changelog', 'here')); | ||||||
| } else if ($version_compare < 0) { | } else if ($version_compare < 0) { | ||||||
| 	success('Woah, seems you\'re using newer version as latest released one! MyAAC latest released version is ' . $myaac_version . ', and you\'re using version ' . MYAAC_VERSION . '. | 	success('Woah, seems you\'re using newer version as latest released one! MyAAC latest released version is ' . $myaac_version . ', and you\'re using version ' . MYAAC_VERSION . '. | ||||||
| 	<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here')); | 	<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=changelog', 'here')); | ||||||
| } else { | } else { | ||||||
| 	warning('You\'re using outdated version.<br/> | 	warning('You\'re using outdated version.<br/> | ||||||
| 		Your version: <b>' . MYAAC_VERSION . '</b><br/> | 		Your version: <b>' . MYAAC_VERSION . '</b><br/> | ||||||
|   | |||||||
| @@ -8,58 +8,29 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| use DeviceDetector\DeviceDetector; |  | ||||||
| use DeviceDetector\Parser\Client\Browser; |  | ||||||
| use DeviceDetector\Parser\OperatingSystem; |  | ||||||
| use MyAAC\Visitors; |  | ||||||
|  |  | ||||||
| $title = 'Visitors'; | $title = 'Visitors'; | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| if (!setting('core.visitors_counter')): ?> | if (!$config['visitors_counter']): ?> | ||||||
| 	Visitors counter is disabled.<br/> | 	Visitors counter is disabled.<br/> | ||||||
| 	You can enable it in Settings -> General -> Visitors Counter.<br/> | 	You can enable it by editing this configurable in <b>config.local.php</b> file:<br/> | ||||||
|  | 	<p style="margin-left: 3em;"><b>$config['visitors_counter'] = true;</b></p> | ||||||
| 	<?php | 	<?php | ||||||
| 	return; | 	return; | ||||||
| endif; | endif; | ||||||
|  |  | ||||||
| $visitors = new Visitors(setting('core.visitors_counter_ttl')); | require SYSTEM . 'libs/visitors.php'; | ||||||
|  | $visitors = new Visitors($config['visitors_counter_ttl']); | ||||||
|  |  | ||||||
| function compare($a, $b): int { | function compare($a, $b) | ||||||
|  | { | ||||||
| 	return $a['lastvisit'] > $b['lastvisit'] ? -1 : 1; | 	return $a['lastvisit'] > $b['lastvisit'] ? -1 : 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| $tmp = $visitors->getVisitors(); | $tmp = $visitors->getVisitors(); | ||||||
| usort($tmp, 'compare'); | usort($tmp, 'compare'); | ||||||
|  |  | ||||||
| foreach ($tmp as &$visitor) { |  | ||||||
| 	$userAgent = $visitor['user_agent'] ?? ''; |  | ||||||
| 	if (!strlen($userAgent) || $userAgent == 'unknown') { |  | ||||||
| 		$browser = 'Unknown'; |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 		$dd = new DeviceDetector($userAgent); |  | ||||||
| 		$dd->parse(); |  | ||||||
|  |  | ||||||
| 		if ($dd->isBot()) { |  | ||||||
| 			$bot = $dd->getBot(); |  | ||||||
| 			$message = '(Bot) %s, <a href="%s" target="_blank">%s</a>'; |  | ||||||
| 			$browser = sprintf($message, $bot['category'] ?? 'Unknown', $bot['url'] ?? '', $bot['name'] ?? 'Unknown name'); |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			$osFamily = OperatingSystem::getOsFamily($dd->getOs('name')); |  | ||||||
| 			$browserFamily = Browser::getBrowserFamily($dd->getClient('name')); |  | ||||||
|  |  | ||||||
| 			$browser = $osFamily . ', ' . $browserFamily; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$visitor['browser'] = $browser; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $twig->display('admin.visitors.html.twig', array( | $twig->display('admin.visitors.html.twig', array( | ||||||
| 	'config_visitors_counter_ttl' => setting('core.visitors_counter_ttl'), | 	'config_visitors_counter_ttl' => $config['visitors_counter_ttl'], | ||||||
| 	'visitors' => $tmp | 	'visitors' => $tmp | ||||||
| )); | )); | ||||||
| ?> | ?> | ||||||
|   | |||||||
| @@ -1,69 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| $menus = [ |  | ||||||
| 	['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'], |  | ||||||
| 	['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' => |  | ||||||
| 		require ADMIN . 'includes/settings_menus.php' |  | ||||||
| 	], |  | ||||||
| 	['name' => 'News', 'icon' => 'newspaper', 'order' => 20,  'link' => |  | ||||||
| 		[ |  | ||||||
| 			['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10], |  | ||||||
| 			['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20], |  | ||||||
| 			['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'icon' => 'plus', 'order' => 30], |  | ||||||
| 			['name' => 'Add article', 'link' => 'news&action=new&type=3', 'icon' => 'plus', 'order' => 40], |  | ||||||
| 		], |  | ||||||
| 	], |  | ||||||
| 	['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' => |  | ||||||
| 		[ |  | ||||||
| 			['name' => 'View', 'link' => 'changelog', 'icon' => 'list', 'order' => 10], |  | ||||||
| 			['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20], |  | ||||||
| 		], |  | ||||||
| 	], |  | ||||||
| 	['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !setting('core.mail_enabled')], |  | ||||||
| 	['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' => |  | ||||||
| 		[ |  | ||||||
| 			['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10], |  | ||||||
| 			['name' => 'Add', 'link' => 'pages&action=new', 'icon' => 'plus', 'order' => 20], |  | ||||||
| 		], |  | ||||||
| 	], |  | ||||||
| 	['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'], |  | ||||||
| 	['name' => 'Plugins', 'icon' => 'plug', 'order' => 70, 'link' => 'plugins'], |  | ||||||
| 	['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'], |  | ||||||
| 	['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' => |  | ||||||
| 		[ |  | ||||||
| 			['name' => 'Accounts', 'link' => 'accounts', 'icon' => 'users', 'order' => 10], |  | ||||||
| 			['name' => 'Players', 'link' => 'players', 'icon' => 'user-astronaut', 'order' => 20], |  | ||||||
| 		], |  | ||||||
| 	], |  | ||||||
| 	['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' => |  | ||||||
| 		[ |  | ||||||
| 			['name' => 'Mass Account Actions', 'link' => 'mass_account', 'icon' => 'globe', 'order' => 10], |  | ||||||
| 			['name' => 'Mass Teleport Actions', 'link' => 'mass_teleport', 'icon' => 'globe', 'order' => 20], |  | ||||||
| 			['name' => 'Notepad', 'link' => 'notepad', 'icon' => 'marker', 'order' => 30], |  | ||||||
| 			['name' => 'phpinfo', 'link' => 'phpinfo', 'icon' => 'server', 'order' => 40], |  | ||||||
| 		], |  | ||||||
| 	], |  | ||||||
| 	['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' => |  | ||||||
| 		[ |  | ||||||
| 			['name' => 'Logs', 'link' => 'logs', 'icon' => 'book', 'order' => 10], |  | ||||||
| 			['name' => 'Reports', 'link' => 'reports', 'icon' => 'book', 'order' => 20], |  | ||||||
| 			['name' => 'Visitors', 'link' => 'visitors', 'icon' => 'user', 'order' => 30], |  | ||||||
| 		], |  | ||||||
| 	], |  | ||||||
| ]; |  | ||||||
|  |  | ||||||
| $hooks->trigger(HOOK_ADMIN_MENU); |  | ||||||
|  |  | ||||||
| usort($menus, function ($a, $b) { |  | ||||||
| 	return $a['order'] - $b['order']; |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| foreach ($menus as $i => $menu) { |  | ||||||
| 	if (isset($menu['link']) && is_array($menu['link'])) { |  | ||||||
| 		usort($menus[$i]['link'], function ($a, $b) { |  | ||||||
| 			return $a['order'] - $b['order']; |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| return $menus; |  | ||||||
| @@ -1,15 +1,44 @@ | |||||||
| .menu-text-li {color: #4b646f; background: #1a2226;} | .slidecontainer { | ||||||
| .menu-text { | 	width: 100%; | ||||||
| 	display: block; |  | ||||||
| 	padding: .5rem 1rem; |  | ||||||
| 	white-space: nowrap; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| .sidebar-mini.sidebar-collapse .menu-text { | .slider { | ||||||
| 	display: none; | 	-webkit-appearance: none; | ||||||
|  | 	width: 100%; | ||||||
|  |  | ||||||
|  | 	outline: none; | ||||||
|  | 	opacity: 0.7; | ||||||
|  | 	-webkit-transition: .2s; | ||||||
|  | 	transition: opacity .2s; | ||||||
| } | } | ||||||
|  |  | ||||||
| .myaac-table tbody tr:nth-child(even) {background: #FFF} /* light border */ | .slider:hover { | ||||||
| .myaac-table tbody tr:nth-child(odd) {background: #CCC} /* dark border */ | 	opacity: 1; | ||||||
| .myaac-table thead td {background: #000000; color: #ffffff !important;} /* vdark border */ | } | ||||||
| .myaac-table tfoot td {background: #000000; color: #ffffff !important;} /* vdark border */ |  | ||||||
|  | .slider::-webkit-slider-thumb { | ||||||
|  | 	-webkit-appearance: none; | ||||||
|  | 	appearance: none; | ||||||
|  | 	width: 15px; | ||||||
|  | 	height: 25px; | ||||||
|  | 	background: #3c8dbc; | ||||||
|  | 	cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .slider::-moz-range-thumb { | ||||||
|  | 	width: 25px; | ||||||
|  | 	height: 25px; | ||||||
|  | 	background: #3c8dbc; | ||||||
|  | 	cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | td.details-control { | ||||||
|  | 	text-align: center; | ||||||
|  | 	color: forestgreen; | ||||||
|  | 	cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | tr.shown td.details-control { | ||||||
|  | 	text-align: center; | ||||||
|  | 	color: red; | ||||||
|  | } | ||||||
| @@ -1,203 +1,229 @@ | |||||||
| <?php defined('MYAAC') or die('Direct access not allowed!'); ?> | <?php defined('MYAAC') or die('Direct access not allowed!'); ?> | ||||||
| <!doctype html> | <!DOCTYPE html> | ||||||
| <html lang="en"> | <html> | ||||||
| <head> | <head> | ||||||
| 	<?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?> | 	<?php echo template_header(true); | ||||||
| 	<?php echo template_header(true); ?> | 	$title_full =  (isset($title) ? $title . $config['title_separator'] : '') . $config['lua']['serverName']; | ||||||
| 	<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title> | 	?> | ||||||
| 	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |  | ||||||
| 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/adminlte.min.css"> | 	<title><?php echo $title_full ?></title> | ||||||
|  | 	<link rel="shortcut icon" href="<?php echo BASE_URL; ?>images/favicon.ico" type="image/x-icon" /> | ||||||
|  | 	<link rel="icon" href="<?php echo BASE_URL; ?>images/favicon.ico" type="image/x-icon" /> | ||||||
|  | 	<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> | ||||||
|  |  | ||||||
|  | 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/bootstrap.min.css"> | ||||||
|  | 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/AdminLTE.min.css"> | ||||||
|  | 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/skins/skin-blue.min.css"> | ||||||
| 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css"> | 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css"> | ||||||
| 	<?php if (isset($use_datatable)) { ?> | 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/ionicons.min.css"> | ||||||
| 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/datatables.bs.min.css"> | 	<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/jquery.dataTables.min.css"> | ||||||
| 	<?php } ?> |  | ||||||
| 	<link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css"/> | 	<link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css"/> | ||||||
| 	<!--[if lt IE 9]> | 	<!--[if lt IE 9]> | ||||||
| 	<script src="<?php echo BASE_URL; ?>tools/js/html5shiv.min.js"></script> | 	<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> | ||||||
| 	<script src="<?php echo BASE_URL; ?>tools/js/respond.min.js"></script> | 	<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> | ||||||
| 	<![endif]--> | 	<![endif]--> | ||||||
| 	<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> | 	<link rel="stylesheet" | ||||||
| 	<?php $hooks->trigger(HOOK_ADMIN_HEAD_END); ?> | 		  href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> | ||||||
| </head> | </head> | ||||||
| <body class="sidebar-mini "> | <body class="hold-transition skin-blue sidebar-mini"> | ||||||
| <?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?> |  | ||||||
| <?php if ($logged && admin()) { ?> |  | ||||||
| <div class="wrapper"> | <div class="wrapper"> | ||||||
| 		<nav class="main-header navbar navbar-expand navbar-white navbar-light"> |  | ||||||
| 			<ul class="navbar-nav"> |  | ||||||
| 				<li class="nav-item"> |  | ||||||
| 					<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a> |  | ||||||
| 				</li> |  | ||||||
| 				<li class="nav-item d-none d-sm-inline-block"> |  | ||||||
| 					<a href="<?php echo ADMIN_URL; ?>" class="nav-link">Home</a> |  | ||||||
| 				</li> |  | ||||||
| 			</ul> |  | ||||||
| 			<ul class="navbar-nav ml-auto"> |  | ||||||
| 				<li class="nav-item"> |  | ||||||
| 					<a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#"><i class="fas fa-th-large"></i></a> |  | ||||||
| 				</li> |  | ||||||
| 			</ul> |  | ||||||
| 		</nav> |  | ||||||
| 		<aside class="main-sidebar sidebar-dark-info elevation-4"> |  | ||||||
| 			<a href="<?php echo ADMIN_URL; ?>" class="brand-link navbar-info"> |  | ||||||
| 				<img src="<?php echo ADMIN_URL; ?>images/logo.png" class="brand-image img-circle elevation-3" style="opacity: .8"> |  | ||||||
| 				<span class="brand-text"><b>My</b>AAC</span> |  | ||||||
| 			</a> |  | ||||||
| 			<div class="sidebar"> |  | ||||||
| 				<nav class="mt-1"> |  | ||||||
| 					<ul class="nav nav-pills nav-sidebar flex-column nav-legacy nav-child-indent" data-widget="treeview" data-accordion="false"> |  | ||||||
| 						<li class="menu-text-li"> |  | ||||||
| 							<span class="menu-text"> |  | ||||||
| 								<a class="text-info" href="<?php echo BASE_URL; ?>" target="_blank"> |  | ||||||
| 									<?php echo $config['lua']['serverName'] ?> |  | ||||||
| 								</a> |  | ||||||
| 							</span> |  | ||||||
| 						</li> |  | ||||||
| 	<?php | 	<?php | ||||||
| 						// name = Display name of link | 	if ($logged && admin()) { | ||||||
| 						// icon = fontawesome icon name without "fas fa-" | 	?> | ||||||
| 						// link = Page link or use as array for sub items | 	<header class="main-header"> | ||||||
| 						$menus = require __DIR__ . '/menus.php'; | 		<a href="." class="logo"> | ||||||
|  | 			<span class="logo-mini"><b>M</b>A</span> | ||||||
|  | 			<span class="logo-lg"><b>My</b>AAC</span> | ||||||
|  | 		</a> | ||||||
|  |  | ||||||
| 						foreach ($menus as $category => $menu) { | 		<nav class="navbar navbar-static-top" role="navigation"> | ||||||
| 							if (isset($menu['disabled']) && $menu['disabled']) { | 			<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button"> | ||||||
| 								continue; | 				<span class="sr-only">Toggle navigation</span> | ||||||
|  | 			</a> | ||||||
|  | 			<div class="navbar-custom-menu"> | ||||||
|  | 				<ul class="nav navbar-nav"> | ||||||
|  | 					<li> | ||||||
|  | 						<a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a> | ||||||
|  | 					</li> | ||||||
|  | 				</ul> | ||||||
|  | 			</div> | ||||||
|  | 		</nav> | ||||||
|  | 	</header> | ||||||
|  | 	<aside class="main-sidebar"> | ||||||
|  | 		<section class="sidebar"> | ||||||
|  | 			<ul class="sidebar-menu" data-widget="tree"> | ||||||
|  | 				<li class="header">MyAAC</li> | ||||||
|  |  | ||||||
|  | 				<?php | ||||||
|  | 				$icons_a = array( | ||||||
|  |                     'dashboard','newspaper-o', 'envelope', | ||||||
|  |                     'book', 'list', | ||||||
|  |                     'plug', 'user', | ||||||
|  |                     'edit', 'gavel', | ||||||
|  |                     'wrench', 'edit', 'book', 'book', | ||||||
|  |                 ); | ||||||
|  |  | ||||||
|  | 				$menus = array( | ||||||
|  | 					'Dashboard' => 'dashboard', | ||||||
|  | 					'News' => 'news', | ||||||
|  | 					'Mailer' => 'mailer', | ||||||
|  | 					'Pages' => 'pages', | ||||||
|  | 					'Menus' => 'menus', | ||||||
|  | 					'Plugins' => 'plugins', | ||||||
|  | 					'Visitors' => 'visitors', | ||||||
|  | 					'Editor' => array( | ||||||
|  | 						'Accounts' => 'accounts', | ||||||
|  | 						'Players' => 'players', | ||||||
|  | 					), | ||||||
|  | 					'Items' => 'items', | ||||||
|  | 					'Tools' => array( | ||||||
|  | 						'Notepad' => 'notepad', | ||||||
|  | 						'phpinfo' => 'phpinfo', | ||||||
|  | 					), | ||||||
|  | 					'Logs' => array( | ||||||
|  | 						'Logs' => 'logs', | ||||||
|  | 						'Reports' => 'reports', | ||||||
|  | 					), | ||||||
|  | 				); | ||||||
|  |  | ||||||
|  | 				$i = 0; | ||||||
|  | 				foreach ($menus as $_name => $_page) { | ||||||
|  | 					$has_child = is_array($_page); | ||||||
|  | 					if (!$has_child) { | ||||||
|  | 						echo '<li '; | ||||||
|  | 						if ($page == $_page) echo ' class="active"'; | ||||||
|  | 						echo ">"; | ||||||
|  | 						echo '<a href="?p=' . $_page . '"><i class="fa fa-' . (isset($icons_a[$i]) ? $icons_a[$i] : 'link') . '"></i> <span>' . $_name . '</span></a></li>'; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 							$has_child = is_array($menu['link']); | 					if ($has_child) { | ||||||
| 							if (!$has_child) { ?> | 						$used_menu = ""; | ||||||
| 								<li class="nav-item"> |  | ||||||
| 									<a class="nav-link<?php echo(strpos($menu['link'], $page) !== false ? ' active' : '') ?>" href="?p=<?php echo $menu['link'] ?>"> |  | ||||||
| 										<i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i> |  | ||||||
| 										<p><?php echo $menu['name'] ?></p> |  | ||||||
| 									</a> |  | ||||||
| 								</li> |  | ||||||
| 								<?php |  | ||||||
| 							} else if ($has_child) { |  | ||||||
| 								$used_menu = null; |  | ||||||
| 						$nav_construct = ''; | 						$nav_construct = ''; | ||||||
| 								foreach ($menu['link'] as $sub_category => $sub_menu) { | 						foreach ($_page as $__name => $__page) { | ||||||
| 									$nav_construct .= '<li class="nav-item"><a href="?p=' . $sub_menu['link'] . '" class="nav-link'; | 							$nav_construct = $nav_construct . '<li'; | ||||||
| 									if ($_SERVER['QUERY_STRING'] == 'p=' . $sub_menu['link']) { |  | ||||||
| 										$nav_construct .= ' active'; | 							if ($page == $__page) { | ||||||
|  | 								$nav_construct = $nav_construct . ' class="active"'; | ||||||
| 								$used_menu = true; | 								$used_menu = true; | ||||||
| 							} | 							} | ||||||
| 									$nav_construct .= '"><i class="fas fa-' . ($sub_menu['icon'] ?? 'circle') . ' nav-icon"></i><p>' . $sub_menu['name'] . '</p></a></li>'; | 							$nav_construct = $nav_construct . '><a href="?p=' . $__page . '"><i class="fa fa-circle-o"></i> ' . $__name . '</a></li>'; | ||||||
| 						} | 						} | ||||||
| 								?> |  | ||||||
| 								<li class="nav-item has-treeview<?php echo($used_menu ? ' menu-open' : '') ?>"> | 						echo '<li class="treeview' . (($used_menu) ? ' menu-open' : '') . '"> | ||||||
| 									<a href="#" class="nav-link<?php echo($used_menu ? ' active' : '') ?>"> |                                       <a href="#"><i class="fa fa-' . (isset($icons_a[$i]) ? $icons_a[$i] : 'link') . '"></i> <span>' . $_name . '</span> | ||||||
| 										<i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i> | 						              <span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a> | ||||||
| 										<p><?php echo $menu['name'] ?></p><i class="right fas fa-angle-left"></i> | 						              <ul class="treeview-menu" style="' . (($used_menu) ? '  display: block' : ' display: none') . '">'; | ||||||
| 									</a> | 						echo $nav_construct; | ||||||
| 									<ul class="nav nav-treeview"> | 						echo '</ul> | ||||||
| 										<?php echo $nav_construct; ?> |                                 </li>'; | ||||||
| 									</ul> |  | ||||||
| 								</li> |  | ||||||
| 								<?php |  | ||||||
| 					} | 					} | ||||||
|  | 					$i++; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				$query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`'); | 				$query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`'); | ||||||
| 				$menu_db = $query->fetchAll(); | 				$menu_db = $query->fetchAll(); | ||||||
| 				foreach ($menu_db as $item) { | 				foreach ($menu_db as $item) { | ||||||
| 							if ($item['flags'] == 0 || hasFlag($item['flags'])) { ?> | 					if ($item['flags'] == 0 || hasFlag($item['flags'])) { | ||||||
| 								<li class="nav-item"> | 						echo '<li '; | ||||||
| 									<a class="nav-link<?php echo($page == $item['page'] ? ' active' : '') ?>" href="?p=<?php echo $item['page'] ?>"> | 						if ($page == $item['page']) echo ' class="active"'; | ||||||
| 										<i class="nav-icon fas fa-link"></i> | 						echo ">"; | ||||||
| 										<p><?php echo $item['name'] ?></p> | 						echo '<a href="?p=' . $item['page'] . '"><i class="fa fa-link"></i> <span>' . $item['name'] . '</span></a></li>'; | ||||||
| 									</a> |  | ||||||
| 								</li> |  | ||||||
| 								<?php |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				?> | 				?> | ||||||
| 			</ul> | 			</ul> | ||||||
| 				</nav> | 		</section> | ||||||
| 			</div> |  | ||||||
| 	</aside> | 	</aside> | ||||||
|  |  | ||||||
| 		<div class="content-wrapper" style="min-height: 823px;"> | 	<div class="content-wrapper"> | ||||||
| 			<div class="content-header"> | 		<section class="content-header"> | ||||||
| 				<div class="container-fluid"> | 			<h1><?php echo(isset($title) ? $title : ''); ?> | ||||||
| 					<div class="row mb-2"> | 				<small> - Admin Panel</small> | ||||||
| 						<div class="col-sm-6"> | 				<div class="pull-right"> | ||||||
| 							<h3 class="m-0 text-dark"><?php echo(isset($title) ? $title : ''); ?><small> - Admin Panel</small></h3> | 					<span class="label label-<?php echo(($status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span> | ||||||
| 				</div> | 				</div> | ||||||
| 						<div class="col-sm-6"> | 			</h1> | ||||||
| 							<div class="float-sm-right d-none d-sm-inline"> | 		</section> | ||||||
| 								<span class="p-2 right badge badge-<?php echo((isset($status['online']) and $status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span> | 		<section class="content"> | ||||||
| 							</div> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
| 				</div> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="content"> |  | ||||||
| 				<div class="container-fluid"> |  | ||||||
| 			<?php echo $content; ?> | 			<?php echo $content; ?> | ||||||
| 				</div> | 		</section> | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
|  |  | ||||||
| 		<aside class="control-sidebar control-sidebar-dark"> |  | ||||||
| 			<div class="p-3"> |  | ||||||
| 				<h4>Account:</h4> |  | ||||||
| 				<p><h5><a href="?action=logout"><i class="fas fa-sign-out-alt text-danger"></i> Log out</h5></a> |  | ||||||
| 				<small>This will log you out</small></p> |  | ||||||
| 	</div> | 	</div> | ||||||
| 			<div class="p-3"> |  | ||||||
| 				<h4>Site:</h4> |  | ||||||
| 				<p><h5><a href="<?php echo BASE_URL; ?>" target="_blank"><i class="far fa-eye text-blue"></i> Preview</a></h5> |  | ||||||
| 				<small>This will open a new tab</small></p> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="p-3"> |  | ||||||
| 				<h4>Version:</h4> |  | ||||||
| 				<p><h5><a href="?p=version"><i class="fas fa-code-branch"></i> <?php echo MYAAC_VERSION; ?></a></h5> |  | ||||||
| 				<small>Check for updates</small></p> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="p-3"> |  | ||||||
| 				<h4>Site:</h4> |  | ||||||
| 				<p><h5><a href="https://github.com/slawkens/myaac" target="_blank"><i class="fab fa-github"></i> Github</a></h5> |  | ||||||
| 				<small>Goto GitHub Page</small></p> |  | ||||||
|  |  | ||||||
| 				<p><h5><a href="http://my-aac.org/" target="_blank"><i class="fas fa-shoe-prints"></i> MyAAC Official</a></h5> |  | ||||||
| 				<small>Goto MyAAC Official Website</small></p> |  | ||||||
|  |  | ||||||
| 				<p><h5><a href="?p=open_source"><i class="fas fa-wrench"></i> Open Source</a></h5> |  | ||||||
| 				<small>View Open Source Software MyAAC is using</small></p> |  | ||||||
| 			</div> |  | ||||||
| 		</aside> |  | ||||||
|  |  | ||||||
| 	<footer class="main-footer"> | 	<footer class="main-footer"> | ||||||
| 			<div class="float-sm-right d-none d-sm-inline"> |  | ||||||
| 				<span class="p-2 right badge badge-<?php echo((isset($status['online']) and $status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span> | 		<div class="pull-right hidden-xs"> | ||||||
|  | 			<div id="status"> | ||||||
|  | 				<?php if ($status['online']): ?> | ||||||
|  | 					<p class="success" style="width: 120px; text-align: center;">Server Online</p> | ||||||
|  | 				<?php else: ?> | ||||||
|  | 					<p class="error" style="width: 120px; text-align: center;">Server Offline</p> | ||||||
|  | 				<?php endif; ?> | ||||||
|  | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?> | 		<?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?> | ||||||
| 	</footer> | 	</footer> | ||||||
| 		<div id="sidebar-overlay"></div> |  | ||||||
|  | 	<aside class="control-sidebar control-sidebar-dark"> | ||||||
|  | 		<ul class="nav nav-tabs nav-justified control-sidebar-tabs"> | ||||||
|  | 			<li class="active"><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li> | ||||||
|  | 			<li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gears"></i></a></li> | ||||||
|  | 		</ul> | ||||||
|  | 		<div class="tab-content"> | ||||||
|  | 			<div class="tab-pane active" id="control-sidebar-home-tab"> | ||||||
|  | 				<h3 class="control-sidebar-heading">Account</h3> | ||||||
|  | 				<ul class="control-sidebar-menu"> | ||||||
|  | 					<li> | ||||||
|  | 						<a href="?action=logout"> | ||||||
|  | 							<i class="menu-icon fa  fa-sign-out bg-red"></i> | ||||||
|  | 							<div class="menu-info"> | ||||||
|  | 								<h4 class="control-sidebar-subheading">Log out</h4> | ||||||
|  | 								<p>This will log you out | ||||||
|  | 									of <?php echo(USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()); ?></p> | ||||||
|  | 							</div> | ||||||
|  | 						</a> | ||||||
|  | 					</li> | ||||||
|  | 				</ul> | ||||||
|  | 				<h3 class="control-sidebar-heading">Site</h3> | ||||||
|  | 				<ul class="control-sidebar-menu"> | ||||||
|  | 					<li> | ||||||
|  | 						<a href="<?php echo BASE_URL; ?>" target="_blank"> | ||||||
|  | 							<i class="menu-icon fa  fa-eye bg-blue"></i> | ||||||
|  | 							<div class="menu-info"> | ||||||
|  | 								<h4 class="control-sidebar-subheading">Preview</h4> | ||||||
|  | 								<p>This will open a new tab</p> | ||||||
|  | 							</div> | ||||||
|  | 						</a> | ||||||
|  | 					</li> | ||||||
|  | 				</ul> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="tab-pane" id="control-sidebar-settings-tab"> | ||||||
|  | 				<form method="post"> | ||||||
|  | 					<h3 class="control-sidebar-heading">Version</h3> | ||||||
|  |  | ||||||
|  | 					<div class="form-group"> | ||||||
|  | 						<label class="control-sidebar-subheading"> | ||||||
|  | 							<?php echo MYAAC_VERSION; ?> (<a href="?p=version">Check for updates</a>)<br/> | ||||||
|  | 						</label> | ||||||
|  | 						<label class="control-sidebar-subheading"> | ||||||
|  | 							<p><a href="https://github.com/slawkens/myaac" target="_blank">Github</a></p> | ||||||
|  | 					</div> | ||||||
|  | 				</form> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 	</aside> | ||||||
|  | 	<div class="control-sidebar-bg"></div> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
| <?php } else if (!$logged && !admin()) { | <?php } | ||||||
|  | if (!$logged && !admin()) { | ||||||
| 	echo $content; | 	echo $content; | ||||||
| } | } | ||||||
| ?> | ?> | ||||||
| <?php |  | ||||||
| /** | <script src="<?php echo BASE_URL; ?>tools/js/bootstrap.min.js"></script> | ||||||
|  * @var OTS_Account $account_logged | <script src="<?php echo BASE_URL; ?>tools/js/jquery-ui.min.js"></script> | ||||||
|  */ | <script src="<?php echo BASE_URL; ?>tools/js/jquery.dataTables.min.js"></script> | ||||||
| if ($logged && admin()) { |  | ||||||
| 	$twig->display('admin-bar.html.twig', [ |  | ||||||
| 		'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId() |  | ||||||
| 	]); |  | ||||||
| } |  | ||||||
| ?> |  | ||||||
| <script src="<?php echo BASE_URL; ?>tools/ext/bootstrap/js/bootstrap.min.js"></script> |  | ||||||
| <script src="<?php echo BASE_URL; ?>tools/ext/jquery-ui/jquery-ui.min.js"></script> |  | ||||||
| <?php if (isset($use_datatable))  { ?> |  | ||||||
| <script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script> |  | ||||||
| <script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script> |  | ||||||
| <?php } ?> |  | ||||||
| <script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script> | <script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script> | ||||||
| <?php $hooks->trigger(HOOK_ADMIN_BODY_END); ?> |  | ||||||
| </body> | </body> | ||||||
| </html> | </html> | ||||||
| @@ -1,6 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| const MYAAC_ADMIN = true; | define('MYAAC_ADMIN', true); | ||||||
| const IGNORE_SET_LAST_VISIT = true; |  | ||||||
|  |  | ||||||
| require '../../common.php'; | require '../../common.php'; | ||||||
| require SYSTEM . 'functions.php'; | require SYSTEM . 'functions.php'; | ||||||
|   | |||||||
| @@ -1,48 +0,0 @@ | |||||||
| <?php |  | ||||||
| /** |  | ||||||
|  * Project: MyAAC |  | ||||||
|  *     Automatic Account Creator for Open Tibia Servers |  | ||||||
|  * |  | ||||||
|  * This is free software; you can redistribute it and/or |  | ||||||
|  * modify it under the terms of the GNU Lesser General Public |  | ||||||
|  * License as published by the Free Software Foundation; either |  | ||||||
|  * version 2.1 of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This software is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU |  | ||||||
|  * Lesser General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Lesser General Public |  | ||||||
|  * License along with this library; if not, write to the Free Software |  | ||||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA |  | ||||||
|  * |  | ||||||
|  * @package   MyAAC |  | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  | ||||||
|  * @copyright 2020 MyAAC |  | ||||||
|  * @link      https://my-aac.org |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| use MyAAC\DataLoader; |  | ||||||
|  |  | ||||||
| const MYAAC_ADMIN = true; |  | ||||||
| const IGNORE_SET_LAST_VISIT = true; |  | ||||||
|  |  | ||||||
| require '../../common.php'; |  | ||||||
| require SYSTEM . 'functions.php'; |  | ||||||
| require SYSTEM . 'init.php'; |  | ||||||
| require SYSTEM . 'login.php'; |  | ||||||
|  |  | ||||||
| if (!admin()) |  | ||||||
| 	die('Access denied.'); |  | ||||||
|  |  | ||||||
| ini_set('max_execution_time', 300); |  | ||||||
| ob_implicit_flush(); |  | ||||||
| @ob_end_flush(); |  | ||||||
| header('X-Accel-Buffering: no'); |  | ||||||
|  |  | ||||||
| require LOCALE . 'en/main.php'; |  | ||||||
| require LOCALE . 'en/install.php'; |  | ||||||
|  |  | ||||||
| DataLoader::setLocale($locale); |  | ||||||
| DataLoader::load(); |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| use MyAAC\Settings; |  | ||||||
|  |  | ||||||
| const MYAAC_ADMIN = true; |  | ||||||
| const IGNORE_SET_LAST_VISIT = true; |  | ||||||
|  |  | ||||||
| require '../../common.php'; |  | ||||||
| require SYSTEM . 'functions.php'; |  | ||||||
| require SYSTEM . 'init.php'; |  | ||||||
| require SYSTEM . 'login.php'; |  | ||||||
|  |  | ||||||
| if(!admin()) { |  | ||||||
| 	http_response_code(500); |  | ||||||
| 	die('Access denied.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| csrfProtect(); |  | ||||||
|  |  | ||||||
| if (!isset($_REQUEST['plugin'])) { |  | ||||||
| 	http_response_code(500); |  | ||||||
| 	die('Please enter plugin name.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (!isset($_POST['settings'])) { |  | ||||||
| 	http_response_code(500); |  | ||||||
| 	die('Please enter settings.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $settings = Settings::getInstance(); |  | ||||||
|  |  | ||||||
| $success = $settings->save($_REQUEST['plugin'], $_POST['settings']); |  | ||||||
|  |  | ||||||
| $errors = $settings->getErrors(); |  | ||||||
| if (count($errors) > 0) { |  | ||||||
| 	http_response_code(500); |  | ||||||
| 	die(implode('<br/>', $errors)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if ($success) { |  | ||||||
| 	echo 'Saved at ' . date('H:i'); |  | ||||||
| } |  | ||||||
| @@ -1,6 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| const MYAAC_ADMIN = true; | define('MYAAC_ADMIN', true); | ||||||
| const IGNORE_SET_LAST_VISIT = true; |  | ||||||
|  |  | ||||||
| require '../../common.php'; | require '../../common.php'; | ||||||
| require SYSTEM . 'init.php'; | require SYSTEM . 'init.php'; | ||||||
|   | |||||||
| @@ -1,54 +0,0 @@ | |||||||
| <?php |  | ||||||
| const MYAAC_ADMIN = true; |  | ||||||
| const IGNORE_SET_LAST_VISIT = true; |  | ||||||
|  |  | ||||||
| require '../../common.php'; |  | ||||||
| require SYSTEM . 'functions.php'; |  | ||||||
| require SYSTEM . 'init.php'; |  | ||||||
| require SYSTEM . 'login.php'; |  | ||||||
|  |  | ||||||
| if(!admin()) |  | ||||||
| 	die('Access denied.'); |  | ||||||
|  |  | ||||||
| // Don't attempt to process the upload on an OPTIONS request |  | ||||||
| if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { |  | ||||||
| 	header('Access-Control-Allow-Methods: POST, OPTIONS'); |  | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $imageFolder = BASE . EDITOR_IMAGES_DIR; |  | ||||||
|  |  | ||||||
| reset ($_FILES); |  | ||||||
| $temp = current($_FILES); |  | ||||||
| if (is_uploaded_file($temp['tmp_name'])) { |  | ||||||
| 	header('Access-Control-Allow-Credentials: true'); |  | ||||||
| 	header('P3P: CP="There is no P3P policy."'); |  | ||||||
|  |  | ||||||
| 	// Sanitize input |  | ||||||
| 	if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) { |  | ||||||
| 		header('HTTP/1.1 400 Invalid file name.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Verify extension |  | ||||||
| 	$ext = strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)); |  | ||||||
| 	if (!in_array($ext, ['gif', 'jpg', 'png'])) { |  | ||||||
| 		header('HTTP/1.1 400 Invalid extension.'); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	do { |  | ||||||
| 		$randomName = generateRandomString(8). ".$ext"; |  | ||||||
| 		$fileToWrite = $imageFolder . $randomName; |  | ||||||
| 	} while (file_exists($fileToWrite)); |  | ||||||
|  |  | ||||||
| 	move_uploaded_file($temp['tmp_name'], $fileToWrite); |  | ||||||
|  |  | ||||||
| 	$returnPathToImage = BASE_URL . EDITOR_IMAGES_DIR . $randomName; |  | ||||||
| 	echo json_encode(['location' => $returnPathToImage]); |  | ||||||
| } else { |  | ||||||
| 	// Notify editor that the upload failed |  | ||||||
| 	header('HTTP/1.1 500 Server Error'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										184
									
								
								common.php
									
									
									
									
									
								
							
							
						
						| @@ -20,151 +20,111 @@ | |||||||
|  * |  * | ||||||
|  * @package   MyAAC |  * @package   MyAAC | ||||||
|  * @author    Slawkens <slawkens@gmail.com> |  * @author    Slawkens <slawkens@gmail.com> | ||||||
|  * @copyright 2024 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
| if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); | if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); | ||||||
|  |  | ||||||
| const MYAAC = true; | define('MYAAC', true); | ||||||
| const MYAAC_VERSION = '1.8.4'; | define('MYAAC_VERSION', '0.8.24'); | ||||||
| const DATABASE_VERSION = 46; | define('DATABASE_VERSION', 33); | ||||||
| const TABLE_PREFIX = 'myaac_'; | define('TABLE_PREFIX', 'myaac_'); | ||||||
| define('START_TIME', microtime(true)); | define('START_TIME', microtime(true)); | ||||||
| define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); | define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); | ||||||
| define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb'])); | define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb'])); | ||||||
|  |  | ||||||
| // account flags | // account flags | ||||||
| const FLAG_NONE = 0; | define('FLAG_ADMIN', 1); | ||||||
| const FLAG_ADMIN = 1; | define('FLAG_SUPER_ADMIN', 2); | ||||||
| const FLAG_SUPER_ADMIN = 2; | define('FLAG_CONTENT_PAGES', 4); | ||||||
| const FLAG_SUPER_BOTH = 3; | define('FLAG_CONTENT_MAILER', 8); | ||||||
| const FLAG_CONTENT_PAGES = 4; | define('FLAG_CONTENT_NEWS', 16); | ||||||
| const FLAG_CONTENT_MAILER = 8; | define('FLAG_CONTENT_FORUM', 32); | ||||||
| const FLAG_CONTENT_NEWS = 16; | define('FLAG_CONTENT_COMMANDS', 64); | ||||||
| const FLAG_CONTENT_FORUM = 32; | define('FLAG_CONTENT_SPELLS', 128); | ||||||
| const FLAG_CONTENT_COMMANDS = 64; | define('FLAG_CONTENT_MONSTERS', 256); | ||||||
| const FLAG_CONTENT_SPELLS = 128; | define('FLAG_CONTENT_GALLERY', 512); | ||||||
| const FLAG_CONTENT_MONSTERS = 256; | define('FLAG_CONTENT_VIDEOS', 1024); | ||||||
| const FLAG_CONTENT_GALLERY = 512; | define('FLAG_CONTENT_FAQ', 2048); | ||||||
| const FLAG_CONTENT_VIDEOS = 1024; | define('FLAG_CONTENT_MENUS', 4096); | ||||||
| const FLAG_CONTENT_FAQ = 2048; | define('FLAG_CONTENT_PLAYERS', 8192); | ||||||
| const FLAG_CONTENT_MENUS = 4096; |  | ||||||
| const FLAG_CONTENT_PLAYERS = 8192; |  | ||||||
|  |  | ||||||
| // account access types |  | ||||||
| const ACCOUNT_WEB_FLAGS = [ |  | ||||||
| 	FLAG_NONE => 'None', |  | ||||||
| 	FLAG_ADMIN =>'Admin', |  | ||||||
| 	FLAG_SUPER_ADMIN => 'Super Admin', |  | ||||||
| 	FLAG_SUPER_BOTH =>'(Admin + Super Admin)', |  | ||||||
| ]; |  | ||||||
|  |  | ||||||
| // news | // news | ||||||
| const NEWS = 1; | define('NEWS', 1); | ||||||
| const TICKER = 2; | define('TICKER', 2); | ||||||
| const ARTICLE = 3; | define('ARTICLE', 3); | ||||||
|  |  | ||||||
| // here you can change location of admin panel |  | ||||||
| // you need also to rename folder "admin" |  | ||||||
| // this may improve security |  | ||||||
| const ADMIN_PANEL_FOLDER = 'admin'; |  | ||||||
|  |  | ||||||
| // directories | // directories | ||||||
| const BASE = __DIR__ . '/'; | define('BASE', __DIR__ . '/'); | ||||||
| const ADMIN = BASE . ADMIN_PANEL_FOLDER . '/'; | define('ADMIN', BASE . 'admin/'); | ||||||
| const SYSTEM = BASE . 'system/'; | define('SYSTEM', BASE . 'system/'); | ||||||
| const CACHE = SYSTEM . 'cache/'; | define('CACHE', SYSTEM . 'cache/'); | ||||||
| const LOCALE = SYSTEM . 'locale/'; | define('LOCALE', SYSTEM . 'locale/'); | ||||||
| const LIBS = SYSTEM . 'libs/'; | define('LIBS', SYSTEM . 'libs/'); | ||||||
| const LOGS = SYSTEM . 'logs/'; | define('LOGS', SYSTEM . 'logs/'); | ||||||
| const PAGES = SYSTEM . 'pages/'; | define('PAGES', SYSTEM . 'pages/'); | ||||||
| const PLUGINS = BASE . 'plugins/'; | define('PLUGINS', BASE . 'plugins/'); | ||||||
| const TEMPLATES = BASE . 'templates/'; | define('TEMPLATES', BASE . 'templates/'); | ||||||
| const TOOLS = BASE . 'tools/'; | define('TOOLS', BASE . 'tools/'); | ||||||
| const VENDOR = BASE . 'vendor/'; |  | ||||||
|  |  | ||||||
| // other dirs |  | ||||||
| const SESSIONS_DIR = SYSTEM . 'php_sessions'; |  | ||||||
| const GUILD_IMAGES_DIR = 'images/guilds/'; |  | ||||||
| const EDITOR_IMAGES_DIR = 'images/editor/'; |  | ||||||
| const GALLERY_DIR = 'images/gallery/'; |  | ||||||
|  |  | ||||||
| // menu categories | // menu categories | ||||||
| const MENU_CATEGORY_NEWS = 1; | define('MENU_CATEGORY_NEWS', 1); | ||||||
| const MENU_CATEGORY_ACCOUNT = 2; | define('MENU_CATEGORY_ACCOUNT', 2); | ||||||
| const MENU_CATEGORY_COMMUNITY = 3; | define('MENU_CATEGORY_COMMUNITY', 3); | ||||||
| const MENU_CATEGORY_FORUM = 4; | define('MENU_CATEGORY_FORUM', 4); | ||||||
| const MENU_CATEGORY_LIBRARY = 5; | define('MENU_CATEGORY_LIBRARY', 5); | ||||||
| const MENU_CATEGORY_SHOP = 6; | define('MENU_CATEGORY_SHOP', 6); | ||||||
|  |  | ||||||
| // otserv versions | // otserv versions | ||||||
| const OTSERV = 1; | define('OTSERV', 1); | ||||||
| const OTSERV_06 = 2; | define('OTSERV_06', 2); | ||||||
| const OTSERV_FIRST = OTSERV; | define('OTSERV_FIRST', OTSERV); | ||||||
| const OTSERV_LAST = OTSERV_06; | define('OTSERV_LAST', OTSERV_06); | ||||||
| const TFS_02 = 3; | define('TFS_02', 3); | ||||||
| const TFS_03 = 4; | define('TFS_03', 4); | ||||||
| const TFS_FIRST = TFS_02; | define('TFS_FIRST', TFS_02); | ||||||
| const TFS_LAST = TFS_03; | define('TFS_LAST', TFS_03); | ||||||
|  |  | ||||||
| // other definitions |  | ||||||
| const MAIL_MAIL = 0; |  | ||||||
| const MAIL_SMTP = 1; |  | ||||||
|  |  | ||||||
| const SMTP_SECURITY_NONE = 0; |  | ||||||
| const SMTP_SECURITY_SSL = 1; |  | ||||||
| const SMTP_SECURITY_TLS = 2; |  | ||||||
|  |  | ||||||
| const ACCOUNT_NUMBER_LENGTH = 8; |  | ||||||
|  |  | ||||||
| if (!IS_CLI) { | if (!IS_CLI) { | ||||||
| 	session_save_path(SESSIONS_DIR); | 	session_save_path(SYSTEM . 'php_sessions'); | ||||||
| 	session_start(); | 	session_start(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // basedir | ||||||
|  | $basedir = ''; | ||||||
|  | $tmp = explode('/', $_SERVER['SCRIPT_NAME']); | ||||||
|  | $size = count($tmp) - 1; | ||||||
|  | for($i = 1; $i < $size; $i++) | ||||||
|  | 	$basedir .= '/' . $tmp[$i]; | ||||||
|  |  | ||||||
|  | $basedir = str_replace(array('/admin', '/install', '/tools'), '', $basedir); | ||||||
|  | define('BASE_DIR', $basedir); | ||||||
|  |  | ||||||
| if (file_exists(BASE . 'config.local.php')) { | if (file_exists(BASE . 'config.local.php')) { | ||||||
| 	require BASE . 'config.local.php'; | 	require BASE . 'config.local.php'; | ||||||
| } | } | ||||||
|  |  | ||||||
| require SYSTEM . 'base.php'; |  | ||||||
| define('BASE_DIR', $baseDir); |  | ||||||
|  |  | ||||||
| if(!IS_CLI) { | if(!IS_CLI) { | ||||||
| 	if (isset($config['site_url'])) { | 	if (isset($_SERVER['HTTP_HOST'][0])) { | ||||||
| 		$hasSlashAtEnd = ($config['site_url'][strlen($config['site_url']) - 1] == '/'); | 		$baseHost = $_SERVER['HTTP_HOST']; | ||||||
|  | 	} else { | ||||||
| 		define('SERVER_URL', $config['site_url']); | 		if (isset($_SERVER['SERVER_NAME'][0])) { | ||||||
| 		define('BASE_URL', SERVER_URL . ($hasSlashAtEnd ? '' : '/')); | 			$baseHost = $_SERVER['SERVER_NAME']; | ||||||
| 		define('ADMIN_URL', SERVER_URL . ($hasSlashAtEnd ? '' : '/') . ADMIN_PANEL_FOLDER . '/'); | 		} else { | ||||||
|  | 			$baseHost = $_SERVER['SERVER_ADDR']; | ||||||
| 		} | 		} | ||||||
| 	else { | 	} | ||||||
|  |  | ||||||
| 	define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost); | 	define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost); | ||||||
| 	define('BASE_URL', SERVER_URL . BASE_DIR . '/'); | 	define('BASE_URL', SERVER_URL . BASE_DIR . '/'); | ||||||
| 		define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/'); | 	define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/'); | ||||||
|  |  | ||||||
| 	//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); | 	//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); | ||||||
|  | 	if(@$config['env'] === 'dev') { | ||||||
|  | 		require SYSTEM . 'exception.php'; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | require SYSTEM . 'autoload.php'; | ||||||
| /** @var array $config */ |  | ||||||
| ini_set('log_errors', 1); |  | ||||||
| if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) { |  | ||||||
| 	ini_set('display_errors', 1); |  | ||||||
| 	ini_set('display_startup_errors', 1); |  | ||||||
| 	error_reporting(E_ALL); |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| 	ini_set('display_errors', 0); |  | ||||||
| 	ini_set('display_startup_errors', 0); |  | ||||||
| 	error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $autoloadFile = VENDOR . 'autoload.php'; |  | ||||||
| if (!is_file($autoloadFile)) { |  | ||||||
| 	throw new RuntimeException('The vendor folder is missing. Please download Composer: <a href="https://getcomposer.org/download">https://getcomposer.org/download</a>, install it and execute in the main MyAAC directory this command: <b>composer install</b>. Or download MyAAC from <a href="https://github.com/slawkens/myaac/releases">GitHub releases</a>, which includes Vendor folder.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| require $autoloadFile; |  | ||||||
|  |  | ||||||
| function isHttps(): bool | function isHttps(): bool | ||||||
| { | { | ||||||
|   | |||||||
| @@ -1,33 +0,0 @@ | |||||||
| { |  | ||||||
|     "require": { |  | ||||||
|         "php": "^8.1", |  | ||||||
|         "ext-pdo": "*", |  | ||||||
|         "ext-pdo_mysql": "*", |  | ||||||
|         "ext-json": "*", |  | ||||||
|         "ext-xml": "*", |  | ||||||
|         "ext-dom": "*", |  | ||||||
|         "phpmailer/phpmailer": "^6.1", |  | ||||||
|         "composer/semver": "^3.2", |  | ||||||
|         "twig/twig": "^3.11", |  | ||||||
|         "erusev/parsedown": "^1.7", |  | ||||||
|         "nikic/fast-route": "^1.3", |  | ||||||
|         "matomo/device-detector": "^6.0", |  | ||||||
|         "illuminate/database": "^10.18", |  | ||||||
|         "peppeocchi/php-cron-scheduler": "4.*", |  | ||||||
|         "symfony/console": "^6.4", |  | ||||||
|         "symfony/string": "^6.4", |  | ||||||
|         "symfony/var-dumper": "^6.4", |  | ||||||
|         "filp/whoops": "^2.15", |  | ||||||
|         "maximebf/debugbar": "1.*", |  | ||||||
|         "guzzlehttp/guzzle": "7.9.3" |  | ||||||
|     }, |  | ||||||
|     "require-dev": { |  | ||||||
|         "phpstan/phpstan": "^1.10" |  | ||||||
|     }, |  | ||||||
|     "autoload": { |  | ||||||
|         "psr-4": { |  | ||||||
|             "MyAAC\\": "system/src" |  | ||||||
|         }, |  | ||||||
|         "files": ["system/src/global.php"] |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										3455
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
							
								
								
									
										302
									
								
								config.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,302 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * This is MyAAC's Main Configuration file | ||||||
|  |  * | ||||||
|  |  * All the default values are kept here, you should not modify it but use | ||||||
|  |  * a config.local.php file instead to override the settings from here. | ||||||
|  |  * | ||||||
|  |  * This is a piece of PHP code so PHP syntax applies! | ||||||
|  |  * For boolean values please use true/false. | ||||||
|  |  * | ||||||
|  |  * Minimally 'server_path' directive have to be filled, other options are optional. | ||||||
|  |  * | ||||||
|  |  * @package   MyAAC | ||||||
|  |  * @author    Slawkens <slawkens@gmail.com> | ||||||
|  |  * @copyright 2019 MyAAC | ||||||
|  |  * @link      https://my-aac.org | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | $config = array( | ||||||
|  | 	// directories & files | ||||||
|  | 	'server_path' => '', // path to the server directory (same directory where config file is located) | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Environment Setting | ||||||
|  | 	 * | ||||||
|  | 	 * if you use this script on your live server - set to 'prod' (production) | ||||||
|  | 	 * if you want to test and debug the script locally, or develop plugins, set to 'dev' (development) | ||||||
|  | 	 * WARNING: on 'dev' cache is disabled, so site will be significantly slower !!! | ||||||
|  | 	 * WARNING2: on 'dev' all PHP errors/warnings are displayed | ||||||
|  | 	 * Recommended: 'prod' cause of speed (page load time is better) | ||||||
|  | 	 */ | ||||||
|  | 	'env' => 'prod', // 'prod' for production and 'dev' for development | ||||||
|  |  | ||||||
|  | 	'template' => 'kathrine', // template used by website (kathrine, tibiacom) | ||||||
|  | 	'template_allow_change' => true, // allow users to choose their own template while browsing website? | ||||||
|  |  | ||||||
|  | 	'vocations_amount' => 4, // how much basic vocations your server got (without promotion) | ||||||
|  |  | ||||||
|  | 	// what client version are you using on this OT? | ||||||
|  | 	// used for the Downloads page and some templates aswell | ||||||
|  | 	'client' => 1098, // 954 = client 9.54 | ||||||
|  |  | ||||||
|  | 	'session_prefix' => 'myaac_', // must be unique for every site on your server | ||||||
|  | 	'friendly_urls' => false, // mod_rewrite is required for this, it makes links looks more elegant to eye, and also are SEO friendly (example: https://my-aac.org/guilds/Testing instead of https://my-aac.org/?subtopic=guilds&name=Testing). Remember to rename .htaccess.dist to .htaccess | ||||||
|  | 	'gzip_output' => false, // gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles | ||||||
|  |  | ||||||
|  | 	// gesior backward support (templates & pages) | ||||||
|  | 	// allows using gesior templates and pages with myaac | ||||||
|  | 	// might bring some performance when disabled | ||||||
|  | 	'backward_support' => true, | ||||||
|  |  | ||||||
|  | 	// head options (html) | ||||||
|  | 	'meta_description' => 'Tibia is a free massive multiplayer online role playing game (MMORPG).', // description of the site | ||||||
|  | 	'meta_keywords' => 'free online game, free multiplayer game, ots, open tibia server', // keywords list separated by commas | ||||||
|  | 	'title_separator' => ' - ', | ||||||
|  |  | ||||||
|  | 	// footer | ||||||
|  | 	'footer' => ''/*'<br/>Your Server © 2016. All rights reserved.'*/, | ||||||
|  |  | ||||||
|  | 	'language' => 'en', // default language (currently only 'en' available) | ||||||
|  | 	'language_allow_change' => false, | ||||||
|  |  | ||||||
|  | 	'visitors_counter' => true, | ||||||
|  | 	'visitors_counter_ttl' => 10, // how long visitor will be marked as online (in minutes) | ||||||
|  | 	'views_counter' => true, | ||||||
|  |  | ||||||
|  | 	// cache system. by default file cache is used | ||||||
|  | 	'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable. | ||||||
|  | 	'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache) | ||||||
|  |  | ||||||
|  | 	// database details (leave blank for auto detect from config.lua) | ||||||
|  | 	'database_host' => '', | ||||||
|  | 	'database_port' => '', // leave blank to default 3306 | ||||||
|  | 	'database_user' => '', | ||||||
|  | 	'database_password' => '', | ||||||
|  | 	'database_name' => '', | ||||||
|  | 	'database_log' => false, // should database queries be logged and and saved into system/logs/database.log? | ||||||
|  | 	'database_socket' => '', // set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock) | ||||||
|  | 	'database_persistent' => false, // use database permanent connection (like server), may speed up your site | ||||||
|  | 	'database_encryption' => 'sha1', | ||||||
|  |  | ||||||
|  | 	// multiworld system (only TFS 0.3) | ||||||
|  | 	'multiworld' => false, // use multiworld system? | ||||||
|  | 	'worlds' => array( // list of worlds | ||||||
|  | 		//'1' => 'Your World Name', | ||||||
|  | 		//'2' => 'Your Second World Name' | ||||||
|  | 	), | ||||||
|  |  | ||||||
|  | 	// images | ||||||
|  | 	'outfit_images_url' => 'https://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit | ||||||
|  | 	'item_images_url' => 'https://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder | ||||||
|  |  | ||||||
|  | 	// account | ||||||
|  | 	'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager) | ||||||
|  | 	'account_create_auto_login' => false, // auto login after creating account? | ||||||
|  | 	'account_create_character_create' => true, // allow directly to create character on create account page? | ||||||
|  | 	'account_mail_verify' => false, // force users to confirm their email addresses when registering | ||||||
|  | 	'account_mail_confirmed_reward' => [ // reward users for confirming their E-Mails | ||||||
|  | 		// account_mail_verify needs to be enabled too | ||||||
|  | 		'premium_days' => 0, | ||||||
|  | 		'premium_points' => 0, | ||||||
|  | 		'coins' => 0, | ||||||
|  | 		'message' => 'You received %d %s for confirming your E-Mail address.' // example: You received 20 premium points for confirming your E-Mail address. | ||||||
|  | 	], | ||||||
|  | 	'account_mail_unique' => true, // email addresses cannot be duplicated? (one account = one email) | ||||||
|  | 	'account_premium_days' => 0, // default premium days on new account | ||||||
|  | 	'account_premium_points' => 0, // default premium points on new account | ||||||
|  | 	'account_welcome_mail' => true, // send welcome email when user registers | ||||||
|  | 	'account_mail_change' => 2, // how many days user need to change email to account - block hackers | ||||||
|  | 	'account_country' => true, // user will be able to set country of origin when registering account, this information will be viewable in others places aswell | ||||||
|  | 	'account_country_recognize' => true, // should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io | ||||||
|  | 	'account_change_character_name' => false, // can user change their character name for premium points? | ||||||
|  | 	'account_change_character_name_points' => 30, // cost of name change | ||||||
|  | 	'account_change_character_sex' => false, // can user change their character sex for premium points? | ||||||
|  | 	'account_change_character_sex_points' => 30, // cost of sex change | ||||||
|  | 	'characters_per_account' => 10,	// max. number of characters per account | ||||||
|  |  | ||||||
|  | 	// mail | ||||||
|  | 	'mail_enabled' => false, // is aac maker configured to send e-mails? | ||||||
|  | 	'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:) | ||||||
|  | 	'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent | ||||||
|  | 	'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function | ||||||
|  | 		'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/, | ||||||
|  | 		'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/ | ||||||
|  | 	), | ||||||
|  | 	'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function, set to true if you use GMail or Microsoft Outlook) | ||||||
|  | 	'smtp_host' => '', // mail host. smtp.gmail.com for GMail / smtp-mail.outlook.com for Microsoft Outlook | ||||||
|  | 	'smtp_port' => 25, // 25 (default) / 465 (ssl, GMail) / 587 (tls, Microsoft Outlook) | ||||||
|  | 	'smtp_auth' => true, // need authorization? | ||||||
|  | 	'smtp_user' => 'admin@example.org', // here your email username | ||||||
|  | 	'smtp_pass' => '', | ||||||
|  | 	'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook) | ||||||
|  | 	'smtp_debug' => false, // set true to debug (you will see more info in error.log) | ||||||
|  |  | ||||||
|  | 	// reCAPTCHA (prevent spam bots) | ||||||
|  | 	'recaptcha_enabled' => false, // enable recaptcha verification code | ||||||
|  | 	'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha | ||||||
|  | 	'recaptcha_secret_key' => '', | ||||||
|  | 	'recaptcha_theme' => 'light', // light, dark | ||||||
|  |  | ||||||
|  | 	// | ||||||
|  | 	'generate_new_reckey' => true,				// let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key) | ||||||
|  | 	'generate_new_reckey_price' => 20,			// price for new recovery key | ||||||
|  | 	'send_mail_when_change_password' => true,	// send e-mail with new password when change password to account | ||||||
|  | 	'send_mail_when_generate_reckey' => true,	// send e-mail with rec key (key is displayed on page anyway when generate) | ||||||
|  |  | ||||||
|  | 	// genders (aka sex) | ||||||
|  | 	'genders' => array( | ||||||
|  | 		0 => 'Female', | ||||||
|  | 		1 => 'Male' | ||||||
|  | 	), | ||||||
|  |  | ||||||
|  | 	// new character config | ||||||
|  | 	'character_samples' => array( // vocations, format: ID_of_vocation => 'Name of Character to copy' | ||||||
|  | 		//0 => 'Rook Sample', | ||||||
|  | 		1 => 'Sorcerer Sample', | ||||||
|  | 		2 => 'Druid Sample', | ||||||
|  | 		3 => 'Paladin Sample', | ||||||
|  | 		4 => 'Knight Sample' | ||||||
|  | 	), | ||||||
|  |  | ||||||
|  | 	'use_character_sample_skills' => false, | ||||||
|  |  | ||||||
|  | 	// it must show limited number of players after using search in character page | ||||||
|  | 	'characters_search_limit' => 15, | ||||||
|  |  | ||||||
|  | 	// town list used when creating character | ||||||
|  | 	// won't be displayed if there is only one item (rookgaard for example) | ||||||
|  | 	'character_towns' => array(1), | ||||||
|  |  | ||||||
|  | 	// characters length | ||||||
|  | 	// This is the minimum and the maximum length that a player can create a character. It is highly recommend the maximum length to be 21. | ||||||
|  | 	'character_name_min_length' => 4, | ||||||
|  | 	'character_name_max_length' => 21, | ||||||
|  |  | ||||||
|  | 	// list of towns | ||||||
|  | 	// if you use TFS 1.3 with support for 'towns' table in database, then you can ignore this - it will be configured automatically (generated from your .OTBM map) | ||||||
|  | 	'towns' => array( | ||||||
|  | 		0 => 'No town', | ||||||
|  | 		1 => 'Sample town' | ||||||
|  | 	), | ||||||
|  |  | ||||||
|  | 	// guilds | ||||||
|  | 	'guild_management' => true, // enable guild management system on the site? | ||||||
|  | 	'guild_need_level' => 1, // min. level to form a guild | ||||||
|  | 	'guild_need_premium' => true, // require premium account to form a guild? | ||||||
|  | 	'guild_image_size_kb' => 80, // maximum size of the guild logo image in KB (kilobytes) | ||||||
|  | 	'guild_description_chars_limit' => 1000, // limit of guild description | ||||||
|  | 	'guild_description_lines_limit' => 6, // limit of lines, if description has more lines it will be showed as long text, without 'enters' | ||||||
|  | 	'guild_motd_chars_limit' => 150, // limit of MOTD (message of the day) that is shown later in the game on the guild channel | ||||||
|  |  | ||||||
|  | 	// online page | ||||||
|  | 	'online_record' => true, // display players record? | ||||||
|  | 	'online_vocations' => false, // display vocation statistics? | ||||||
|  | 	'online_vocations_images' => false, // display vocation images? | ||||||
|  | 	'online_skulls' => false, // display skull images | ||||||
|  | 	'online_outfit' => true, | ||||||
|  | 	'online_afk' => false, | ||||||
|  |  | ||||||
|  | 	// support list page | ||||||
|  | 	'team_style' => 2, // 1/2 (1 - normal table, 2 - in boxes, grouped by group id) | ||||||
|  | 	'team_display_status' => true, | ||||||
|  | 	'team_display_lastlogin' => true, | ||||||
|  | 	'team_display_world' => false, | ||||||
|  | 	'team_display_outfit' => true, | ||||||
|  |  | ||||||
|  | 	// bans page | ||||||
|  | 	'bans_limit' => 50, | ||||||
|  | 	'bans_display_all' => true, // should all bans be displayed? (sorted page by page) | ||||||
|  |  | ||||||
|  | 	// highscores page | ||||||
|  | 	'highscores_vocation_box' => true, // show 'Choose a vocation' box on the highscores (allowing peoples to sort highscores by vocation)? | ||||||
|  | 	'highscores_vocation' => true, // show player vocation under his nickname? | ||||||
|  | 	'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)? Only 0.3 | ||||||
|  | 	'highscores_balance' => false, // show 'Balance' tab (richest players on the server) | ||||||
|  | 	'highscores_outfit' => true, // show player outfit? | ||||||
|  | 	'highscores_country_box' => false, // doesnt work yet! (not implemented) | ||||||
|  | 	'highscores_groups_hidden' => 3, // this group id and higher won't be shown on the highscores | ||||||
|  | 	'highscores_ids_hidden' => array(0), // this ids of players will be hidden on the highscores (should be ids of samples) | ||||||
|  | 	'highscores_length' => 100, // how many records per page on highscores | ||||||
|  |  | ||||||
|  | 	// characters page | ||||||
|  | 	'characters' => array( // what things to display on character view page (true/false in each option) | ||||||
|  | 		'level' => true, | ||||||
|  | 		'experience' => false, | ||||||
|  | 		'magic_level' => false, | ||||||
|  | 		'balance' => false, | ||||||
|  | 		'marriage_info' => true, // only 0.3 | ||||||
|  | 		'outfit' => true, | ||||||
|  | 		'creation_date' => true, | ||||||
|  | 		'quests' => true, | ||||||
|  | 		'skills' => true, | ||||||
|  | 		'equipment' => true, | ||||||
|  | 		'frags' => false, | ||||||
|  | 		'deleted' => false, // should deleted characters from same account be still listed on the list of characters? When enabled it will show that character is "[DELETED]" | ||||||
|  | 	), | ||||||
|  | 	'quests' => array( | ||||||
|  | 		//'Some Quest' => 123, | ||||||
|  | 		//'Some Quest Two' => 456, | ||||||
|  | 	), // quests list (displayed in character view), name => storage | ||||||
|  | 	'signature_enabled' => true, | ||||||
|  | 	'signature_type' => 'tibian', // signature engine to use: tibian, mango, gesior | ||||||
|  | 	'signature_cache_time' => 5, // how long to store cached file (in minutes), default 5 minutes | ||||||
|  | 	'signature_browser_cache' => 60, // how long to cache by browser (in minutes), default 1 hour | ||||||
|  |  | ||||||
|  | 	// news page | ||||||
|  | 	'news_limit' => 5, // limit of news on the latest news page | ||||||
|  | 	'news_ticker_limit' => 5, // limit of news in tickers (mini news) (0 to disable) | ||||||
|  | 	'news_date_format' => 'j.n.Y', // check php manual date() function for more info about this | ||||||
|  | 	'news_author' => true, // show author of the news | ||||||
|  |  | ||||||
|  | 	// gifts/shop system | ||||||
|  | 	'gifts_system' => false, | ||||||
|  |  | ||||||
|  | 	// support/system | ||||||
|  | 	'bug_report' => true, // this configurable has no effect, its always enabled | ||||||
|  |  | ||||||
|  | 	// forum | ||||||
|  | 	'forum' => 'site', // link to the server forum, set to "site" if you want to use build in forum system, otherwise leave empty if you aren't going to use any forum | ||||||
|  | 	'forum_level_required' => 0, // level required to post, 0 to disable | ||||||
|  | 	'forum_post_interval' => 30, // in seconds | ||||||
|  | 	'forum_posts_per_page' => 20, | ||||||
|  | 	'forum_threads_per_page' => 20, | ||||||
|  | 	// uncomment to force use table for forum | ||||||
|  | 	//'forum_table_prefix' => 'z_', // what forum mysql table to use, z_ (for gesior old forum) or myaac_ (for myaac) | ||||||
|  |  | ||||||
|  | 	// last kills | ||||||
|  | 	'last_kills_limit' => 50, // max. number of deaths shown on the last kills page | ||||||
|  |  | ||||||
|  | 	// status, took automatically from config file if empty | ||||||
|  | 	'status_enabled' => true, // you can disable status checking by settings this to "false" | ||||||
|  | 	'status_ip' => '127.0.0.1', | ||||||
|  | 	'status_port' => '', | ||||||
|  | 	'status_timeout' => 1.0, // how long to wait for the initial response from the server (default: 1 second) | ||||||
|  |  | ||||||
|  | 	// how often to connect to server and update status (default: every minute) | ||||||
|  | 	// if your status timeout in config.lua is bigger, that it will be used instead | ||||||
|  | 	// when server is offline, it will be checked every time web refreshes, ignoring this variable | ||||||
|  | 	'status_interval' => 60, | ||||||
|  |  | ||||||
|  | 	// admin panel | ||||||
|  | 	'admin_panel_modules' => 'lastlogin,points,coins', | ||||||
|  |  | ||||||
|  | 	// other | ||||||
|  | 	'anonymous_usage_statistics' => true, | ||||||
|  | 	'email_lai_sec_interval' => 60, // time in seconds between e-mails to one account from lost account interface, block spam | ||||||
|  | 	'google_analytics_id' => '', // e.g.: UA-XXXXXXX-X | ||||||
|  | 	'experiencetable_columns' => 3, // how many columns to display in experience table page. * experiencetable_rows, 5 = 500 (will show up to 500 level) | ||||||
|  | 	'experiencetable_rows' => 200, // till how many levels in one column | ||||||
|  | 	'date_timezone' => 'Europe/Berlin', // more info at http://php.net/manual/en/timezones.php | ||||||
|  | 	'footer_show_load_time' => true, // display load time of the page in the footer | ||||||
|  |  | ||||||
|  | 	'npc' => array(), | ||||||
|  |  | ||||||
|  | 	// character name blocked | ||||||
|  | 	'character_name_blocked' => array( | ||||||
|  | 		'prefix' => array(), | ||||||
|  | 		'names' => array(), | ||||||
|  | 		'words' => array(), | ||||||
|  | 	), | ||||||
|  |  | ||||||
|  | ); | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| const { defineConfig } = require("cypress"); |  | ||||||
|  |  | ||||||
| module.exports = defineConfig({ |  | ||||||
|   e2e: { |  | ||||||
|     setupNodeEvents(on, config) { |  | ||||||
|       // implement node event listeners here |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
| }); |  | ||||||
| @@ -1,76 +0,0 @@ | |||||||
| describe('Install MyAAC', () => { |  | ||||||
| 	beforeEach(() => { |  | ||||||
| 		// Cypress starts out with a blank slate for each test |  | ||||||
| 		// so we must tell it to visit our website with the `cy.visit()` command. |  | ||||||
| 		// Since we want to visit the same URL at the start of all our tests, |  | ||||||
| 		// we include it in our beforeEach function so that it runs before each test |  | ||||||
| 		cy.visit(Cypress.env('URL')) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go through installer', () => { |  | ||||||
| 		cy.visit(Cypress.env('URL') + '/install/?step=welcome') |  | ||||||
| 		cy.wait(1000) |  | ||||||
|  |  | ||||||
| 		cy.screenshot('install-welcome') |  | ||||||
|  |  | ||||||
| 		// step 1 - Welcome |  | ||||||
| 		cy.get('select[name="lang"]').select('en') |  | ||||||
|  |  | ||||||
| 		//cy.get('input[type=button]').contains('Next »').click() |  | ||||||
|  |  | ||||||
| 		cy.get('form').submit() |  | ||||||
|  |  | ||||||
| 		// step 2 - License |  | ||||||
| 		// just skip |  | ||||||
| 		cy.contains('GNU/GPL License'); |  | ||||||
| 		cy.get('form').submit() |  | ||||||
|  |  | ||||||
| 		// step 3 - Requirements |  | ||||||
| 		cy.contains('Requirements check'); |  | ||||||
|  |  | ||||||
| 		cy.get('#step').then(elem => { |  | ||||||
| 			elem.val('config'); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		cy.get('form').submit() |  | ||||||
|  |  | ||||||
| 		// step 4 - Configuration |  | ||||||
| 		cy.contains('Basic configuration'); |  | ||||||
|  |  | ||||||
| 		cy.get('#vars_server_path').click().clear().type(Cypress.env('SERVER_PATH')) |  | ||||||
|  |  | ||||||
| 		cy.get('[type="checkbox"]').uncheck() // usage statistics uncheck |  | ||||||
|  |  | ||||||
| 		cy.wait(1000) |  | ||||||
|  |  | ||||||
| 		cy.get('form').submit() |  | ||||||
|  |  | ||||||
| 		// check if there is any error |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		// step 5 - Import Schema |  | ||||||
| 		cy.contains('Import MySQL schema'); |  | ||||||
|  |  | ||||||
| 		// AAC is not installed yet, this message should not come |  | ||||||
| 		cy.contains('Seems AAC is already installed. Skipping importing MySQL schema..').should('not.exist') |  | ||||||
|  |  | ||||||
| 		cy.contains('[class="alert alert-success"]', 'Local configuration has been saved into file: config.local.php').should('be.visible') |  | ||||||
|  |  | ||||||
| 		cy.get('form').submit() |  | ||||||
|  |  | ||||||
| 		// step 6 - Admin Account |  | ||||||
| 		cy.get('#vars_email').click().clear().type('admin@my-aac.org') |  | ||||||
| 		cy.get('#vars_account').click().clear().type('admin') |  | ||||||
| 		cy.get('#vars_password').click().clear().type('test1234') |  | ||||||
| 		cy.get('#vars_password_confirm').click().clear().type('test1234') |  | ||||||
| 		cy.get('#vars_player_name').click().clear().type('Admin') |  | ||||||
|  |  | ||||||
| 		cy.get('form').submit() |  | ||||||
|  |  | ||||||
| 		cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 60000 }).should('be.visible') |  | ||||||
|  |  | ||||||
| 		cy.wait(2000); |  | ||||||
|  |  | ||||||
| 		cy.screenshot('install-finish') |  | ||||||
| 	}) |  | ||||||
| }) |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| describe('Create Account Page', () => { |  | ||||||
| 	beforeEach(() => { |  | ||||||
| 		// Cypress starts out with a blank slate for each test |  | ||||||
| 		// so we must tell it to visit our website with the `cy.visit()` command. |  | ||||||
| 		// Since we want to visit the same URL at the start of all our tests, |  | ||||||
| 		// we include it in our beforeEach function so that it runs before each test |  | ||||||
| 		cy.visit(Cypress.env('URL') + '/index.php/account/create') |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Create Test Account', () => { |  | ||||||
| 		cy.screenshot('create-account-page') |  | ||||||
|  |  | ||||||
| 		cy.get('#account_input').type('tester') |  | ||||||
| 		cy.get('#email').type('tester@example.com') |  | ||||||
|  |  | ||||||
| 		cy.get('#password').type('test1234') |  | ||||||
| 		cy.get('#password_confirm').type('test1234') |  | ||||||
|  |  | ||||||
| 		cy.get('#character_name').type('Slaw') |  | ||||||
|  |  | ||||||
| 		cy.get('#sex1').check() |  | ||||||
| 		cy.get('#vocation1').check() |  | ||||||
| 		cy.get('#accept_rules').check() |  | ||||||
|  |  | ||||||
| 		cy.get('#createaccount').submit() |  | ||||||
|  |  | ||||||
| 		// no errors please |  | ||||||
| 		cy.contains('The Following Errors Have Occurred:').should('not.exist') |  | ||||||
|  |  | ||||||
| 		// ss of post page |  | ||||||
| 		cy.screenshot('create-account-page-post') |  | ||||||
| 	}) |  | ||||||
| }) |  | ||||||
| @@ -1,174 +0,0 @@ | |||||||
| describe('Check Public Pages', () => { |  | ||||||
|  |  | ||||||
| 	/// news |  | ||||||
| 	it('Go to news page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/news', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to news archive page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/news/archive', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to changelog page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/change-log', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	/// account management |  | ||||||
| 	it('Go to account manage page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/manage', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to account create page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/create', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to account lost page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/lost', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to rules page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/rules', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	// community |  | ||||||
| 	it('Go to online page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/online', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to characters list page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/characters', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to guilds page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/guilds', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to highscores page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/highscores', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to last kills page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/last-kills', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to houses page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/houses', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to bans page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/bans', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to forum page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/forum', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to team page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/team', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	// library |  | ||||||
| 	it('Go to monsters page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/monsters', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to spells page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/spells', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to server info page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/ots-info', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to commands page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/commands', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to downloads page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/downloads', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to gallery page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/gallery', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to experience table page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/exp-table', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to faq page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/faq', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 	}) |  | ||||||
| }) |  | ||||||
| @@ -1,81 +0,0 @@ | |||||||
| const REQUIRED_LOGIN_MESSAGE = 'Please enter your account name and your password.'; |  | ||||||
| const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.'; |  | ||||||
|  |  | ||||||
| describe('Check Protected Pages', () => { |  | ||||||
|  |  | ||||||
| 	// character actions |  | ||||||
| 	it('Go to account character creation page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/character/create', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(REQUIRED_LOGIN_MESSAGE) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to account character deletion page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/character/delete', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(REQUIRED_LOGIN_MESSAGE) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	// account actions |  | ||||||
| 	it('Go to account email change page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/email', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(REQUIRED_LOGIN_MESSAGE) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to account password change page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/password', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(REQUIRED_LOGIN_MESSAGE) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to account info change page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/info', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(REQUIRED_LOGIN_MESSAGE) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to account logout change page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/account/logout', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(REQUIRED_LOGIN_MESSAGE) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	// guild actions |  | ||||||
| 	it('Go to guild creation page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/?subtopic=guilds&action=create', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(YOU_ARE_NOT_LOGGEDIN) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to guilds cleanup players action page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_players', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(YOU_ARE_NOT_LOGGEDIN) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	it('Go to guilds cleanup guilds action page', () => { |  | ||||||
| 		cy.visit({ |  | ||||||
| 			url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_guilds', |  | ||||||
| 			method: 'GET', |  | ||||||
| 		}) |  | ||||||
| 		cy.contains(YOU_ARE_NOT_LOGGEDIN) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| }) |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| { |  | ||||||
|   "name": "Using fixtures to represent data", |  | ||||||
|   "email": "hello@cypress.io", |  | ||||||
|   "body": "Fixtures are a great way to mock data for responses to routes" |  | ||||||
| } |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| // *********************************************** |  | ||||||
| // This example commands.js shows you how to |  | ||||||
| // create various custom commands and overwrite |  | ||||||
| // existing commands. |  | ||||||
| // |  | ||||||
| // For more comprehensive examples of custom |  | ||||||
| // commands please read more here: |  | ||||||
| // https://on.cypress.io/custom-commands |  | ||||||
| // *********************************************** |  | ||||||
| // |  | ||||||
| // |  | ||||||
| // -- This is a parent command -- |  | ||||||
| // Cypress.Commands.add('login', (email, password) => { ... }) |  | ||||||
| // |  | ||||||
| // |  | ||||||
| // -- This is a child command -- |  | ||||||
| // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) |  | ||||||
| // |  | ||||||
| // |  | ||||||
| // -- This is a dual command -- |  | ||||||
| // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) |  | ||||||
| // |  | ||||||
| // |  | ||||||
| // -- This will overwrite an existing command -- |  | ||||||
| // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| // *********************************************************** |  | ||||||
| // This example support/e2e.js is processed and |  | ||||||
| // loaded automatically before your test files. |  | ||||||
| // |  | ||||||
| // This is a great place to put global configuration and |  | ||||||
| // behavior that modifies Cypress. |  | ||||||
| // |  | ||||||
| // You can change the location of this file or turn off |  | ||||||
| // automatically serving support files with the |  | ||||||
| // 'supportFile' configuration option. |  | ||||||
| // |  | ||||||
| // You can read more here: |  | ||||||
| // https://on.cypress.io/configuration |  | ||||||
| // *********************************************************** |  | ||||||
|  |  | ||||||
| // Import commands.js using ES2015 syntax: |  | ||||||
| import './commands' |  | ||||||
|  |  | ||||||
| // Alternatively you can use CommonJS syntax: |  | ||||||
| // require('./commands') |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								images/del.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 433 B | 
							
								
								
									
										
											BIN
										
									
								
								images/druid.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 38 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/edit.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 450 B | 
							
								
								
									
										
											BIN
										
									
								
								images/error.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 592 B After Width: | Height: | Size: 706 B | 
							
								
								
									
										
											BIN
										
									
								
								images/false.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 1004 B | 
							
								
								
									
										
											BIN
										
									
								
								images/hist.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 110 B After Width: | Height: | Size: 117 B | 
							
								
								
									
										
											BIN
										
									
								
								images/info.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 631 B After Width: | Height: | Size: 783 B | 
| Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 38 KiB | 
| Before Width: | Height: | Size: 1005 B After Width: | Height: | Size: 30 KiB | 
| Before Width: | Height: | Size: 735 B After Width: | Height: | Size: 789 B | 
| Before Width: | Height: | Size: 56 B | 
| Before Width: | Height: | Size: 56 B | 
| Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 33 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/plus.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 9.1 KiB | 
| Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 615 B | 
| Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 34 KiB | 
| Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 816 B | 
							
								
								
									
										
											BIN
										
									
								
								images/trash.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 476 B | 
							
								
								
									
										
											BIN
										
									
								
								images/true.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 709 B After Width: | Height: | Size: 809 B | 
							
								
								
									
										361
									
								
								index.php
									
									
									
									
									
								
							
							
						
						| @@ -24,29 +24,23 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\UsageStatistics; | ob_start(); | ||||||
| use MyAAC\Visitors; |  | ||||||
|  |  | ||||||
| require_once 'common.php'; | require_once 'common.php'; | ||||||
| require_once SYSTEM . 'functions.php'; | require_once SYSTEM . 'functions.php'; | ||||||
|  |  | ||||||
| $uri = $_SERVER['REQUEST_URI']; | $uri = $_SERVER['REQUEST_URI']; | ||||||
| if(str_contains($uri, 'index.php')) { |  | ||||||
| 	$uri = str_replace_first('/index.php', '', $uri); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(str_starts_with($uri, '/')) { | $tmp = BASE_DIR; | ||||||
|  | if(!empty($tmp)) | ||||||
|  | 	$uri = str_replace(BASE_DIR . '/', '', $uri); | ||||||
|  | else | ||||||
| 	$uri = str_replace_first('/', '', $uri); | 	$uri = str_replace_first('/', '', $uri); | ||||||
| } |  | ||||||
|  |  | ||||||
| if(preg_match("/^[A-Za-z0-9-_%'+\/]+\.png$/i", $uri)) { | $uri = str_replace(array('index.php/', '?'), '', $uri); | ||||||
| 	if (!empty(BASE_DIR)) { | define('URI', $uri); | ||||||
| 		$tmp = explode('.', str_replace_first(str_replace_first('/', '', BASE_DIR) . '/', '', $uri)); |  | ||||||
| 	} | if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { | ||||||
| 	else { |  | ||||||
| 	$tmp = explode('.', $uri); | 	$tmp = explode('.', $uri); | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$_REQUEST['name'] = urldecode($tmp[0]); | 	$_REQUEST['name'] = urldecode($tmp[0]); | ||||||
|  |  | ||||||
| 	chdir(TOOLS . 'signature'); | 	chdir(TOOLS . 'signature'); | ||||||
| @@ -54,83 +48,164 @@ if(preg_match("/^[A-Za-z0-9-_%'+\/]+\.png$/i", $uri)) { | |||||||
| 	exit(); | 	exit(); | ||||||
| } | } | ||||||
|  |  | ||||||
| if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { | if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { | ||||||
| 	http_response_code(404); | 	http_response_code(404); | ||||||
| 	exit; | 	exit; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | if(file_exists(BASE . 'config.local.php')) { | ||||||
|  | 	require_once BASE . 'config.local.php'; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ini_set('log_errors', 1); | ||||||
|  | if(config('env') === 'dev') { | ||||||
|  | 	ini_set('display_errors', 1); | ||||||
|  | 	ini_set('display_startup_errors', 1); | ||||||
|  | 	error_reporting(E_ALL); | ||||||
|  | } | ||||||
|  | else { | ||||||
|  | 	ini_set('display_errors', 0); | ||||||
|  | 	ini_set('display_startup_errors', 0); | ||||||
|  | 	error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); | ||||||
|  | } | ||||||
|  |  | ||||||
| if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install')) | if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install')) | ||||||
| { | { | ||||||
| 	header('Location: ' . BASE_URL . 'install/'); | 	header('Location: ' . BASE_URL . 'install/'); | ||||||
| 	exit(); | 	throw new RuntimeException('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!'); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | require_once SYSTEM . 'init.php'; | ||||||
|  | require_once SYSTEM . 'template.php'; | ||||||
|  |  | ||||||
|  | // verify myaac tables exists in database | ||||||
|  | if(!$db->hasTable('myaac_account_actions')) { | ||||||
|  | 	throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $found = false; | ||||||
|  | if(empty($uri) || isset($_REQUEST['template'])) { | ||||||
|  | 	$_REQUEST['p'] = 'news'; | ||||||
|  | 	$found = true; | ||||||
|  | } | ||||||
|  | else { | ||||||
|  | 	$tmp = strtolower($uri); | ||||||
|  | 	if (!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(TEMPLATES . $template_name . '/pages/' . $tmp . '.php')) { | ||||||
|  | 		$_REQUEST['p'] = $uri; | ||||||
|  | 		$found = true; | ||||||
|  | 	} | ||||||
|  | 	else if (!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) { | ||||||
|  | 		$_REQUEST['p'] = $uri; | ||||||
|  | 		$found = true; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		$rules = array( | ||||||
|  | 			'/^account\/manage\/?$/' => array('subtopic' => 'accountmanagement'), | ||||||
|  | 			'/^account\/create\/?$/' => array('subtopic' => 'createaccount'), | ||||||
|  | 			'/^account\/lost\/?$/' => array('subtopic' => 'lostaccount'), | ||||||
|  | 			'/^account\/logout\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'logout'), | ||||||
|  | 			'/^account\/password\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_password'), | ||||||
|  | 			'/^account\/register\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register'), | ||||||
|  | 			'/^account\/register\/new\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register_new'), | ||||||
|  | 			'/^account\/email\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_email'), | ||||||
|  | 			'/^account\/info\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_info'), | ||||||
|  | 			'/^account\/character\/create\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'create_character'), | ||||||
|  | 			'/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'), | ||||||
|  | 			'/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'), | ||||||
|  | 			'/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'), | ||||||
|  | 			'/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'), | ||||||
|  | 			'/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'), | ||||||
|  | 			'/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'), | ||||||
|  | 			'/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'), | ||||||
|  | 			'/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'), | ||||||
|  | 			'/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'), | ||||||
|  | 			'/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'), | ||||||
|  | 			'/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'), | ||||||
|  | 			'/^faq\/edit\/?$/' => array('subtopic' => 'faq', 'action' => 'edit'), | ||||||
|  | 			'/^forum\/add_board\/?$/' => array('subtopic' => 'forum', 'action' => 'add_board'),# | ||||||
|  | 			'/^forum\/edit_board\/?$/' => array('subtopic' => 'forum', 'action' => 'edit_board'), | ||||||
|  | 			'/^forum\/board\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2'), | ||||||
|  | 			'/^forum\/board\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2', 'page' => '$3'), | ||||||
|  | 			'/^forum\/thread\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2'), | ||||||
|  | 			'/^forum\/thread\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2', 'page' => '$3'), | ||||||
|  | 			'/^gallery\/add\/?$/' => array('subtopic' => 'gallery', 'action' => 'add'), | ||||||
|  | 			'/^gallery\/edit\/?$/' => array('subtopic' => 'gallery', 'action' => 'edit'), | ||||||
|  | 			'/^gallery\/[0-9]+\/?$/' => array('subtopic' => 'gallery', 'image' => '$1'), | ||||||
|  | 			'/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), | ||||||
|  | 			'/^guilds\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'guilds', 'action' => 'show', 'guild' => '$1'), | ||||||
|  | 			'/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2', 'page' => '$3'), | ||||||
|  | 			'/^highscores\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'page' => '$2'), | ||||||
|  | 			'/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2'), | ||||||
|  | 			'/^highscores\/[A-Za-z0-9-_\']+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1'), | ||||||
|  | 			'/^news\/add\/?$/' => array('subtopic' => 'news', 'action' => 'add'), | ||||||
|  | 			'/^news\/edit\/?$/' => array('subtopic' => 'news', 'action' => 'edit'), | ||||||
|  | 			'/^news\/archive\/?$/' => array('subtopic' => 'newsarchive'), | ||||||
|  | 			'/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'), | ||||||
|  | 			'/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), | ||||||
|  | 			'/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'), | ||||||
|  | 			'/^houses\/view\/?$/' => array('subtopic' => 'houses', 'page' => 'view') | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 		foreach ($rules as $rule => $redirect) { | ||||||
|  | 			if (preg_match($rule, $uri)) { | ||||||
|  | 				$tmp = explode('/', $uri); | ||||||
|  | 				/* @var $redirect array */ | ||||||
|  | 				foreach ($redirect as $key => $value) { | ||||||
|  |  | ||||||
|  | 					if (strpos($value, '$') !== false) { | ||||||
|  | 						$value = str_replace('$' . $value[1], $tmp[$value[1]], $value); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					$_REQUEST[$key] = $value; | ||||||
|  | 					$_GET[$key] = $value; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				$found = true; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // handle ?fbclid=x, etc. (show news page) | ||||||
|  | if (!$found && count($_GET) > 0 && !isset($_REQUEST['subtopic']) && !isset($_REQUEST['p']) && !in_array($_SERVER['QUERY_STRING'], getDatabasePages())) { | ||||||
|  | 	$_REQUEST['p'] = $_REQUEST['subtopic'] = 'news'; | ||||||
|  | 	$found = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // define page visited, so it can be used within events system | ||||||
|  | $page = isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : (isset($_REQUEST['p']) ? $_REQUEST['p'] : ''); | ||||||
|  | if(empty($page) || !preg_match('/^[A-z0-9\_\-]+$/', $page)) { | ||||||
|  | 	$tmp = URI; | ||||||
|  | 	if(!empty($tmp)) { | ||||||
|  | 		$page = $tmp; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		if(!$found) | ||||||
|  | 			$page = '404'; | ||||||
|  | 		else | ||||||
|  | 			$page = 'news'; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $page = strtolower($page); | ||||||
|  | define('PAGE', $page); | ||||||
|  |  | ||||||
| $template_place_holders = array(); | $template_place_holders = array(); | ||||||
|  |  | ||||||
| require_once SYSTEM . 'init.php'; |  | ||||||
|  |  | ||||||
| require_once SYSTEM . 'template.php'; |  | ||||||
| require_once SYSTEM . 'login.php'; | require_once SYSTEM . 'login.php'; | ||||||
| require_once SYSTEM . 'status.php'; | require_once SYSTEM . 'status.php'; | ||||||
|  |  | ||||||
| $twig->addGlobal('config', $config); | $twig->addGlobal('config', $config); | ||||||
| $twig->addGlobal('status', $status); | $twig->addGlobal('status', $status); | ||||||
|  |  | ||||||
|  | require SYSTEM . 'migrate.php'; | ||||||
|  |  | ||||||
| $hooks->trigger(HOOK_STARTUP); | $hooks->trigger(HOOK_STARTUP); | ||||||
|  |  | ||||||
| // backward support for gesior |  | ||||||
| if(setting('core.backward_support')) { |  | ||||||
| 	define('INITIALIZED', true); |  | ||||||
| 	$SQL = $db; |  | ||||||
| 	$layout_header = template_header(); |  | ||||||
| 	$layout_name = $template_path; |  | ||||||
| 	$news_content = ''; |  | ||||||
| 	$tickers_content = ''; |  | ||||||
| 	$main_content = ''; |  | ||||||
|  |  | ||||||
| 	$config['access_admin_panel'] = 2; |  | ||||||
| 	$group_id_of_acc_logged = 0; |  | ||||||
| 	if($logged && $account_logged) |  | ||||||
| 		$group_id_of_acc_logged = $account_logged->getGroupId(); |  | ||||||
|  |  | ||||||
| 	$config['serverPath'] = $config['server_path']; |  | ||||||
| 	$config['site'] = &$config; |  | ||||||
| 	$config['server'] = &$config['lua']; |  | ||||||
| 	$config['site']['shop_system'] = setting('core.gifts_system'); |  | ||||||
| 	$config['site']['gallery_page'] = true; |  | ||||||
|  |  | ||||||
| 	if(!isset($config['vdarkborder'])) |  | ||||||
| 		$config['vdarkborder'] = '#505050'; |  | ||||||
| 	if(!isset($config['darkborder'])) |  | ||||||
| 		$config['darkborder'] = '#D4C0A1'; |  | ||||||
| 	if(!isset($config['lightborder'])) |  | ||||||
| 		$config['lightborder'] = '#F1E0C6'; |  | ||||||
|  |  | ||||||
| 	$config['site']['download_page'] = true; |  | ||||||
| 	$config['site']['serverinfo_page'] = true; |  | ||||||
| 	$config['site']['screenshot_page'] = true; |  | ||||||
|  |  | ||||||
| 	$forumSetting = setting('core.forum'); |  | ||||||
| 	if($forumSetting != '') |  | ||||||
| 		$config['forum_link'] = (strtolower($forumSetting) === 'site' ? getLink('forum') : $forumSetting); |  | ||||||
|  |  | ||||||
| 	foreach($status as $key => $value) |  | ||||||
| 		$config['status']['serverStatus_' . $key] = $value; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(setting('core.views_counter')) { |  | ||||||
| 	require_once SYSTEM . 'counter.php'; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(setting('core.visitors_counter')) { |  | ||||||
| 	$visitors = new Visitors(setting('core.visitors_counter_ttl')); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| require_once SYSTEM . 'router.php'; |  | ||||||
|  |  | ||||||
| // anonymous usage statistics | // anonymous usage statistics | ||||||
| // sent only when user agrees | // sent only when user agrees | ||||||
| if(setting('core.anonymous_usage_statistics')) { | if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) { | ||||||
| 	$report_time = 30 * 24 * 60 * 60; // report one time per 30 days | 	$report_time = 30 * 24 * 60 * 60; // report one time per 30 days | ||||||
| 	$should_report = true; | 	$should_report = true; | ||||||
|  |  | ||||||
| @@ -153,7 +228,8 @@ if(setting('core.anonymous_usage_statistics')) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if($should_report) { | 	if($should_report) { | ||||||
| 		UsageStatistics::report(); | 		require_once LIBS . 'usage_statistics.php'; | ||||||
|  | 		Usage_Statistics::report(); | ||||||
|  |  | ||||||
| 		updateDatabaseConfig('last_usage_report', time()); | 		updateDatabaseConfig('last_usage_report', time()); | ||||||
| 		if($cache->enabled()) { | 		if($cache->enabled()) { | ||||||
| @@ -162,7 +238,146 @@ if(setting('core.anonymous_usage_statistics')) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| $title_full =  (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName']; | if($config['views_counter']) | ||||||
|  | 	require_once SYSTEM . 'counter.php'; | ||||||
|  |  | ||||||
|  | if($config['visitors_counter']) | ||||||
|  | { | ||||||
|  | 	require_once SYSTEM . 'libs/visitors.php'; | ||||||
|  | 	$visitors = new Visitors($config['visitors_counter_ttl']); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // page content loading | ||||||
|  | if(!isset($content[0])) | ||||||
|  | 	$content = ''; | ||||||
|  | $load_it = true; | ||||||
|  |  | ||||||
|  | // check if site has been closed | ||||||
|  | $site_closed = false; | ||||||
|  | if(fetchDatabaseConfig('site_closed', $site_closed)) { | ||||||
|  | 	$site_closed = ($site_closed == 1); | ||||||
|  | 	if($site_closed) { | ||||||
|  | 		if(!admin()) | ||||||
|  | 		{ | ||||||
|  | 			$title = getDatabaseConfig('site_closed_title'); | ||||||
|  | 			$content .= '<p class="note">' . getDatabaseConfig('site_closed_message') . '</p><br/>'; | ||||||
|  | 			$load_it = false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if(!$logged) | ||||||
|  | 		{ | ||||||
|  | 			ob_start(); | ||||||
|  | 			require SYSTEM . 'pages/accountmanagement.php'; | ||||||
|  | 			$content .= ob_get_contents(); | ||||||
|  | 			ob_end_clean(); | ||||||
|  | 			$load_it = false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | define('SITE_CLOSED', $site_closed); | ||||||
|  |  | ||||||
|  | // backward support for gesior | ||||||
|  | if($config['backward_support']) { | ||||||
|  | 	define('INITIALIZED', true); | ||||||
|  | 	$SQL = $db; | ||||||
|  | 	$layout_header = template_header(); | ||||||
|  | 	$layout_name = $template_path; | ||||||
|  | 	$news_content = ''; | ||||||
|  | 	$tickers_content = ''; | ||||||
|  | 	$subtopic = PAGE; | ||||||
|  | 	$main_content = ''; | ||||||
|  |  | ||||||
|  | 	$config['access_admin_panel'] = 2; | ||||||
|  | 	$group_id_of_acc_logged = 0; | ||||||
|  | 	if($logged && $account_logged) | ||||||
|  | 		$group_id_of_acc_logged = $account_logged->getGroupId(); | ||||||
|  |  | ||||||
|  | 	$config['site'] = &$config; | ||||||
|  | 	$config['server'] = &$config['lua']; | ||||||
|  | 	$config['site']['shop_system'] = $config['gifts_system']; | ||||||
|  | 	$config['site']['gallery_page'] = true; | ||||||
|  |  | ||||||
|  | 	if(!isset($config['vdarkborder'])) | ||||||
|  | 		$config['vdarkborder'] = '#505050'; | ||||||
|  | 	if(!isset($config['darkborder'])) | ||||||
|  | 		$config['darkborder'] = '#D4C0A1'; | ||||||
|  | 	if(!isset($config['lightborder'])) | ||||||
|  | 		$config['lightborder'] = '#F1E0C6'; | ||||||
|  |  | ||||||
|  | 	$config['site']['download_page'] = true; | ||||||
|  | 	$config['site']['serverinfo_page'] = true; | ||||||
|  | 	$config['site']['screenshot_page'] = true; | ||||||
|  |  | ||||||
|  | 	if($config['forum'] != '') | ||||||
|  | 		$config['forum_link'] = (strtolower($config['forum']) === 'site' ? getLink('forum') : $config['forum']); | ||||||
|  |  | ||||||
|  | 	foreach($status as $key => $value) | ||||||
|  | 		$config['status']['serverStatus_' . $key] = $value; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if($load_it) | ||||||
|  | { | ||||||
|  | 	if(SITE_CLOSED && admin()) | ||||||
|  | 		$content .= '<p class="note">Site is under maintenance (closed mode). Only privileged users can see it.</p>'; | ||||||
|  |  | ||||||
|  | 	if($config['backward_support']) { | ||||||
|  | 		require SYSTEM . 'compat/pages.php'; | ||||||
|  | 		require SYSTEM . 'compat/classes.php'; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$ignore = false; | ||||||
|  |  | ||||||
|  | 	$logged_access = 1; | ||||||
|  | 	if($logged && $account_logged && $account_logged->isLoaded()) { | ||||||
|  | 		$logged_access = $account_logged->getAccess(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$success = false; | ||||||
|  | 	$tmp_content = getCustomPage($page, $success); | ||||||
|  | 	if($success && $hooks->trigger(HOOK_BEFORE_PAGE_CUSTOM)) { | ||||||
|  | 		$content .= $tmp_content; | ||||||
|  | 		if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { | ||||||
|  | 			$pageInfo = getCustomPageInfo($page); | ||||||
|  | 			$content = $twig->render('admin.pages.links.html.twig', array( | ||||||
|  | 					'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') | ||||||
|  | 				)) . $content; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		$hooks->trigger(HOOK_AFTER_PAGE_CUSTOM); | ||||||
|  | 	} else { | ||||||
|  | 		$file = TEMPLATES . "$template_name/pages/$page.php"; | ||||||
|  | 		if(!@file_exists($file) || preg_match('/[^A-z0-9_\-]/', $page)) { | ||||||
|  | 			$file = SYSTEM . "pages/$page.php"; | ||||||
|  | 			if(!@file_exists($file) || preg_match('/[^A-z0-9_\-]/', $page)) { | ||||||
|  | 				$page = '404'; | ||||||
|  | 				$file = SYSTEM . 'pages/404.php'; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ob_start(); | ||||||
|  | 	if($hooks->trigger(HOOK_BEFORE_PAGE)) { | ||||||
|  | 		if(!$ignore) | ||||||
|  | 			require $file; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if($config['backward_support'] && isset($main_content[0])) | ||||||
|  | 		$content .= $main_content; | ||||||
|  |  | ||||||
|  | 	$content .= ob_get_contents(); | ||||||
|  | 	ob_end_clean(); | ||||||
|  | 	$hooks->trigger(HOOK_AFTER_PAGE); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if($config['backward_support']) { | ||||||
|  | 	$main_content = $content; | ||||||
|  | 	if(!isset($title)) | ||||||
|  | 		$title = ucfirst($page); | ||||||
|  |  | ||||||
|  | 	$topic = $title; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $title_full =  (isset($title) ? $title . $config['title_separator'] : '') . $config['lua']['serverName']; | ||||||
| require $template_path . '/' . $template_index; | require $template_path . '/' . $template_index; | ||||||
|  |  | ||||||
| echo base64_decode('PCEtLSBQb3dlcmVkIGJ5IE15QUFDIDo6IGh0dHBzOi8vd3d3Lm15LWFhYy5vcmcvIC0tPg==') . PHP_EOL; | echo base64_decode('PCEtLSBQb3dlcmVkIGJ5IE15QUFDIDo6IGh0dHBzOi8vd3d3Lm15LWFhYy5vcmcvIC0tPg==') . PHP_EOL; | ||||||
|   | |||||||
| @@ -26,9 +26,6 @@ if(!isset($error) || !$error) { | |||||||
| 		$config['database_type'] = $config['lua']['database_type']; | 		$config['database_type'] = $config['lua']['database_type']; | ||||||
| 	else if(isset($config['lua']['sql_type'])) // otserv | 	else if(isset($config['lua']['sql_type'])) // otserv | ||||||
| 		$config['database_type'] = $config['lua']['sql_type']; | 		$config['database_type'] = $config['lua']['sql_type']; | ||||||
| 	else { |  | ||||||
| 		$config['database_type'] = ''; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$config['database_type'] = strtolower($config['database_type']); | 	$config['database_type'] = strtolower($config['database_type']); | ||||||
| 	if(empty($config['database_type'])) { | 	if(empty($config['database_type'])) { | ||||||
|   | |||||||
| @@ -6,18 +6,12 @@ $ots = POT::getInstance(); | |||||||
| require SYSTEM . 'database.php'; | require SYSTEM . 'database.php'; | ||||||
|  |  | ||||||
| if(!isset($db)) { | if(!isset($db)) { | ||||||
| 	$database_error = '<p class="lead">' . $locale['step_database_error_mysql_connect'] . '</p>'; | 	$database_error = $locale['step_database_error_mysql_connect'] . '<br/>' . | ||||||
| 	 | 			$locale['step_database_error_mysql_connect_2'] . | ||||||
| 	$database_error .= '<p>' . $locale['step_database_error_mysql_connect_2'] . '</p>'; | 			'<ul>' . | ||||||
|  | 				'<li>' . $locale['step_database_error_mysql_connect_3'] . '</li>' . | ||||||
| 	$database_error .= '<ul class="list-group">' . | 				'<li>' . $locale['step_database_error_mysql_connect_4'] . '</li>' . | ||||||
| 							'<li class="list-group-item list-group-item-warning">' . $locale['step_database_error_mysql_connect_3'] . '</li>' . | 			'</ul>' . '<br/>' . $error; | ||||||
| 							'<li class="list-group-item list-group-item-warning">' . $locale['step_database_error_mysql_connect_4'] . '</li>' . |  | ||||||
| 						'</ul>'; |  | ||||||
|  |  | ||||||
| 	$database_error .= '<div class="alert alert-danger mt-4"> |  | ||||||
| 							<span>' . $error . '</span> |  | ||||||
| 						</div>'; |  | ||||||
| } | } | ||||||
| else { | else { | ||||||
| 	if($db->hasTable('accounts')) | 	if($db->hasTable('accounts')) | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ function query($query) | |||||||
|  |  | ||||||
| // define php version id if its not already | // define php version id if its not already | ||||||
| if(!defined('PHP_VERSION_ID')) { | if(!defined('PHP_VERSION_ID')) { | ||||||
| 	$version = array_map('intval', explode('.', PHP_VERSION)); | 	$version = explode('.', PHP_VERSION); | ||||||
|  |  | ||||||
| 	define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); | 	define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); | ||||||
| } | } | ||||||
| @@ -62,9 +62,9 @@ function next_buttons($previous = true, $next = true) | |||||||
| 		$ret .= '<input class="button" type="submit" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\';" value="' . $locale['next'] . '" />'; | 		$ret .= '<input class="button" type="submit" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\';" value="' . $locale['next'] . '" />'; | ||||||
| */ | */ | ||||||
| 	if($previous) | 	if($previous) | ||||||
| 		$ret .= '<input type="button" class="button btn btn-primary m-2" onclick="document.getElementById(\'step\').value=\'' . $steps[$i - 1] . '\'; this.form.submit();" value="« ' . $locale['previous'] . '" />'; | 		$ret .= '<input type="button" class="button" onclick="document.getElementById(\'step\').value=\'' . $steps[$i - 1] . '\'; this.form.submit();" value="« ' . $locale['previous'] . '" />'; | ||||||
| 	if($next) | 	if($next) | ||||||
| 		$ret .= '<input type="button" class="button btn btn-primary m-2" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\'; this.form.submit(); " value="' . $locale['next'] . ' »" />'; | 		$ret .= '<input type="button" class="button" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\'; this.form.submit(); " value="' . $locale['next'] . ' »" />'; | ||||||
|  |  | ||||||
| 	$ret .= '</div>'; | 	$ret .= '</div>'; | ||||||
| 	return $ret; | 	return $ret; | ||||||
|   | |||||||