mirror of
https://github.com/ThomasGsp/HyperProxmox.git
synced 2025-03-09 15:40:18 +00:00
modifié : README.md
modifié : code/scripts/main/api/v1/__pycache__/api.cpython-35.pyc modifié : code/scripts/main/core/__pycache__/core.cpython-35.pyc modifié : code/scripts/main/core/libs/__pycache__/hcrypt.cpython-35.pyc modifié : code/scripts/main/core/modules/__pycache__/mod_access.cpython-35.pyc modifié : code/scripts/main/core/modules/__pycache__/mod_analyst.cpython-35.pyc modifié : code/scripts/main/core/modules/__pycache__/mod_database.cpython-35.pyc modifié : code/scripts/main/core/modules/__pycache__/mod_proxmox.cpython-35.pyc modifié : code/scripts/main/core/modules/mod_access.py modifié : code/scripts/main/startup.py supprimé : code/web/backend/.htaccess supprimé : code/web/backend/.scrutinizer.yml supprimé : code/web/backend/.travis.yml supprimé : code/web/backend/CHANGELOG.md supprimé : code/web/backend/README.md supprimé : code/web/backend/_one-click-installation/Vagrantfile supprimé : code/web/backend/_one-click-installation/bootstrap.sh supprimé : code/web/backend/_pictures/huge-logo.png supprimé : code/web/backend/_pictures/support-via-a2hosting.png supprimé : code/web/backend/_pictures/support-via-paypal.png supprimé : code/web/backend/application/_installation/01-create-database.sql supprimé : code/web/backend/application/_installation/02-create-table-users.sql supprimé : code/web/backend/application/_installation/03-create-table-notes.sql supprimé : code/web/backend/application/config/config.development.php supprimé : code/web/backend/application/config/texts.php supprimé : code/web/backend/application/controller/DashboardController.php supprimé : code/web/backend/application/controller/ErrorController.php supprimé : code/web/backend/application/controller/IndexController.php supprimé : code/web/backend/application/controller/LoginController.php supprimé : code/web/backend/application/controller/NoteController.php supprimé : code/web/backend/application/controller/ProfileController.php supprimé : code/web/backend/application/core/Application.php supprimé : code/web/backend/application/core/Auth.php supprimé : code/web/backend/application/core/Config.php supprimé : code/web/backend/application/core/Controller.php supprimé : code/web/backend/application/core/DatabaseFactory.php supprimé : code/web/backend/application/core/Environment.php supprimé : code/web/backend/application/core/Mail.php supprimé : code/web/backend/application/core/Redirect.php supprimé : code/web/backend/application/core/Request.php supprimé : code/web/backend/application/core/Session.php supprimé : code/web/backend/application/core/Text.php supprimé : code/web/backend/application/core/View.php supprimé : code/web/backend/application/model/AvatarModel.php supprimé : code/web/backend/application/model/CaptchaModel.php supprimé : code/web/backend/application/model/LoginModel.php supprimé : code/web/backend/application/model/NoteModel.php supprimé : code/web/backend/application/model/PasswordResetModel.php supprimé : code/web/backend/application/model/RegistrationModel.php supprimé : code/web/backend/application/model/UserModel.php supprimé : code/web/backend/application/model/UserRoleModel.php supprimé : code/web/backend/application/view/_templates/feedback.php supprimé : code/web/backend/application/view/_templates/footer.php supprimé : code/web/backend/application/view/_templates/header.php supprimé : code/web/backend/application/view/dashboard/index.php supprimé : code/web/backend/application/view/error/index.php supprimé : code/web/backend/application/view/index/index.php supprimé : code/web/backend/application/view/login/changePassword.php supprimé : code/web/backend/application/view/login/changeUserRole.php supprimé : code/web/backend/application/view/login/editAvatar.php supprimé : code/web/backend/application/view/login/editUserEmail.php supprimé : code/web/backend/application/view/login/editUsername.php supprimé : code/web/backend/application/view/login/index.php supprimé : code/web/backend/application/view/login/register.php supprimé : code/web/backend/application/view/login/requestPasswordReset.php supprimé : code/web/backend/application/view/login/showProfile.php supprimé : code/web/backend/application/view/login/verify.php supprimé : code/web/backend/application/view/note/edit.php supprimé : code/web/backend/application/view/note/index.php supprimé : code/web/backend/application/view/profile/index.php supprimé : code/web/backend/application/view/profile/showProfile.php supprimé : code/web/backend/composer.json supprimé : code/web/backend/public/.htaccess supprimé : code/web/backend/public/avatars/.htaccess supprimé : code/web/backend/public/avatars/default.jpg supprimé : code/web/backend/public/css/style.css supprimé : code/web/backend/public/index.php supprimé : code/web/backend/tests/core/ConfigTest.php supprimé : code/web/backend/tests/core/EnvironmentTest.php supprimé : code/web/backend/tests/core/RequestTest.php supprimé : code/web/backend/tests/core/TextTest.php supprimé : code/web/backend/tests/phpunit.xml supprimé : code/web/backend/travis-ci-apache supprimé : code/web/frontend/README.md supprimé : doc/Command Process.dia supprimé : system/BASE_SOFT/APACHE/2.2/README.md supprimé : system/BASE_SOFT/APACHE/2.4/.htpasswd supprimé : system/BASE_SOFT/APACHE/2.4/README.md supprimé : system/BASE_SOFT/APACHE/2.4/apache2.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/README.md supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/charset.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/javascript-common.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/localized-error-pages.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/other-vhosts-access-log.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/security.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-available/serve-cgi-bin.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-enabled/README.md supprimé : system/BASE_SOFT/APACHE/2.4/conf-enabled/charset.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-enabled/localized-error-pages.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-enabled/other-vhosts-access-log.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-enabled/security.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf-enabled/serve-cgi-bin.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf.d/README.md supprimé : system/BASE_SOFT/APACHE/2.4/conf.d/awhsecure.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf.d/badbot.conf supprimé : system/BASE_SOFT/APACHE/2.4/conf.d/security.conf supprimé : system/BASE_SOFT/APACHE/2.4/envvars supprimé : system/BASE_SOFT/APACHE/2.4/magic supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/README.md supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/access_compat.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/actions.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/actions.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/alias.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/alias.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/allowmethods.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/asis.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/auth_basic.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/auth_digest.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/auth_form.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authn_anon.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authn_core.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authn_dbd.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authn_dbm.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authn_file.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authn_socache.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authnz_fcgi.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authnz_ldap.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_core.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_dbd.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_dbm.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_groupfile.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_host.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_owner.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/authz_user.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/autoindex.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/autoindex.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/buffer.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cache.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cache_disk.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cache_disk.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cache_socache.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cgi.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cgid.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/cgid.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/charset_lite.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/data.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dav.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dav_fs.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dav_fs.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dav_lock.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dbd.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/deflate.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/deflate.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dialup.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dir.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dir.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/dump_io.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/echo.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/env.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/expires.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ext_filter.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/fastcgi.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/fastcgi.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/file_cache.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/filter.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/headers.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/heartbeat.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/heartmonitor.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ident.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/include.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/info.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/info.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/lbmethod_bybusyness.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/lbmethod_byrequests.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/lbmethod_bytraffic.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/lbmethod_heartbeat.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ldap.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ldap.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/log_debug.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/log_forensic.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/lua.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/macro.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mime.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mime.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mime_magic.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mime_magic.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mpm_event.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mpm_event.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mpm_prefork.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mpm_prefork.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mpm_worker.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/mpm_worker.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/negotiation.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/negotiation.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_ajp.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_balancer.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_balancer.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_connect.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_express.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_fcgi.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_fdpass.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_ftp.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_ftp.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_html.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_html.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_http.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_scgi.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/proxy_wstunnel.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ratelimit.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/reflector.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/remoteip.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/remoteip.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/reqtimeout.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/reqtimeout.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/request.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/rewrite.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/rpaf.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/rpaf.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/sed.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/session.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/session_cookie.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/session_crypto.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/session_dbd.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/setenvif.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/setenvif.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/slotmem_plain.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/slotmem_shm.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/socache_dbm.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/socache_memcache.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/socache_shmcb.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/speling.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ssl.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/ssl.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/status.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/status.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/substitute.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/suexec.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/unique_id.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/userdir.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/userdir.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/usertrack.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/vhost_alias.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/worker.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-available/xml2enc.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/README.md supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/access_compat.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/actions.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/alias.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/alias.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/auth_basic.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/authn_core.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/authn_file.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/authz_core.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/authz_host.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/authz_user.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/autoindex.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/autoindex.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/deflate.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/deflate.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/dir.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/dir.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/env.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/expires.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/fastcgi.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/fastcgi.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/filter.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/headers.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/mime.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/mime.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/mpm_event.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/mpm_event.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/negotiation.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/negotiation.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/remoteip.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/remoteip.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/rewrite.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/rpaf.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/rpaf.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/setenvif.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/setenvif.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/status.conf supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/status.load supprimé : system/BASE_SOFT/APACHE/2.4/mods-enabled/worker.conf supprimé : system/BASE_SOFT/APACHE/2.4/ports.conf supprimé : system/BASE_SOFT/APACHE/2.4/sites-available/000-default.conf supprimé : system/BASE_SOFT/APACHE/2.4/sites-available/010-mywebsite.com.conf supprimé : system/BASE_SOFT/APACHE/2.4/sites-available/README.md supprimé : system/BASE_SOFT/APACHE/2.4/sites-enabled/000-default.conf supprimé : system/BASE_SOFT/APACHE/2.4/sites-enabled/README.md supprimé : system/BASE_SOFT/APACHE/README.md supprimé : system/BASE_SOFT/ES/README.md supprimé : system/BASE_SOFT/FPM/README.md supprimé : system/BASE_SOFT/FPM/conf.d/05-opcache.ini supprimé : system/BASE_SOFT/FPM/conf.d/10-pdo.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-curl.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-gd.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-intl.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-json.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-mcrypt.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-mysql.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-mysqli.ini supprimé : system/BASE_SOFT/FPM/conf.d/20-pdo_mysql.ini supprimé : system/BASE_SOFT/FPM/conf.d/README.md supprimé : system/BASE_SOFT/FPM/php-fpm.conf supprimé : system/BASE_SOFT/FPM/php.ini supprimé : system/BASE_SOFT/FPM/pool.d/README.md supprimé : system/BASE_SOFT/FPM/pool.d/www.conf supprimé : system/BASE_SOFT/HAPROXY/1.7.5/README.md supprimé : system/BASE_SOFT/HAPROXY/1.7.5/haproxy.cfg supprimé : system/BASE_SOFT/HAPROXY/README.md supprimé : system/BASE_SOFT/KEEPALIVED/README.md supprimé : system/BASE_SOFT/KEEPALIVED/keepalived.conf supprimé : system/BASE_SOFT/LETSENCRYPT/README.md supprimé : system/BASE_SOFT/LETSENCRYPT/cron/README.md supprimé : system/BASE_SOFT/LETSENCRYPT/cron/certbot_renew supprimé : system/BASE_SOFT/LETSENCRYPT/scripts/README.md supprimé : system/BASE_SOFT/LETSENCRYPT/scripts/newdomain.sh supprimé : system/BASE_SOFT/LETSENCRYPT/scripts/renew.sh supprimé : system/BASE_SOFT/MEMCACHE/README.md supprimé : system/BASE_SOFT/MONGODB/README.md supprimé : system/BASE_SOFT/MYSQL/README.md supprimé : system/BASE_SOFT/PSQL/README.md supprimé : system/BASE_SOFT/README.md supprimé : system/BASE_SOFT/REDIS/README.md supprimé : system/BASE_SOFT/SYSTEM/FIREWALL/README.md supprimé : system/BASE_SOFT/SYSTEM/FIREWALL/firewall.sh supprimé : system/BASE_SOFT/SYSTEM/NETWORK/README.md supprimé : system/BASE_SOFT/SYSTEM/README.md supprimé : system/BASE_SOFT/SYSTEM/SSH/README.md supprimé : system/BASE_SOFT/SYSTEM/SSH/sshd_config supprimé : system/BASE_SOFT/SYSTEM/SUDO/README.md supprimé : system/BASE_SOFT/SYSTEM/USERS/README.md supprimé : system/BASE_SOFT/VARNISH/4.1/README.md supprimé : system/BASE_SOFT/VARNISH/4.1/conf/README.md supprimé : system/BASE_SOFT/VARNISH/4.1/conf/VMODS/README.md supprimé : system/BASE_SOFT/VARNISH/4.1/conf/VMODS/libvmod_shield.so supprimé : system/BASE_SOFT/VARNISH/4.1/conf/VMODS/libvmod_vsthrottle.so supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/README.md supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/acls.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/backends.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/directors.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/error-404.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/error.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/probes.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/includes/wp-protection.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/conf/production.vcl supprimé : system/BASE_SOFT/VARNISH/4.1/varnish supprimé : system/BASE_SOFT/VARNISH/5.0/README.md supprimé : system/BASE_SOFT/VARNISH/README.md supprimé : system/BASE_SOFT/changes.md supprimé : system/README.md supprimé : system/scripts/README.md supprimé : system/scripts/install_packages.py supprimé : system/scripts/install_packages.pyc supprimé : system/scripts/lamp-debian9/README.md supprimé : system/scripts/lamp-debian9/debian9.ini
This commit is contained in:
parent
f0e67d1aed
commit
7c37b1adaf
358 changed files with 4 additions and 8269 deletions
|
@ -5,8 +5,7 @@
|
|||
* Status: Dev
|
||||
* Object : Massive LXC CT deploy system for proxmox hypervisor.
|
||||
|
||||
|
||||
## Quick start (testings)
|
||||
## Quick start
|
||||
|
||||
### Requirement:
|
||||
* A proxmox server
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -8,7 +8,6 @@ Minimum version require: 3.4
|
|||
import os
|
||||
from Crypto.PublicKey import RSA
|
||||
import hashlib
|
||||
import codecs
|
||||
|
||||
def encodepassphrase(passphrase):
|
||||
return hashlib.sha512(passphrase.encode("UTF-8")).hexdigest()
|
||||
|
@ -97,7 +96,7 @@ class CryticalData:
|
|||
else:
|
||||
result_encrypt = {
|
||||
"result": "OK",
|
||||
"data": codecs.encode(self.public_key.encrypt(mutable_bytes, 32)[0], 'base64')
|
||||
"data": self.public_key.encrypt(data.encode("utf-8"), 64)
|
||||
}
|
||||
except BaseException as e:
|
||||
result_encrypt = {
|
||||
|
|
|
@ -62,12 +62,7 @@ if __name__ == "__main__":
|
|||
exit(1)
|
||||
|
||||
key_pub = CritConf.read_public_key(localconf['system']['key_pub'])
|
||||
"""
|
||||
crypttest=CritConf.data_encryption("ploopp")
|
||||
print(type(crypttest['data']))
|
||||
print(CritConf.data_decryption(crypttest['data']))
|
||||
exit(0)
|
||||
"""
|
||||
|
||||
# URL MAPPING
|
||||
urls = \
|
||||
(
|
||||
|
@ -81,7 +76,7 @@ if __name__ == "__main__":
|
|||
'/api/v1/instance/([0-9]+)/vhost(?:/([0-9]+))', 'vhost',
|
||||
'/api/v1/instance/([0-9]+)/database(?:/([0-9]+))', 'database',
|
||||
|
||||
# MAPPIN NODES
|
||||
# MAPPING NODES
|
||||
'/api/v1/node(?:/([0-9]+))', 'node',
|
||||
|
||||
# MAPPING SERVICES
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
# This file is - if you set up HUGE correctly - not needed.
|
||||
# But, for fallback reasons (if you don't route your vhost to /public), it will stay here.
|
||||
RewriteEngine on
|
||||
RewriteRule ^(.*) public/$1 [L]
|
|
@ -1,5 +0,0 @@
|
|||
# This file just tells the wonderful code quality analyzer Scrutinizer (https://scrutinizer-ci.com/g/panique/huge/)
|
||||
# that we are using external services (Travis) to generate code coverage stats
|
||||
# TODO is this correct ?
|
||||
tools:
|
||||
external_code_coverage: true
|
|
@ -1,30 +0,0 @@
|
|||
language: php
|
||||
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update > /dev/null
|
||||
|
||||
before_script:
|
||||
- sudo apt-get install apache2
|
||||
- sudo a2enmod rewrite
|
||||
# configure apache virtual hosts, create vhost via travis-ci-apache file template
|
||||
- sudo cp -f travis-ci-apache /etc/apache2/sites-available/default
|
||||
- sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
|
||||
- sudo service apache2 restart
|
||||
# composer
|
||||
- composer self-update
|
||||
- composer install --prefer-source --no-interaction --dev
|
||||
# go to tests folder
|
||||
- cd tests
|
||||
|
||||
# run unit tests, create result file
|
||||
script: phpunit --configuration phpunit.xml --coverage-text --coverage-clover=coverage.clover
|
||||
|
||||
# gets tools from Scrutinizer, uploads unit tests results to Scrutinizer (?)
|
||||
after_script:
|
||||
- wget https://scrutinizer-ci.com/ocular.phar
|
||||
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
|
|
@ -1,72 +0,0 @@
|
|||
# CHANGE LOG
|
||||
|
||||
For the newest (und unstable) version always check the develop branch.
|
||||
|
||||
## 3.1
|
||||
|
||||
Code Quality at Scrutinizer 9.7/10, at Code Climate 3.9/4
|
||||
|
||||
**February 2015**
|
||||
|
||||
- [panique] several code quality improvements (and line reductions :) ) all over the project
|
||||
- [PR](https://github.com/panique/huge/pull/620) [owenr88] view rending now possible with multiple view files
|
||||
- [panique] lots of code refactorings and simplifications all over the project
|
||||
- [PR](https://github.com/panique/huge/pull/615) [Dominic28] Avatar can now be deleted by the user
|
||||
- [panique] First Unit tests :)
|
||||
- [panique] several code quality improvements all over the project
|
||||
- [panique] avatarModel code improvements
|
||||
- [panique] renamed AccountType stuff to UserRole, minor changes
|
||||
|
||||
## 3.0
|
||||
|
||||
Code Quality at Scrutinizer 9.3/10, at Code Climate 3.9/4
|
||||
|
||||
**February 2015**
|
||||
|
||||
- [panique] removed duplicate code in AccountTypeModel
|
||||
- [PR](https://github.com/panique/huge/pull/587) [upperwood] Facebook stuff completely removed from SQL
|
||||
- [panique] tiny text changes
|
||||
|
||||
**January 2015**
|
||||
|
||||
- [panique] added static Text class (gets the messages etc)
|
||||
- [panique] added static Environment class (get the environment)
|
||||
- [panique] added static Config class (gets config easily and according to environment)
|
||||
- [panique] new styling of the entire project: login/index has new look now
|
||||
- [panique] massive refactoring of all model classes: lots of methods have been organized into other model classes
|
||||
- [panique] massive refactoring of all model classes: all methods are static now
|
||||
- [panique] EXPERIMENTAL: added static database call / DatabaseFactory, rebuild NoteModel with static methods
|
||||
- [panique] massive refactoring of mail sending, (chose between PHPMailer, SwiftMailer, native / SMTP or no SMTP)
|
||||
|
||||
**December 2014**
|
||||
|
||||
- [panique] lots of refactorings
|
||||
- [panique] refactored LoginModel'S login() method / LoginController's login() method
|
||||
- [panique] removed COOKIE_DOMAIN (cookie is now valid on the domain/IP it has been created on)
|
||||
- [panique] Abstracting super-globals like $_POST['x'] into Request::post('x')
|
||||
- [panique] entirely removed all the Facebook stuff [will be replaced by new proper Oauth2 solution soon]
|
||||
- [panique] lots of code refactorings and cleaning, deletions of duplicate code
|
||||
- [panique] moving nearly all hardcoded values to config
|
||||
- [panique] new View handling: you'll have to pass vars to the view renderer now
|
||||
- [panique] completely removed Facebook login process from controller (incomplete) [will be replaced by new solution]
|
||||
- [panique] less config, URL/IP is auto-detected now
|
||||
- [panique] added loadConfig() to load a specific config according to environment setting (fallback: development)
|
||||
- [panique] added getEnvironment() to fetch (potential) environment setting
|
||||
- [panique] replaced native super-globals access by wrapper access (Session:get instead of $_SESSION)
|
||||
- [panique] complete frontend rebuilding (incomplete yet)
|
||||
- [panique] massive cleaning of all controllers
|
||||
- [panique] added Session::add() to allow stacking of elements (useful for collecting feedback, errors etc)
|
||||
- [panique] complete rebuild of model handling
|
||||
- [panique] View can now render(), renderWithoutHeaderFooter() and renderJSON
|
||||
- [panique] using Composer's PSR-4 autoloader (in a very basic way currently)
|
||||
- [panique] DB construction needs now port by default
|
||||
- [panique] removed (semi-optional) hashing cost factor (as it's redundant usually)
|
||||
- [panique] email max limit increased to 254/255 (official number)
|
||||
- [panique] simpler and improved core
|
||||
- [panique] improved architecture, controllers are now named like "IndexController"
|
||||
- [panique] moved index.php to /public folder, new .htaccess, new installation guideline
|
||||
- [panique] MVC naming fixes
|
||||
- [nerdalertdk] betters paths, automatic paths
|
||||
- [panique] removed legacy PHP stuff: 5.5.x is now the minimum
|
||||
- [PR](https://github.com/panique/php-login/pull/503) [Malkleth] allow users to request password reset by inputting email as well as user names
|
||||
- [PR](https://github.com/panique/php-login/pull/516) [pein0119] cookie runtime calculation fix
|
|
@ -1,353 +0,0 @@
|
|||
[](http://www.php-login.net)
|
||||
|
||||
# HUGE
|
||||
|
||||
[](https://scrutinizer-ci.com/g/panique/huge/?branch=master)
|
||||
[](https://codeclimate.com/github/panique/huge)
|
||||
[](https://travis-ci.org/panique/huge)
|
||||
[](https://www.versioneye.com/user/projects/54ca11fbde7924f81a000010)
|
||||
|
||||
Just a simple user authentication solution inside a super-simple framework skeleton that works out-of-the-box
|
||||
(and comes with an auto-installer), using the future-proof official bcrypt password hashing/salting implementation of
|
||||
PHP 5.5+, plus some nice features that will speed up the time from idea to first usable prototype application
|
||||
dramatically. Nothing more. This project has its focus on hardcore simplicity. Everything is as simple as possible,
|
||||
made for smaller projects, typical agency work and quick pitch drafts. If you want to build massive corporate
|
||||
applications with all the features modern frameworks have, then have a look at [Laravel](http://laravel.com),
|
||||
[Symfony](http://symfony.com) or [Yii](http://www.yiiframework.com), but if you just want to quickly create something
|
||||
that just works, then this script might be interesting for you.
|
||||
|
||||
HUGE's simple-as-possible architecture was inspired by several conference talks, slides and articles about huge
|
||||
applications that - surprisingly and intentionally - go back to the basics of programming, using procedural programming,
|
||||
static classes, extremely simple constructs, not-totally-DRY code etc. while keeping the code extremely readable
|
||||
([StackOverflow](http://www.dev-metal.com/architecture-stackoverflow/), Wikipedia, SoundCloud).
|
||||
|
||||
Buzzwords: [KISS](http://en.wikipedia.org/wiki/KISS_principle), [YASNI](http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it).
|
||||
|
||||
#### Quick-Index
|
||||
|
||||
+ [Features](#features)
|
||||
+ [Live-Demo](#live-demo)
|
||||
+ [Support](#support)
|
||||
+ [Follow the project](#follow)
|
||||
+ [License](#license)
|
||||
+ [Requirements](#requirements)
|
||||
+ [Auto-Installation](#auto-installation)
|
||||
- [Auto-Installation in Vagrant](#auto-installation-vagrant)
|
||||
- [Auto-Installation in Ubuntu 14.04 LTS server](#auto-installation-ubuntu)
|
||||
+ [Installation (Ubuntu 14.04 LTS)](#installation)
|
||||
- [Quick Installation](#quick-installation)
|
||||
- [Detailed Installation](#detailed-installation)
|
||||
+ [Documentation](#documentation)
|
||||
+ [Why is there no support forum anymore ?](#why-no-support-forum)
|
||||
+ [Zero tolerance for idiots, trolls and vandals](#zero-tolerance)
|
||||
+ [Contribute](#contribute)
|
||||
+ [Report a bug](#bug-report)
|
||||
|
||||
### The History of HUGE
|
||||
|
||||
This script was formerly named "php-login" and by far the most popular version of the 4 simple PHP user auth
|
||||
scripts of [The PHP Login Project](http://www.php-login.net) (a collection of simple login scripts, made to prevent
|
||||
people from using totally outdated and insecure MD5 password hashing, which was still very popular in the PHP world
|
||||
back in 2012).
|
||||
|
||||
Why the name "HUGE" ? It's a nice combination to
|
||||
[TINY](https://github.com/panique/tiny),
|
||||
[MINI](https://github.com/panique/mini) and
|
||||
[MINI2](https://github.com/panique/mini2), my other projects :)
|
||||
|
||||
### Features <a name="features"></a>
|
||||
* built with the official PHP password hashing functions, fitting the most modern password hashing/salting web standards
|
||||
* users can register, login, logout (with username, email, password)
|
||||
* [planned: OAuth2 implementation for proper future-proof 3rd party auth]
|
||||
* password-forget / reset
|
||||
* remember-me (login via cookie)
|
||||
* account verification via mail
|
||||
* captcha
|
||||
* failed-login-throttling
|
||||
* user profiles
|
||||
* account upgrade / downgrade
|
||||
* supports local avatars and remote Gravatars
|
||||
* supports native mail and SMTP sending (via PHPMailer and other tools)
|
||||
* uses PDO for database access for sure, has nice DatabaseFactory (in case your project goes big)
|
||||
* uses URL rewriting ("beautiful URLs")
|
||||
* proper split of application and public files (requests only go into /public)
|
||||
* uses Composer to load external dependencies (PHPMailer, Captcha-Generator, etc.)
|
||||
* fits PSR-0/1/2/4 coding guidelines
|
||||
* masses of comments
|
||||
* is actively developed, maintained and bug-fixed
|
||||
|
||||
### Live-Demo <a name="live-demo"></a>
|
||||
|
||||
See a [live demo here](http://demo-huge.php-login.net) and [the server's phpinfo() here](http://demo-huge.php-login.net/info.php).
|
||||
|
||||
### Support the project <a name="support"></a>
|
||||
|
||||
There a lot of work behind this project. I might save you hundreds, maybe thousands of hours of work (calculate that
|
||||
in developer costs). So when you are earning money by using HUGE, be fair and give something back to open-source.
|
||||
HUGE is totally free to private and commercial use.
|
||||
|
||||
TODO new banners
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=P5YLUK4MW3LDG)
|
||||
[](https://affiliates.a2hosting.com/idevaffiliate.php?id=4471&url=579)
|
||||
|
||||
You can also rent your next $5 server at [Virpus](http://my.virpus.com/aff.php?aff=1836) or [DigitalOcean](https://www.digitalocean.com/?refcode=40d978532a20)
|
||||
or donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=P5YLUK4MW3LDG).
|
||||
|
||||
Also feel free to contribute to this project.
|
||||
|
||||
### Follow the project <a name="follow"></a>
|
||||
|
||||
Here on **[Twitter](https://twitter.com/simplephplogin)** or **[Facebook](https://www.facebook.com/pages/PHP-Login-Script/461306677235868)**.
|
||||
I'm also blogging at **[Dev Metal](http://www.dev-metal.com)**.
|
||||
|
||||
### License <a name="license"></a>
|
||||
|
||||
Licensed under [MIT](http://www.opensource.org/licenses/mit-license.php).
|
||||
Totally free for private or commercial projects.
|
||||
|
||||
### Requirements <a name="requirements"></a>
|
||||
|
||||
Make sure you know the basics of object-oriented programming and MVC, are able to use the command line and have
|
||||
used Composer before. This script is not for beginners.
|
||||
|
||||
* **PHP 5.5+**
|
||||
* **MySQL 5** database (better use versions 5.5+ as very old versions have a [PDO injection bug](http://stackoverflow.com/q/134099/1114320)
|
||||
* installed PHP extensions: pdo, gd, openssl (the install guideline shows how to do)
|
||||
* installed tools on your server: git, curl, composer (the install guideline shows how to do)
|
||||
* for professional mail sending: an SMTP account (I use [SMTP2GO](http://www.smtp2go.com/?s=devmetal))
|
||||
* activated mod_rewrite on your server (the install guideline shows how to do)
|
||||
|
||||
### Auto-Installations <a name="auto-installation"></a>
|
||||
|
||||
Yo, fully automatic. Why ? Because I always hated it to spend days trying to find out how to install a thing.
|
||||
This will save you masses of time and nerves. Donate a coffee if you like it.
|
||||
|
||||
#### Auto-Installation (in Vagrant) <a name="auto-installation-vagrant"></a>
|
||||
|
||||
If you are using Vagrant for your development, then simply
|
||||
|
||||
1. Add the official Ubuntu 14.04 LTS box to your Vagrant: `vagrant box add ubuntu/trusty64`
|
||||
2. Move *Vagrantfile* and *bootstrap.sh* (from *_one-click-installation* folder) to a folder where you want to initialize your project.
|
||||
3. Do `vagrant up` in that folder.
|
||||
|
||||
5 minutes later you'll have a fully installed HUGE inside Ubuntu 14.04 LTS. The full code will be auto-synced with
|
||||
the current folder. MySQL root password and the PHPMyAdmin root password are set to *12345678*. By default
|
||||
192.168.33.111 is the IP of your new box.
|
||||
|
||||
#### Auto-Installation in a naked Ubuntu 14.04 LTS server <a name="auto-installation-ubuntu"></a>
|
||||
|
||||
Extremely simple installation in a fresh and naked typical Ubuntu 14.04 LTS server:
|
||||
|
||||
Download the installer script
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/panique/huge/master/_one-click-installation/bootstrap.sh
|
||||
```
|
||||
|
||||
Make it executable
|
||||
```bash
|
||||
chmod +x bootstrap.sh
|
||||
```
|
||||
|
||||
Run it! Give it some minutes to perform all the tasks. And yes, you can thank me later :)
|
||||
```bash
|
||||
sudo ./bootstrap.sh
|
||||
```
|
||||
### Installation <a name="installation"></a>
|
||||
|
||||
This script is very fresh, so the install guidelines are not perfect yet.
|
||||
|
||||
#### Quick guide: <a name="quick-installation"></a>
|
||||
|
||||
0. Make sure you have Apache, PHP, MySQL installed. [Tutorial](http://www.dev-metal.com/installsetup-basic-lamp-stack-linux-apache-mysql-php-ubuntu-14-04-lts/).
|
||||
1. Clone the repo to a folder on your server
|
||||
2. Activate mod_rewrite, route all traffic to application's /public folder. [Tutorial](http://www.dev-metal.com/enable-mod_rewrite-ubuntu-14-04-lts/).
|
||||
3. Edit application/config: Set your database credentials
|
||||
4. Execute SQL statements from application/_installation to setup database tables
|
||||
5. [Install Composer](http://www.dev-metal.com/install-update-composer-windows-7-ubuntu-debian-centos/),
|
||||
run `Composer install` on application's root folder to install dependencies
|
||||
6. Make avatar folder (application/public/avatars) writable
|
||||
7. For proper email usage: Set SMTP credentials in config file, set EMAIL_USE_SMTP to true
|
||||
|
||||
"Email does not work" ? See the troubleshooting below. TODO
|
||||
|
||||
#### Detailed guide (Ubuntu 14.04 LTS): <a name="detailed-installation"></a>
|
||||
|
||||
This is just a quick guideline for easy setup of a development environment!
|
||||
|
||||
Make sure you have Apache, PHP 5.5+ and MySQL installed. [Tutorial here](http://www.dev-metal.com/installsetup-basic-lamp-stack-linux-apache-mysql-php-ubuntu-14-04-lts/).
|
||||
Nginx will work for sure too, but no install guidelines are available yet.
|
||||
|
||||
Edit vhost to make clean URLs possible and route all traffic to /public folder of your project:
|
||||
```bash
|
||||
sudo nano /etc/apache2/sites-available/000-default.conf
|
||||
```
|
||||
|
||||
and make the file look like
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot "/var/www/html/public"
|
||||
<Directory "/var/www/html/public">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
Enable mod_rewrite and restart apache.
|
||||
```bash
|
||||
sudo a2enmod rewrite
|
||||
service apache2 restart
|
||||
```
|
||||
|
||||
Install curl (needed to use git), openssl (needed to clone from GitHub, as github is https only),
|
||||
PHP GD, the graphic lib (we create captchas and avatars), and git.
|
||||
```bash
|
||||
sudo apt-get -y install curl
|
||||
sudo apt-get -y install php5-curl
|
||||
sudo apt-get -y install openssl
|
||||
sudo apt-get -y install php5-gd
|
||||
sudo apt-get -y install git
|
||||
```
|
||||
|
||||
git clone HUGE
|
||||
```bash
|
||||
sudo git clone https://github.com/panique/huge "/var/www/html"
|
||||
```
|
||||
|
||||
Install Composer
|
||||
```bash
|
||||
curl -s https://getcomposer.org/installer | php
|
||||
mv composer.phar /usr/local/bin/composer
|
||||
```
|
||||
|
||||
Go to project folder, load Composer packages (--dev is optional, you know the deal)
|
||||
```bash
|
||||
cd /var/www/html
|
||||
composer install --dev
|
||||
```
|
||||
|
||||
Execute the SQL statements. Via phpmyadmin or via the command line for example. 12345678 is the example password.
|
||||
Note that this is written without a space.
|
||||
```bash
|
||||
sudo mysql -h "localhost" -u "root" "-p12345678" < "/var/www/html/application/_installation/01-create-database.sql"
|
||||
sudo mysql -h "localhost" -u "root" "-p12345678" < "/var/www/html/application/_installation/02-create-table-users.sql"
|
||||
sudo mysql -h "localhost" -u "root" "-p12345678" < "/var/www/html/application/_installation/03-create-table-notes.sql"
|
||||
```
|
||||
|
||||
Make avatar folder writable
|
||||
```bash
|
||||
sudo chmod 0777 -R "/var/www/html/public/avatars"
|
||||
```
|
||||
|
||||
Remove Apache's default demo file
|
||||
```bash
|
||||
sudo rm "/var/www/html/index.html"
|
||||
```
|
||||
|
||||
Edit the application's config in application/config.development.php and put in your database credentials.
|
||||
|
||||
Last part (not needed for a first test): Set your SMTP credentials in the same file and set EMAIL_USE_SMTP to true, so
|
||||
you can send proper emails. It's highly recommended to use SMTP for mail sending! Native sending via PHP's mail() will
|
||||
not work in nearly every case (spam blocking). I use [SMTP2GO](http://www.smtp2go.com/?s=devmetal).
|
||||
|
||||
Then check your server's IP / domain. Everything should work fine.
|
||||
|
||||
#### Testing with demo user
|
||||
|
||||
By default HUGE has a demo-user: username is `demo`, password is `12345678`. The user is already activated.
|
||||
|
||||
### What the hell are .travis.yml, .scrutinizer.yml etc. ?
|
||||
|
||||
There are several files in the root folder of the project that might be irritating:
|
||||
|
||||
- *.htaccess* (optionally) routes all traffic to /public/index.php! If you installed this project correctly, then this
|
||||
file is not necessary, but as lots of people have problems setting up the vhost correctly, .htaccess it still there
|
||||
to increase security, even on partly-broken-installations.
|
||||
- *.scrutinizer.yml* (can be deleted): Configs for the external code quality analyzer Scrutinizer, just used here on
|
||||
GitHub, you don't need this for your project.
|
||||
- *.travis.yml* (can be deleted): Same like above. Travis is an external service that creates installations of this
|
||||
repo after each code change to make sure everything runs fine. Also runs the unit tests. You don't need this inside
|
||||
your project.
|
||||
- *composer.json* (important): You should know what this does. ;) This file says what external dependencies are used.
|
||||
- *travis-ci-apache* (can be deleted): Config file for Travis, see above, so Travis knows how to setup the Apache.
|
||||
|
||||
*README* and *CHANGELOG* are self-explaining.
|
||||
|
||||
#### Documentation <a name="documentation"></a>
|
||||
|
||||
A real documentation is in the making. Until then, please have a look at the code and use your IDE's code completion
|
||||
features to get an idea how things work, it's quite obvious when you look at the controller files, the model files and
|
||||
how data is shown in the view files. A big sorry that there's no documentation yet, but time is rare :)
|
||||
|
||||
TODO: Full documentation
|
||||
TODO: Basic examples on how to do things
|
||||
|
||||
### Why is there no support forum (anymore) ? <a name="why-no-support-forum"></a>
|
||||
|
||||
There were two (!) support forums for v1 and v2 of this project (HUGE is v3), and both were vandalized by people who
|
||||
didn't even read the readme and / or the install guidelines. Most asked question was "script does not work plz help"
|
||||
without giving any useful information (like code or server setup or even the version used). While I'm writing these
|
||||
lines somebody just asked via Twitter "how to install without Composer". You know what I mean :) ... Beside, 140
|
||||
characters on Twitter are not a clever way to ask for / describe a complex development situation. 99% of the questions
|
||||
were not necessary if the people would had read the guidelines, do a minimal research on their own or would stop making
|
||||
things so unnecessarily complicated. And even when writing detailed answers most of them still messed it up, resulting
|
||||
in rants and complaints (for free support for a free software!). It was just frustrating to deal with this every day,
|
||||
especially when people take it for totally granted that *it's the duty* of open-source developers to give detailed,
|
||||
free and personal support for every "plz help"-request.
|
||||
|
||||
So I decided to completely stop any free support. For serious questions about real problems inside the script please
|
||||
use the GitHub issues feature.
|
||||
|
||||
### Zero tolerance for idiots, trolls and vandals! <a name="zero-tolerance"></a>
|
||||
|
||||
Harsh words, but as basically every public internet project gets harassed, vandalized and trolled these days by very
|
||||
strange people it's necessary: Some simple rules.
|
||||
|
||||
1. Respect that this is just a simple script written by unpaid volunteers in their free-time.
|
||||
This is NOT business-software you've bought for $10.000.
|
||||
There's no reason to complain (!) about free open-source software. The attitude against free software
|
||||
is really frustrating these days, people take everything for granted without realizing the work behind it, and the
|
||||
fact they they get serious software totally for free, saving thousands of dollars. If you don't like it, then don't
|
||||
use it. If you want a feature, try to take part in the process, maybe even build it by yourself and add it to the
|
||||
project! Be nice and respectful. Constructive criticism is for sure always welcome!
|
||||
|
||||
2. Don't bash, don't hate, don't spam, don't vandalize. Don't ask for personal free support, don't ask if somebody
|
||||
could do your work for you. Before you ask something, make sure you've read the README, followed every tutorial,
|
||||
double-checked the code and tried to solve the problem by yourself.
|
||||
|
||||
Trolls and very annoying people will get a permanent ban / block. GitHub has a very powerful anti-abuse team.
|
||||
|
||||
### Contribute <a name="contribute"></a>
|
||||
|
||||
Please commit only in *develop* branch. The *master* branch will always contain the stable version.
|
||||
|
||||
### Found a bug (Responsible Disclosure) ? <a name="bug-report"></a>
|
||||
|
||||
Due to the possible consequences when publishing a bug on a public open-source project I'd kindly ask you to send really
|
||||
big bugs to my email address, not posting this here. If the bug is not interesting for attackers: Feel free to create
|
||||
an normal GitHub issue.
|
||||
|
||||
### Current and further development
|
||||
|
||||
See active issues and requested features here:
|
||||
https://github.com/panique/huge/issues?state=open
|
||||
|
||||
### Useful links
|
||||
|
||||
- [How to use PDO](http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers)
|
||||
- [A short guideline on how to use the PHP 5.5 password hashing functions and its PHP 5.3 & 5.4 implementations](http://www.dev-metal.com/use-php-5-5-password-hashing-functions/)
|
||||
- [How to setup latest version of PHP 5.5 on Ubuntu 12.04 LTS](http://www.dev-metal.com/how-to-setup-latest-version-of-php-5-5-on-ubuntu-12-04-lts/)
|
||||
- [How to setup latest version of PHP 5.5 on Debian Wheezy 7.0/7.1 (and how to fix the GPG key error)](http://www.dev-metal.com/setup-latest-version-php-5-5-debian-wheezy-7-07-1-fix-gpg-key-error/)
|
||||
- [Notes on password & hashing salting in upcoming PHP versions (PHP 5.5.x & 5.6 etc.)](https://github.com/panique/huge/wiki/Notes-on-password-&-hashing-salting-in-upcoming-PHP-versions-%28PHP-5.5.x-&-5.6-etc.%29)
|
||||
- [Some basic "benchmarks" of all PHP hash/salt algorithms](https://github.com/panique/huge/wiki/Which-hashing-&-salting-algorithm-should-be-used-%3F)
|
||||
- [How to prevent PHP sessions being shared between different apache vhosts / different applications](http://www.dev-metal.com/prevent-php-sessions-shared-different-apache-vhosts-different-applications/)
|
||||
|
||||
### Side-facts
|
||||
|
||||
1. Weird! When I renamed php-login to HUGE (to get rid off the too generic project name and to make it fitting nicely
|
||||
to MINI, TINY and MINI2, my other projects) I had a research if the word "huge" is already used in the php world for
|
||||
sure. Nothing came up. Then, weeks later, I stumbled upon this: https://github.com/ffremont/HugeRest
|
||||
I nice little framework in PHP, but it has only 1 star on Github, so it's obviously not so widely used. Looks very
|
||||
professional, too. Hmm.... The guy behind published the entire readme etc. in pure french (!), so it's hard to use
|
||||
for non-french-speaking people. However, I'm not related to him in any way, this is pure coincidence.
|
|
@ -1,22 +0,0 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
|
||||
# Every Vagrant virtual environment requires a box to build off of.
|
||||
config.vm.box = "ubuntu/trusty64"
|
||||
|
||||
# Create a private network, which allows host-only access to the machine using a specific IP.
|
||||
config.vm.network "private_network", ip: "192.168.33.111"
|
||||
|
||||
# Share an additional folder to the guest VM. The first argument is the path on the host to the actual folder.
|
||||
# The second argument is the path on the guest to mount the folder.
|
||||
config.vm.synced_folder "./", "/var/www/html"
|
||||
|
||||
# Define the bootstrap file: A (shell) script that runs after first setup of your box (= provisioning)
|
||||
config.vm.provision :shell, path: "bootstrap.sh"
|
||||
|
||||
end
|
|
@ -1,83 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Use single quotes instead of double quotes to make it work with special-character passwords
|
||||
PASSWORD='12345678'
|
||||
PROJECTFOLDER='myproject'
|
||||
|
||||
# create project folder
|
||||
sudo mkdir "/var/www/html/${PROJECTFOLDER}"
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get -y upgrade
|
||||
|
||||
sudo apt-get install -y apache2
|
||||
sudo apt-get install -y php5
|
||||
|
||||
sudo debconf-set-selections <<< "mysql-server mysql-server/root_password password $PASSWORD"
|
||||
sudo debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $PASSWORD"
|
||||
sudo apt-get -y install mysql-server
|
||||
sudo apt-get install php5-mysql
|
||||
|
||||
sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/dbconfig-install boolean true"
|
||||
sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/app-password-confirm password $PASSWORD"
|
||||
sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/mysql/admin-pass password $PASSWORD"
|
||||
sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/mysql/app-pass password $PASSWORD"
|
||||
sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/reconfigure-webserver multiselect apache2"
|
||||
sudo apt-get -y install phpmyadmin
|
||||
|
||||
# setup hosts file
|
||||
VHOST=$(cat <<EOF
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot "/var/www/html/${PROJECTFOLDER}/public"
|
||||
<Directory "/var/www/html/${PROJECTFOLDER}/public">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
EOF
|
||||
)
|
||||
echo "${VHOST}" > /etc/apache2/sites-available/000-default.conf
|
||||
|
||||
# enable mod_rewrite
|
||||
sudo a2enmod rewrite
|
||||
|
||||
# restart apache
|
||||
service apache2 restart
|
||||
|
||||
# install curl (needed to use git afaik)
|
||||
sudo apt-get -y install curl
|
||||
sudo apt-get -y install php5-curl
|
||||
|
||||
# install openssl (needed to clone from GitHub, as github is https only)
|
||||
sudo apt-get -y install openssl
|
||||
|
||||
# install PHP GD, the graphic lib (we create captchas and avatars)
|
||||
sudo apt-get -y install php5-gd
|
||||
|
||||
# install git
|
||||
sudo apt-get -y install git
|
||||
|
||||
# git clone HUGE
|
||||
sudo git clone https://github.com/panique/huge "/var/www/html/${PROJECTFOLDER}"
|
||||
|
||||
# install Composer
|
||||
curl -s https://getcomposer.org/installer | php
|
||||
mv composer.phar /usr/local/bin/composer
|
||||
|
||||
# go to project folder, load Composer packages
|
||||
cd "/var/www/html/${PROJECTFOLDER}"
|
||||
composer install --dev
|
||||
|
||||
# run SQL statements from install folder
|
||||
sudo mysql -h "localhost" -u "root" "-p${PASSWORD}" < "/var/www/html/${PROJECTFOLDER}/application/_installation/01-create-database.sql"
|
||||
sudo mysql -h "localhost" -u "root" "-p${PASSWORD}" < "/var/www/html/${PROJECTFOLDER}/application/_installation/02-create-table-users.sql"
|
||||
sudo mysql -h "localhost" -u "root" "-p${PASSWORD}" < "/var/www/html/${PROJECTFOLDER}/application/_installation/03-create-table-notes.sql"
|
||||
|
||||
# writing rights to avatar folder
|
||||
sudo chmod 0777 -R "/var/www/html/${PROJECTFOLDER}/public/avatars"
|
||||
|
||||
# remove Apache's default demo file
|
||||
sudo rm "/var/www/html/index.html"
|
||||
|
||||
# final feedback
|
||||
echo "Voila!"
|
Binary file not shown.
Before Width: | Height: | Size: 58 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
|
@ -1 +0,0 @@
|
|||
CREATE DATABASE IF NOT EXISTS `huge`;
|
|
@ -1,28 +0,0 @@
|
|||
CREATE TABLE IF NOT EXISTS `huge`.`users` (
|
||||
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'auto incrementing user_id of each user, unique index',
|
||||
`user_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT 'user''s name, unique',
|
||||
`user_password_hash` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'user''s password in salted and hashed format',
|
||||
`user_email` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT 'user''s email, unique',
|
||||
`user_active` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'user''s activation status',
|
||||
`user_account_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'user''s account type (basic, premium, etc)',
|
||||
`user_has_avatar` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1 if user has a local avatar, 0 if not',
|
||||
`user_remember_me_token` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'user''s remember-me cookie token',
|
||||
`user_creation_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the creation of user''s account',
|
||||
`user_last_login_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of user''s last login',
|
||||
`user_failed_logins` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'user''s failed login attempts',
|
||||
`user_last_failed_login` int(10) DEFAULT NULL COMMENT 'unix timestamp of last failed login attempt',
|
||||
`user_activation_hash` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'user''s email verification hash string',
|
||||
`user_password_reset_hash` char(40) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'user''s password reset code',
|
||||
`user_password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request',
|
||||
`user_provider_type` text COLLATE utf8_unicode_ci,
|
||||
PRIMARY KEY (`user_id`),
|
||||
UNIQUE KEY `user_name` (`user_name`),
|
||||
UNIQUE KEY `user_email` (`user_email`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='user data';
|
||||
|
||||
INSERT INTO `huge`.`users` (`user_id`, `user_name`, `user_password_hash`, `user_email`, `user_active`, `user_account_type`,
|
||||
`user_has_avatar`, `user_remember_me_token`, `user_creation_timestamp`, `user_last_login_timestamp`,
|
||||
`user_failed_logins`, `user_last_failed_login`, `user_activation_hash`, `user_password_reset_hash`,
|
||||
`user_password_reset_timestamp`, `user_provider_type`) VALUES
|
||||
(1, 'demo', '$2y$10$OvprunjvKOOhM1h9bzMPs.vuwGIsOqZbw88rzSyGCTJTcE61g5WXi', 'demo@demo.com', 1, 1, 0, NULL, 1422205178,
|
||||
1422209189, 0, NULL, NULL, NULL, NULL, 'DEFAULT');
|
|
@ -1,6 +0,0 @@
|
|||
CREATE TABLE IF NOT EXISTS `huge`.`notes` (
|
||||
`note_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`note_text` text NOT NULL,
|
||||
`user_id` int(11) unsigned NOT NULL,
|
||||
PRIMARY KEY (`note_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='user notes';
|
|
@ -1,129 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Configuration for DEVELOPMENT environment
|
||||
* To create another configuration set just copy this file to config.production.php etc. You get the idea :)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configuration for: Error reporting
|
||||
* Useful to show every little problem during development, but only show hard / no errors in production.
|
||||
* It's a little bit dirty to put this here, but who cares. For development purposes it's totally okay.
|
||||
*/
|
||||
error_reporting(E_ALL);
|
||||
ini_set("display_errors", 1);
|
||||
|
||||
/**
|
||||
* Returns the full configuration.
|
||||
* This is used by the core/Config class.
|
||||
*/
|
||||
return array(
|
||||
/**
|
||||
* Configuration for: Base URL
|
||||
* This detects your URL/IP incl. sub-folder automatically. You can also deactivate auto-detection and provide the
|
||||
* URL manually. This should then look like 'http://192.168.33.44/' ! Note the slash in the end.
|
||||
*/
|
||||
'URL' => 'http://' . $_SERVER['HTTP_HOST'] . str_replace('public', '', dirname($_SERVER['SCRIPT_NAME'])),
|
||||
/**
|
||||
* Configuration for: Folders
|
||||
* Usually there's no reason to change this.
|
||||
*/
|
||||
'PATH_CONTROLLER' => realpath(dirname(__FILE__).'/../../') . '/application/controller/',
|
||||
'PATH_VIEW' => realpath(dirname(__FILE__).'/../../') . '/application/view/',
|
||||
/**
|
||||
* Configuration for: Avatar paths
|
||||
* Internal path to save avatars. Make sure this folder is writable. The slash at the end is VERY important!
|
||||
*/
|
||||
'PATH_AVATARS' => realpath(dirname(__FILE__).'/../../') . '/public/avatars/',
|
||||
'PATH_AVATARS_PUBLIC' => 'avatars/',
|
||||
/**
|
||||
* Configuration for: Default controller and action
|
||||
*/
|
||||
'DEFAULT_CONTROLLER' => 'index',
|
||||
'DEFAULT_ACTION' => 'index',
|
||||
/**
|
||||
* Configuration for: Database
|
||||
* DB_TYPE The used database type. Note that other types than "mysql" might break the db construction currently.
|
||||
* DB_HOST The mysql hostname, usually localhost or 127.0.0.1
|
||||
* DB_NAME The database name
|
||||
* DB_USER The username
|
||||
* DB_PASS The password
|
||||
* DB_PORT The mysql port, 3306 by default (?), find out via phpinfo() and look for mysqli.default_port.
|
||||
* DB_CHARSET The charset, necessary for security reasons. Check Database.php class for more info.
|
||||
*/
|
||||
'DB_TYPE' => 'mysql',
|
||||
'DB_HOST' => '127.0.0.1',
|
||||
'DB_NAME' => 'huge',
|
||||
'DB_USER' => 'root',
|
||||
'DB_PASS' => '12345678',
|
||||
'DB_PORT' => '3306',
|
||||
'DB_CHARSET' => 'utf8',
|
||||
/**
|
||||
* Configuration for: Additional login providers: Facebook
|
||||
* CURRENTLY REMOVED (as Facebook has removed support for the used API version).
|
||||
* Another, better and up-to-date implementation might come soon.
|
||||
*/
|
||||
'FACEBOOK_LOGIN' => false,
|
||||
/**
|
||||
* Configuration for: Captcha size
|
||||
* The currently used Captcha generator (https://github.com/Gregwar/Captcha) also runs without giving a size,
|
||||
* so feel free to use ->build(); inside CaptchaModel.
|
||||
*/
|
||||
'CAPTCHA_WIDTH' => 359,
|
||||
'CAPTCHA_HEIGHT' => 100,
|
||||
/**
|
||||
* Configuration for: Cookies
|
||||
* 1209600 seconds = 2 weeks
|
||||
* COOKIE_PATH is the path the cookie is valid on, usually "/" to make it valid on the whole domain.
|
||||
* @see http://stackoverflow.com/q/9618217/1114320
|
||||
* @see php.net/manual/en/function.setcookie.php
|
||||
*/
|
||||
'COOKIE_RUNTIME' => 1209600,
|
||||
'COOKIE_PATH' => '/',
|
||||
/**
|
||||
* Configuration for: Avatars/Gravatar support
|
||||
* Set to true if you want to use "Gravatar(s)", a service that automatically gets avatar pictures via using email
|
||||
* addresses of users by requesting images from the gravatar.com API. Set to false to use own locally saved avatars.
|
||||
* AVATAR_SIZE set the pixel size of avatars/gravatars (will be 44x44 by default). Avatars are always squares.
|
||||
* AVATAR_DEFAULT_IMAGE is the default image in public/avatars/
|
||||
*/
|
||||
'USE_GRAVATAR' => false,
|
||||
'GRAVATAR_DEFAULT_IMAGESET' => 'mm',
|
||||
'GRAVATAR_RATING' => 'pg',
|
||||
'AVATAR_SIZE' => 44,
|
||||
'AVATAR_JPEG_QUALITY' => 85,
|
||||
'AVATAR_DEFAULT_IMAGE' => 'default.jpg',
|
||||
/**
|
||||
* Configuration for: Email server credentials
|
||||
*
|
||||
* Here you can define how you want to send emails.
|
||||
* If you have successfully set up a mail server on your linux server and you know
|
||||
* what you do, then you can skip this section. Otherwise please set EMAIL_USE_SMTP to true
|
||||
* and fill in your SMTP provider account data.
|
||||
*
|
||||
* EMAIL_USED_MAILER: Check Mail class for alternatives
|
||||
* EMAIL_USE_SMTP: Use SMTP or not
|
||||
* EMAIL_SMTP_AUTH: leave this true unless your SMTP service does not need authentication
|
||||
*/
|
||||
'EMAIL_USED_MAILER' => 'phpmailer',
|
||||
'EMAIL_USE_SMTP' => false,
|
||||
'EMAIL_SMTP_HOST' => 'yourhost',
|
||||
'EMAIL_SMTP_AUTH' => true,
|
||||
'EMAIL_SMTP_USERNAME' => 'yourusername',
|
||||
'EMAIL_SMTP_PASSWORD' => 'yourpassword',
|
||||
'EMAIL_SMTP_PORT' => 465,
|
||||
'EMAIL_SMTP_ENCRYPTION' => 'ssl',
|
||||
/**
|
||||
* Configuration for: Email content data
|
||||
*/
|
||||
'EMAIL_PASSWORD_RESET_URL' => 'login/verifypasswordreset',
|
||||
'EMAIL_PASSWORD_RESET_FROM_EMAIL' => 'no-reply@example.com',
|
||||
'EMAIL_PASSWORD_RESET_FROM_NAME' => 'My Project',
|
||||
'EMAIL_PASSWORD_RESET_SUBJECT' => 'Password reset for PROJECT XY',
|
||||
'EMAIL_PASSWORD_RESET_CONTENT' => 'Please click on this link to reset your password: ',
|
||||
'EMAIL_VERIFICATION_URL' => 'login/verify',
|
||||
'EMAIL_VERIFICATION_FROM_EMAIL' => 'no-reply@example.com',
|
||||
'EMAIL_VERIFICATION_FROM_NAME' => 'My Project',
|
||||
'EMAIL_VERIFICATION_SUBJECT' => 'Account activation for PROJECT XY',
|
||||
'EMAIL_VERIFICATION_CONTENT' => 'Please click on this link to activate your account: ',
|
||||
);
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Texts used in the application.
|
||||
* These texts are used via Text::get('FEEDBACK_USERNAME_ALREADY_TAKEN').
|
||||
* Could be extended to i18n etc.
|
||||
*/
|
||||
return array(
|
||||
"FEEDBACK_UNKNOWN_ERROR" => "Unknown error occurred!",
|
||||
"FEEDBACK_PASSWORD_WRONG_3_TIMES" => "You have typed in a wrong password 3 or more times already. Please wait 30 seconds to try again.",
|
||||
"FEEDBACK_ACCOUNT_NOT_ACTIVATED_YET" => "Your account is not activated yet. Please click on the confirm link in the mail.",
|
||||
"FEEDBACK_PASSWORD_WRONG" => "Password was wrong.",
|
||||
"FEEDBACK_USER_DOES_NOT_EXIST" => "This user does not exist.",
|
||||
"FEEDBACK_LOGIN_FAILED" => "Login failed.",
|
||||
"FEEDBACK_USERNAME_FIELD_EMPTY" => "Username field was empty.",
|
||||
"FEEDBACK_PASSWORD_FIELD_EMPTY" => "Password field was empty.",
|
||||
"FEEDBACK_USERNAME_OR_PASSWORD_FIELD_EMPTY" => "Username or password field was empty.",
|
||||
"FEEDBACK_USERNAME_EMAIL_FIELD_EMPTY" => "Username / email field was empty.",
|
||||
"FEEDBACK_EMAIL_FIELD_EMPTY" => "Email field was empty.",
|
||||
"FEEDBACK_EMAIL_AND_PASSWORD_FIELDS_EMPTY" => "Email and password fields were empty.",
|
||||
"FEEDBACK_USERNAME_SAME_AS_OLD_ONE" => "Sorry, that username is the same as your current one. Please choose another one.",
|
||||
"FEEDBACK_USERNAME_ALREADY_TAKEN" => "Sorry, that username is already taken. Please choose another one.",
|
||||
"FEEDBACK_USER_EMAIL_ALREADY_TAKEN" => "Sorry, that email is already in use. Please choose another one.",
|
||||
"FEEDBACK_USERNAME_CHANGE_SUCCESSFUL" => "Your username has been changed successfully.",
|
||||
"FEEDBACK_USERNAME_AND_PASSWORD_FIELD_EMPTY" => "Username and password fields were empty.",
|
||||
"FEEDBACK_USERNAME_DOES_NOT_FIT_PATTERN" => "Username does not fit the name pattern: only a-Z and numbers are allowed, 2 to 64 characters.",
|
||||
"FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN" => "Sorry, your chosen email does not fit into the email naming pattern.",
|
||||
"FEEDBACK_EMAIL_SAME_AS_OLD_ONE" => "Sorry, that email address is the same as your current one. Please choose another one.",
|
||||
"FEEDBACK_EMAIL_CHANGE_SUCCESSFUL" => "Your email address has been changed successfully.",
|
||||
"FEEDBACK_CAPTCHA_WRONG" => "The entered captcha security characters were wrong.",
|
||||
"FEEDBACK_PASSWORD_REPEAT_WRONG" => "Password and password repeat are not the same.",
|
||||
"FEEDBACK_PASSWORD_TOO_SHORT" => "Password has a minimum length of 6 characters.",
|
||||
"FEEDBACK_USERNAME_TOO_SHORT_OR_TOO_LONG" => "Username cannot be shorter than 2 or longer than 64 characters.",
|
||||
"FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED" => "Your account has been created successfully and we have sent you an email. Please click the VERIFICATION LINK within that mail.",
|
||||
"FEEDBACK_VERIFICATION_MAIL_SENDING_FAILED" => "Sorry, we could not send you an verification mail. Your account has NOT been created.",
|
||||
"FEEDBACK_ACCOUNT_CREATION_FAILED" => "Sorry, your registration failed. Please go back and try again.",
|
||||
"FEEDBACK_VERIFICATION_MAIL_SENDING_ERROR" => "Verification mail could not be sent due to: ",
|
||||
"FEEDBACK_VERIFICATION_MAIL_SENDING_SUCCESSFUL" => "A verification mail has been sent successfully.",
|
||||
"FEEDBACK_ACCOUNT_ACTIVATION_SUCCESSFUL" => "Activation was successful! You can now log in.",
|
||||
"FEEDBACK_ACCOUNT_ACTIVATION_FAILED" => "Sorry, no such id/verification code combination here...",
|
||||
"FEEDBACK_AVATAR_UPLOAD_SUCCESSFUL" => "Avatar upload was successful.",
|
||||
"FEEDBACK_AVATAR_UPLOAD_WRONG_TYPE" => "Only JPEG and PNG files are supported.",
|
||||
"FEEDBACK_AVATAR_UPLOAD_TOO_SMALL" => "Avatar source file's width/height is too small. Needs to be 100x100 pixel minimum.",
|
||||
"FEEDBACK_AVATAR_UPLOAD_TOO_BIG" => "Avatar source file is too big. 5 Megabyte is the maximum.",
|
||||
"FEEDBACK_AVATAR_FOLDER_DOES_NOT_EXIST_OR_NOT_WRITABLE" => "Avatar folder does not exist or is not writable. Please change this via chmod 775 or 777.",
|
||||
"FEEDBACK_AVATAR_IMAGE_UPLOAD_FAILED" => "Something went wrong with the image upload.",
|
||||
"FEEDBACK_AVATAR_IMAGE_DELETE_SUCCESSFUL" => "You successfully deleted your avatar.",
|
||||
"FEEDBACK_AVATAR_IMAGE_DELETE_NO_FILE" => "You don't have a custom avatar.",
|
||||
"FEEDBACK_AVATAR_IMAGE_DELETE_FAILED" => "Something went wrong while deleting your avatar.",
|
||||
"FEEDBACK_PASSWORD_RESET_TOKEN_FAIL" => "Could not write token to database.",
|
||||
"FEEDBACK_PASSWORD_RESET_TOKEN_MISSING" => "No password reset token.",
|
||||
"FEEDBACK_PASSWORD_RESET_MAIL_SENDING_ERROR" => "Password reset mail could not be sent due to: ",
|
||||
"FEEDBACK_PASSWORD_RESET_MAIL_SENDING_SUCCESSFUL" => "A password reset mail has been sent successfully.",
|
||||
"FEEDBACK_PASSWORD_RESET_LINK_EXPIRED" => "Your reset link has expired. Please use the reset link within one hour.",
|
||||
"FEEDBACK_PASSWORD_RESET_COMBINATION_DOES_NOT_EXIST" => "Username/Verification code combination does not exist.",
|
||||
"FEEDBACK_PASSWORD_RESET_LINK_VALID" => "Password reset validation link is valid. Please change the password now.",
|
||||
"FEEDBACK_PASSWORD_CHANGE_SUCCESSFUL" => "Password successfully changed.",
|
||||
"FEEDBACK_PASSWORD_CHANGE_FAILED" => "Sorry, your password changing failed.",
|
||||
"FEEDBACK_ACCOUNT_TYPE_CHANGE_SUCCESSFUL" => "Account type change successful",
|
||||
"FEEDBACK_ACCOUNT_TYPE_CHANGE_FAILED" => "Account type change failed",
|
||||
"FEEDBACK_NOTE_CREATION_FAILED" => "Note creation failed.",
|
||||
"FEEDBACK_NOTE_EDITING_FAILED" => "Note editing failed.",
|
||||
"FEEDBACK_NOTE_DELETION_FAILED" => "Note deletion failed.",
|
||||
"FEEDBACK_COOKIE_INVALID" => "Your remember-me-cookie is invalid.",
|
||||
"FEEDBACK_COOKIE_LOGIN_SUCCESSFUL" => "You were successfully logged in via the remember-me-cookie.",
|
||||
"FEEDBACK_FACEBOOK_LOGIN_NOT_REGISTERED" => "Sorry, you don't have an account here. Please register first.",
|
||||
"FEEDBACK_FACEBOOK_EMAIL_NEEDED" => "Sorry, but you need to allow us to see your email address to register.",
|
||||
"FEEDBACK_FACEBOOK_UID_ALREADY_EXISTS" => "Sorry, but you have already registered here (your Facebook ID exists in our database).",
|
||||
"FEEDBACK_FACEBOOK_EMAIL_ALREADY_EXISTS" => "Sorry, but you have already registered here (your Facebook email exists in our database).",
|
||||
"FEEDBACK_FACEBOOK_USERNAME_ALREADY_EXISTS" => "Sorry, but you have already registered here (your Facebook username exists in our database).",
|
||||
"FEEDBACK_FACEBOOK_REGISTER_SUCCESSFUL" => "You have been successfully registered with Facebook.",
|
||||
"FEEDBACK_FACEBOOK_OFFLINE" => "We could not reach the Facebook servers. Maybe Facebook is offline (that really happens sometimes).",
|
||||
);
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This controller shows an area that's only visible for logged in users (because of Auth::checkAuthentication(); in line 16)
|
||||
*/
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Construct this object by extending the basic Controller class
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// this entire controller should only be visible/usable by logged in users, so we put authentication-check here
|
||||
Auth::checkAuthentication();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /dashboard/index in your app.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->View->render('dashboard/index');
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class Error
|
||||
* This controller simply shows a page that will be displayed when a controller/method is not found. Simple 404.
|
||||
*/
|
||||
class ErrorController extends Controller
|
||||
{
|
||||
/**
|
||||
* Construct this object by extending the basic Controller class
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens / what the user sees when a page does not exist (404)
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$this->View->render('error/index');
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
/**
|
||||
* Construct this object by extending the basic Controller class
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles what happens when user moves to URL/index/index - or - as this is the default controller, also
|
||||
* when user moves to /index or enter your application at base level
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->View->render('index/index');
|
||||
}
|
||||
}
|
|
@ -1,313 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* LoginController
|
||||
* Controls everything that is authentication-related
|
||||
*/
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/**
|
||||
* Construct this object by extending the basic Controller class. The parent::__construct thing is necessary to
|
||||
* put checkAuthentication in here to make an entire controller only usable for logged-in users (for sure not
|
||||
* needed in the LoginController).
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Index, default action (shows the login form), when you do login/index
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// if user is logged in redirect to main-page, if not show the view
|
||||
if (LoginModel::isUserLoggedIn()) {
|
||||
Redirect::home();
|
||||
} else {
|
||||
$this->View->render('login/index');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The login action, when you do login/login
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
// perform the login method, put result (true or false) into $login_successful
|
||||
$login_successful = LoginModel::login(
|
||||
Request::post('user_name'), Request::post('user_password'), Request::post('set_remember_me_cookie')
|
||||
);
|
||||
|
||||
// check login status: if true, then redirect user login/showProfile, if false, then to login form again
|
||||
if ($login_successful) {
|
||||
Redirect::to('login/showProfile');
|
||||
} else {
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The logout action
|
||||
* Perform logout, redirect user to main-page
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
LoginModel::logout();
|
||||
Redirect::home();
|
||||
}
|
||||
|
||||
/**
|
||||
* Login with cookie
|
||||
*/
|
||||
public function loginWithCookie()
|
||||
{
|
||||
// run the loginWithCookie() method in the login-model, put the result in $login_successful (true or false)
|
||||
$login_successful = LoginModel::loginWithCookie(Request::cookie('remember_me'));
|
||||
|
||||
// if login successful, redirect to dashboard/index ...
|
||||
if ($login_successful) {
|
||||
Redirect::to('dashboard/index');
|
||||
} else {
|
||||
// if not, delete cookie (outdated? attack?) and route user to login form to prevent infinite login loops
|
||||
LoginModel::deleteCookie();
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show user's PRIVATE profile
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
public function showProfile()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
$this->View->render('login/showProfile', array(
|
||||
'user_name' => Session::get('user_name'),
|
||||
'user_email' => Session::get('user_email'),
|
||||
'user_gravatar_image_url' => Session::get('user_gravatar_image_url'),
|
||||
'user_avatar_file' => Session::get('user_avatar_file'),
|
||||
'user_account_type' => Session::get('user_account_type')
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show edit-my-username page
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
public function editUsername()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
$this->View->render('login/editUsername');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit user name (perform the real action after form has been submitted)
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action
|
||||
*/
|
||||
public function editUsername_action()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
UserModel::editUserName(Request::post('user_name'));
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show edit-my-user-email page
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
public function editUserEmail()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
$this->View->render('login/editUserEmail');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit user email (perform the real action after form has been submitted)
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
// make this POST
|
||||
public function editUserEmail_action()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
UserModel::editUserEmail(Request::post('user_email'));
|
||||
Redirect::to('login/editUserEmail');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit avatar
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
public function editAvatar()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
$this->View->render('login/editAvatar', array(
|
||||
'avatar_file_path' => AvatarModel::getPublicUserAvatarFilePathByUserId(Session::get('user_id'))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the upload of the avatar
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
* POST-request
|
||||
*/
|
||||
public function uploadAvatar_action()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
AvatarModel::createAvatar();
|
||||
Redirect::to('login/editAvatar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the current user's avatar
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
public function deleteAvatar_action()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
AvatarModel::deleteAvatar(Session::get("user_id"));
|
||||
Redirect::to('login/editAvatar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the change-account-type page
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
|
||||
*/
|
||||
public function changeUserRole()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
$this->View->render('login/changeUserRole');
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the account-type changing
|
||||
* Auth::checkAuthentication() makes sure that only logged in users can use this action
|
||||
* POST-request
|
||||
*/
|
||||
public function changeUserRole_action()
|
||||
{
|
||||
Auth::checkAuthentication();
|
||||
|
||||
if (Request::post('user_account_upgrade')) {
|
||||
// "2" is quick & dirty account type 2, something like "premium user" maybe. you got the idea :)
|
||||
UserRoleModel::changeUserRole(2);
|
||||
}
|
||||
|
||||
if (Request::post('user_account_downgrade')) {
|
||||
// "1" is quick & dirty account type 1, something like "basic user" maybe.
|
||||
UserRoleModel::changeUserRole(1);
|
||||
}
|
||||
|
||||
Redirect::to('login/changeUserRole');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register page
|
||||
* Show the register form, but redirect to main-page if user is already logged-in
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if (LoginModel::isUserLoggedIn()) {
|
||||
Redirect::home();
|
||||
} else {
|
||||
$this->View->render('login/register');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register page action
|
||||
* POST-request after form submit
|
||||
*/
|
||||
public function register_action()
|
||||
{
|
||||
$registration_successful = RegistrationModel::registerNewUser();
|
||||
|
||||
if ($registration_successful) {
|
||||
Redirect::to('login/index');
|
||||
} else {
|
||||
Redirect::to('login/register');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user after activation mail link opened
|
||||
* @param int $user_id user's id
|
||||
* @param string $user_activation_verification_code user's verification token
|
||||
*/
|
||||
public function verify($user_id, $user_activation_verification_code)
|
||||
{
|
||||
if (isset($user_id) && isset($user_activation_verification_code)) {
|
||||
RegistrationModel::verifyNewUser($user_id, $user_activation_verification_code);
|
||||
$this->View->render('login/verify');
|
||||
} else {
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the request-password-reset page
|
||||
*/
|
||||
public function requestPasswordReset()
|
||||
{
|
||||
$this->View->render('login/requestPasswordReset');
|
||||
}
|
||||
|
||||
/**
|
||||
* The request-password-reset action
|
||||
* POST-request after form submit
|
||||
*/
|
||||
public function requestPasswordReset_action()
|
||||
{
|
||||
PasswordResetModel::requestPasswordReset(Request::post('user_name_or_email'));
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the verification token of that user (to show the user the password editing view or not)
|
||||
* @param string $user_name username
|
||||
* @param string $verification_code password reset verification token
|
||||
*/
|
||||
public function verifyPasswordReset($user_name, $verification_code)
|
||||
{
|
||||
// check if this the provided verification code fits the user's verification code
|
||||
if (PasswordResetModel::verifyPasswordReset($user_name, $verification_code)) {
|
||||
// pass URL-provided variable to view to display them
|
||||
$this->View->render('login/changePassword', array(
|
||||
'user_name' => $user_name,
|
||||
'user_password_reset_hash' => $verification_code
|
||||
));
|
||||
} else {
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new password
|
||||
* Please note that this happens while the user is not logged in. The user identifies via the data provided by the
|
||||
* password reset link from the email, automatically filled into the <form> fields. See verifyPasswordReset()
|
||||
* for more. Then (regardless of result) route user to index page (user will get success/error via feedback message)
|
||||
* POST request !
|
||||
* TODO this is an _action
|
||||
*/
|
||||
public function setNewPassword()
|
||||
{
|
||||
PasswordResetModel::setNewPassword(
|
||||
Request::post('user_name'), Request::post('user_password_reset_hash'),
|
||||
Request::post('user_password_new'), Request::post('user_password_repeat')
|
||||
);
|
||||
Redirect::to('login/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a captcha, write the characters into $_SESSION['captcha'] and returns a real image which will be used
|
||||
* like this: <img src="......./login/showCaptcha" />
|
||||
* IMPORTANT: As this action is called via <img ...> AFTER the real application has finished executing (!), the
|
||||
* SESSION["captcha"] has no content when the application is loaded. The SESSION["captcha"] gets filled at the
|
||||
* moment the end-user requests the <img .. >
|
||||
* Maybe refactor this sometime.
|
||||
*/
|
||||
public function showCaptcha()
|
||||
{
|
||||
CaptchaModel::generateAndShowCaptcha();
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The note controller: Just an example of simple create, read, update and delete (CRUD) actions.
|
||||
*/
|
||||
class NoteController extends Controller
|
||||
{
|
||||
/**
|
||||
* Construct this object by extending the basic Controller class
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// VERY IMPORTANT: All controllers/areas that should only be usable by logged-in users
|
||||
// need this line! Otherwise not-logged in users could do actions. If all of your pages should only
|
||||
// be usable by logged-in users: Put this line into libs/Controller->__construct
|
||||
Auth::checkAuthentication();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /note/index in your app.
|
||||
* Gets all notes (of the user).
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->View->render('note/index', array(
|
||||
'notes' => NoteModel::getAllNotes()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /dashboard/create in your app.
|
||||
* Creates a new note. This is usually the target of form submit actions.
|
||||
* POST request.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
NoteModel::createNote(Request::post('note_text'));
|
||||
Redirect::to('note');
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /note/edit(/XX) in your app.
|
||||
* Shows the current content of the note and an editing form.
|
||||
* @param $note_id int id of the note
|
||||
*/
|
||||
public function edit($note_id)
|
||||
{
|
||||
$this->View->render('note/edit', array(
|
||||
'note' => NoteModel::getNote($note_id)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /note/editSave in your app.
|
||||
* Edits a note (performs the editing after form submit).
|
||||
* POST request.
|
||||
*/
|
||||
public function editSave()
|
||||
{
|
||||
NoteModel::updateNote(Request::post('note_id'), Request::post('note_text'));
|
||||
Redirect::to('note');
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /note/delete(/XX) in your app.
|
||||
* Deletes a note. In a real application a deletion via GET/URL is not recommended, but for demo purposes it's
|
||||
* totally okay.
|
||||
* @param int $note_id id of the note
|
||||
*/
|
||||
public function delete($note_id)
|
||||
{
|
||||
NoteModel::deleteNote($note_id);
|
||||
Redirect::to('note');
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Construct this object by extending the basic Controller class
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /overview/index in your app.
|
||||
* Shows a list of all users.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->View->render('profile/index', array(
|
||||
'users' => UserModel::getPublicProfilesOfAllUsers())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method controls what happens when you move to /overview/showProfile in your app.
|
||||
* Shows the (public) details of the selected user.
|
||||
* @param $user_id int id the the user
|
||||
*/
|
||||
public function showProfile($user_id)
|
||||
{
|
||||
if (isset($user_id)) {
|
||||
$this->View->render('profile/showProfile', array(
|
||||
'user' => UserModel::getPublicProfileOfUser($user_id))
|
||||
);
|
||||
} else {
|
||||
Redirect::home();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class Application
|
||||
* The heart of the application
|
||||
*/
|
||||
class Application
|
||||
{
|
||||
/** @var mixed Instance of the controller */
|
||||
private $controller;
|
||||
|
||||
/** @var array URL parameters, will be passed to used controller-method */
|
||||
private $parameters = array();
|
||||
|
||||
/** @var string Just the name of the controller, useful for checks inside the view ("where am I ?") */
|
||||
private $controller_name;
|
||||
|
||||
/** @var string Just the name of the controller's method, useful for checks inside the view ("where am I ?") */
|
||||
private $action_name;
|
||||
|
||||
/**
|
||||
* Start the application, analyze URL elements, call according controller/method or relocate to fallback location
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// create array with URL parts in $url
|
||||
$this->splitUrl();
|
||||
|
||||
// creates controller and action names (from URL input)
|
||||
$this->createControllerAndActionNames();
|
||||
|
||||
// does such a controller exist ?
|
||||
if (file_exists(Config::get('PATH_CONTROLLER') . $this->controller_name . '.php')) {
|
||||
|
||||
// load this file and create this controller
|
||||
// example: if controller would be "car", then this line would translate into: $this->car = new car();
|
||||
require Config::get('PATH_CONTROLLER') . $this->controller_name . '.php';
|
||||
$this->controller = new $this->controller_name();
|
||||
|
||||
// check for method: does such a method exist in the controller ?
|
||||
if (method_exists($this->controller, $this->action_name)) {
|
||||
if (!empty($this->parameters)) {
|
||||
// call the method and pass arguments to it
|
||||
call_user_func_array(array($this->controller, $this->action_name), $this->parameters);
|
||||
} else {
|
||||
// if no parameters are given, just call the method without parameters, like $this->index->index();
|
||||
$this->controller->{$this->action_name}();
|
||||
}
|
||||
} else {
|
||||
header('location: ' . Config::get('URL') . 'error');
|
||||
}
|
||||
} else {
|
||||
header('location: ' . Config::get('URL') . 'error');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and split the URL
|
||||
*/
|
||||
private function splitUrl()
|
||||
{
|
||||
if (Request::get('url')) {
|
||||
|
||||
// split URL
|
||||
$url = trim(Request::get('url'), '/');
|
||||
$url = filter_var($url, FILTER_SANITIZE_URL);
|
||||
$url = explode('/', $url);
|
||||
|
||||
// put URL parts into according properties
|
||||
$this->controller_name = isset($url[0]) ? $url[0] : null;
|
||||
$this->action_name = isset($url[1]) ? $url[1] : null;
|
||||
|
||||
// remove controller name and action name from the split URL
|
||||
unset($url[0], $url[1]);
|
||||
|
||||
// rebase array keys and store the URL parameters
|
||||
$this->parameters = array_values($url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if controller and action names are given. If not, default values are put into the properties.
|
||||
* Also renames controller to usable name.
|
||||
*/
|
||||
private function createControllerAndActionNames()
|
||||
{
|
||||
// check for controller: no controller given ? then make controller = default controller (from config)
|
||||
if (!$this->controller_name) {
|
||||
$this->controller_name = Config::get('DEFAULT_CONTROLLER');
|
||||
}
|
||||
|
||||
// check for action: no action given ? then make action = default action (from config)
|
||||
if (!$this->action_name OR (strlen($this->action_name) == 0)) {
|
||||
$this->action_name = Config::get('DEFAULT_ACTION');
|
||||
}
|
||||
|
||||
// rename controller name to real controller class/file name ("index" to "IndexController")
|
||||
$this->controller_name = ucwords($this->controller_name) . 'Controller';
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class Auth
|
||||
* Checks if user is logged in, if not then sends the user to "yourdomain.com/login".
|
||||
* Auth::checkAuthentication() can be used in the constructor of a controller (to make the
|
||||
* entire controller only visible for logged-in users) or inside a controller-method to make only this part of the
|
||||
* application available for logged-in users.
|
||||
*/
|
||||
class Auth
|
||||
{
|
||||
public static function checkAuthentication()
|
||||
{
|
||||
// initialize the session (if not initialized yet)
|
||||
Session::init();
|
||||
|
||||
// if user is not logged in...
|
||||
if (!Session::userIsLoggedIn()) {
|
||||
// ... then treat user as "not logged in", destroy session, redirect to login page
|
||||
Session::destroy();
|
||||
header('location: ' . Config::get('URL') . 'login');
|
||||
// to prevent fetching views via cURL (which "ignores" the header-redirect above) we leave the application
|
||||
// the hard way, via exit(). @see https://github.com/panique/php-login/issues/453
|
||||
// this is not optimal and will be fixed in future releases
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Config
|
||||
{
|
||||
// this is public to allow better Unit Testing
|
||||
public static $config;
|
||||
|
||||
public static function get($key)
|
||||
{
|
||||
if (!self::$config) {
|
||||
|
||||
$config_file = '../application/config/config.' . Environment::get() . '.php';
|
||||
|
||||
if (!file_exists($config_file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self::$config = require $config_file;
|
||||
}
|
||||
|
||||
return self::$config[$key];
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This is the "base controller class". All other "real" controllers extend this class.
|
||||
* Whenever a controller is created, we also
|
||||
* 1. initialize a session
|
||||
* 2. check if the user is not logged in anymore (session timeout) but has a cookie
|
||||
*/
|
||||
class Controller
|
||||
{
|
||||
/** @var View View The view object */
|
||||
public $View;
|
||||
|
||||
/**
|
||||
* Construct the (base) controller. This happens when a real controller is constructed, like in
|
||||
* the constructor of IndexController when it says: parent::__construct();
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
// always initialize a session
|
||||
Session::init();
|
||||
|
||||
// user is not logged in but has remember-me-cookie ? then try to login with cookie ("remember me" feature)
|
||||
if (!Session::userIsLoggedIn() AND Request::cookie('remember_me')) {
|
||||
header('location: ' . Config::get('URL') . 'login/loginWithCookie');
|
||||
}
|
||||
|
||||
// create a view object to be able to use it inside a controller, like $this->View->render();
|
||||
$this->View = new View();
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class DatabaseFactory
|
||||
*
|
||||
* Use it like this:
|
||||
* $database = DatabaseFactory::getFactory()->getConnection();
|
||||
*
|
||||
* That's my personal favourite when creating a database connection.
|
||||
* It's a slightly modified version of Jon Raphaelson's excellent answer on StackOverflow:
|
||||
* http://stackoverflow.com/questions/130878/global-or-singleton-for-database-connection
|
||||
*
|
||||
* Full quote from the answer:
|
||||
*
|
||||
* "Then, in 6 months when your app is super famous and getting dugg and slashdotted and you decide you need more than
|
||||
* a single connection, all you have to do is implement some pooling in the getConnection() method. Or if you decide
|
||||
* that you want a wrapper that implements SQL logging, you can pass a PDO subclass. Or if you decide you want a new
|
||||
* connection on every invocation, you can do do that. It's flexible, instead of rigid."
|
||||
*
|
||||
* Thanks! Big up, mate!
|
||||
*/
|
||||
class DatabaseFactory
|
||||
{
|
||||
private static $factory;
|
||||
private $database;
|
||||
|
||||
public static function getFactory()
|
||||
{
|
||||
if (!self::$factory) {
|
||||
self::$factory = new DatabaseFactory();
|
||||
}
|
||||
return self::$factory;
|
||||
}
|
||||
|
||||
public function getConnection() {
|
||||
if (!$this->database) {
|
||||
$options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
|
||||
$this->database = new PDO(
|
||||
Config::get('DB_TYPE') . ':host=' . Config::get('DB_HOST') . ';dbname=' .
|
||||
Config::get('DB_NAME') . ';port=' . Config::get('DB_PORT') . ';charset=' . Config::get('DB_CHARSET'),
|
||||
Config::get('DB_USER'), Config::get('DB_PASS'), $options
|
||||
);
|
||||
}
|
||||
return $this->database;
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class Environment
|
||||
*
|
||||
* Extremely simple way to get the environment, everywhere inside your application.
|
||||
* Extend this the way you want.
|
||||
*/
|
||||
class Environment
|
||||
{
|
||||
public static function get()
|
||||
{
|
||||
// if APPLICATION_ENV constant exists (set in Apache configs)
|
||||
// then return content of APPLICATION_ENV
|
||||
// else return "development"
|
||||
return (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : "development");
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Mail
|
||||
{
|
||||
/** @var mixed variable to collect errors */
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* Try to send a mail by using PHP's native mail() function.
|
||||
* Please note that not PHP itself will send a mail, it's just a wrapper for Linux's sendmail or other mail tools
|
||||
*
|
||||
* Good guideline on how to send mails natively with mail():
|
||||
* @see http://stackoverflow.com/a/24644450/1114320
|
||||
* @see http://www.php.net/manual/en/function.mail.php
|
||||
*/
|
||||
public function sendMailWithNativeMailFunction()
|
||||
{
|
||||
// no code yet, so we just return something to make IDEs and code analyzer tools happy
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to send a mail by using SwiftMailer.
|
||||
* Make sure you have loaded SwiftMailer via Composer.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sendMailWithSwiftMailer()
|
||||
{
|
||||
// no code yet, so we just return something to make IDEs and code analyzer tools happy
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to send a mail by using PHPMailer.
|
||||
* Make sure you have loaded PHPMailer via Composer.
|
||||
* Depending on your EMAIL_USE_SMTP setting this will work via SMTP credentials or via native mail()
|
||||
*
|
||||
* @param $user_email
|
||||
* @param $from_email
|
||||
* @param $from_name
|
||||
* @param $subject
|
||||
* @param $body
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
* @throws phpmailerException
|
||||
*/
|
||||
public function sendMailWithPHPMailer($user_email, $from_email, $from_name, $subject, $body)
|
||||
{
|
||||
$mail = new PHPMailer;
|
||||
|
||||
// if you want to send mail via PHPMailer using SMTP credentials
|
||||
if (Config::get('EMAIL_USE_SMTP')) {
|
||||
// set PHPMailer to use SMTP
|
||||
$mail->IsSMTP();
|
||||
// 0 = off, 1 = commands, 2 = commands and data, perfect to see SMTP errors
|
||||
$mail->SMTPDebug = 0;
|
||||
// enable SMTP authentication
|
||||
$mail->SMTPAuth = Config::get('EMAIL_SMTP_AUTH');
|
||||
// encryption
|
||||
if (Config::get('EMAIL_SMTP_ENCRYPTION')) {
|
||||
$mail->SMTPSecure = Config::get('EMAIL_SMTP_ENCRYPTION');
|
||||
}
|
||||
// set SMTP provider's credentials
|
||||
$mail->Host = Config::get('EMAIL_SMTP_HOST');
|
||||
$mail->Username = Config::get('EMAIL_SMTP_USERNAME');
|
||||
$mail->Password = Config::get('EMAIL_SMTP_PASSWORD');
|
||||
$mail->Port = Config::get('EMAIL_SMTP_PORT');
|
||||
} else {
|
||||
$mail->IsMail();
|
||||
}
|
||||
|
||||
// fill mail with data
|
||||
$mail->From = $from_email;
|
||||
$mail->FromName = $from_name;
|
||||
$mail->AddAddress($user_email);
|
||||
$mail->Subject = $subject;
|
||||
$mail->Body = $body;
|
||||
|
||||
// try to send mail
|
||||
$mail->Send();
|
||||
|
||||
if ($mail) {
|
||||
return true;
|
||||
} else {
|
||||
// if not successful, copy errors into Mail's error property
|
||||
$this->error = $mail->ErrorInfo;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function sendMail($user_email, $from_email, $from_name, $subject, $body)
|
||||
{
|
||||
if (Config::get('EMAIL_USED_MAILER') == "phpmailer") {
|
||||
// returns true if successful, false if not
|
||||
return $this->sendMailWithPHPMailer(
|
||||
$user_email, $from_email, $from_name, $subject, $body
|
||||
);
|
||||
}
|
||||
|
||||
if (Config::get('EMAIL_USED_MAILER') == "swiftmailer") {
|
||||
return $this->sendMailWithSwiftMailer();
|
||||
}
|
||||
|
||||
if (Config::get('EMAIL_USED_MAILER') == "native") {
|
||||
return $this->sendMailWithNativeMailFunction();
|
||||
}
|
||||
}
|
||||
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class Redirect
|
||||
*
|
||||
* Simple abstraction for redirecting the user to a certain page
|
||||
*/
|
||||
class Redirect
|
||||
{
|
||||
/**
|
||||
* To the homepage
|
||||
*/
|
||||
public static function home()
|
||||
{
|
||||
header("location: " . Config::get('URL'));
|
||||
}
|
||||
|
||||
/**
|
||||
* To the defined page
|
||||
*
|
||||
* @param $path
|
||||
*/
|
||||
public static function to($path)
|
||||
{
|
||||
header("location: " . Config::get('URL') . $path);
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This is under development. Expect changes!
|
||||
* Class Request
|
||||
* Abstracts the access to $_GET, $_POST and $_COOKIE, preventing direct access to these super-globals.
|
||||
* This makes PHP code quality analyzer tools very happy.
|
||||
* @see http://php.net/manual/en/reserved.variables.request.php
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* Gets/returns the value of a specific key of the POST super-global.
|
||||
* When using just Request::post('x') it will return the raw and untouched $_POST['x'], when using it like
|
||||
* Request::post('x', true) then it will return a trimmed and stripped $_POST['x'] !
|
||||
*
|
||||
* @param mixed $key key
|
||||
* @param bool $clean marker for optional cleaning of the var
|
||||
* @return mixed the key's value or nothing
|
||||
*/
|
||||
public static function post($key, $clean = false)
|
||||
{
|
||||
if (isset($_POST[$key])) {
|
||||
// we use the Ternary Operator here which saves the if/else block
|
||||
// @see http://davidwalsh.name/php-shorthand-if-else-ternary-operators
|
||||
return ($clean) ? trim(strip_tags($_POST[$key])) : $_POST[$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets/returns the value of a specific key of the GET super-global
|
||||
* @param mixed $key key
|
||||
* @return mixed the key's value or nothing
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
if (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets/returns the value of a specific key of the COOKIE super-global
|
||||
* @param mixed $key key
|
||||
* @return mixed the key's value or nothing
|
||||
*/
|
||||
public static function cookie($key)
|
||||
{
|
||||
if (isset($_COOKIE[$key])) {
|
||||
return $_COOKIE[$key];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Session class
|
||||
*
|
||||
* handles the session stuff. creates session when no one exists, sets and gets values, and closes the session
|
||||
* properly (=logout). Not to forget the check if the user is logged in or not.
|
||||
*/
|
||||
class Session
|
||||
{
|
||||
/**
|
||||
* starts the session
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
// if no session exist, start the session
|
||||
if (session_id() == '') {
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets a specific value to a specific key of the session
|
||||
*
|
||||
* @param mixed $key key
|
||||
* @param mixed $value value
|
||||
*/
|
||||
public static function set($key, $value)
|
||||
{
|
||||
$_SESSION[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets/returns the value of a specific key of the session
|
||||
*
|
||||
* @param mixed $key Usually a string, right ?
|
||||
* @return mixed the key's value or nothing
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
if (isset($_SESSION[$key])) {
|
||||
return $_SESSION[$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a value as a new array element to the key.
|
||||
* useful for collecting error messages etc
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function add($key, $value)
|
||||
{
|
||||
$_SESSION[$key][] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes the session (= logs the user out)
|
||||
*/
|
||||
public static function destroy()
|
||||
{
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is logged in or not
|
||||
*
|
||||
* @return bool user's login status
|
||||
*/
|
||||
public static function userIsLoggedIn()
|
||||
{
|
||||
return (Session::get('user_logged_in') ? true : false);
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Text
|
||||
{
|
||||
private static $texts;
|
||||
|
||||
public static function get($key)
|
||||
{
|
||||
// if not $key
|
||||
if (!$key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// load config file (this is only done once per application lifecycle)
|
||||
if (!self::$texts) {
|
||||
self::$texts = require('../application/config/texts.php');
|
||||
}
|
||||
|
||||
// check if array key exists
|
||||
if (!array_key_exists($key, self::$texts)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return self::$texts[$key];
|
||||
}
|
||||
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class View
|
||||
* The part that handles all the output
|
||||
*/
|
||||
class View
|
||||
{
|
||||
/**
|
||||
* simply includes (=shows) the view. this is done from the controller. In the controller, you usually say
|
||||
* $this->view->render('help/index'); to show (in this example) the view index.php in the folder help.
|
||||
* Usually the Class and the method are the same like the view, but sometimes you need to show different views.
|
||||
* @param string $filename Path of the to-be-rendered view, usually folder/file(.php)
|
||||
* @param array $data Data to be used in the view
|
||||
*/
|
||||
public function render($filename, $data = null)
|
||||
{
|
||||
if ($data) {
|
||||
foreach ($data as $key => $value) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
require Config::get('PATH_VIEW') . '_templates/header.php';
|
||||
require Config::get('PATH_VIEW') . $filename . '.php';
|
||||
require Config::get('PATH_VIEW') . '_templates/footer.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to render, but accepts an array of separate views to render between the header and footer. Use like
|
||||
* the following: $this->view->renderMulti(array('help/index', 'help/banner'));
|
||||
* @param array $filenames Array of the paths of the to-be-rendered view, usually folder/file(.php) for each
|
||||
* @param array $data Data to be used in the view
|
||||
* @return bool
|
||||
*/
|
||||
public function renderMulti($filenames, $data = null)
|
||||
{
|
||||
if (!is_array($filenames)) {
|
||||
self::render($filenames, $data);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data) {
|
||||
foreach ($data as $key => $value) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
require Config::get('PATH_VIEW') . '_templates/header.php';
|
||||
|
||||
foreach($filenames as $filename) {
|
||||
require Config::get('PATH_VIEW') . $filename . '.php';
|
||||
}
|
||||
|
||||
require Config::get('PATH_VIEW') . '_templates/footer.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Same like render(), but does not include header and footer
|
||||
* @param string $filename Path of the to-be-rendered view, usually folder/file(.php)
|
||||
* @param mixed $data Data to be used in the view
|
||||
*/
|
||||
public function renderWithoutHeaderAndFooter($filename, $data = null)
|
||||
{
|
||||
if ($data) {
|
||||
foreach ($data as $key => $value) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
require Config::get('PATH_VIEW') . $filename . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders pure JSON to the browser, useful for API construction
|
||||
* @param $data
|
||||
*/
|
||||
public function renderJSON($data)
|
||||
{
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* renders the feedback messages into the view
|
||||
*/
|
||||
public function renderFeedbackMessages()
|
||||
{
|
||||
// echo out the feedback messages (errors and success messages etc.),
|
||||
// they are in $_SESSION["feedback_positive"] and $_SESSION["feedback_negative"]
|
||||
require Config::get('PATH_VIEW') . '_templates/feedback.php';
|
||||
|
||||
// delete these messages (as they are not needed anymore and we want to avoid to show them twice
|
||||
Session::set('feedback_positive', null);
|
||||
Session::set('feedback_negative', null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed string is the currently active controller.
|
||||
* Useful for handling the navigation's active/non-active link.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $navigation_controller
|
||||
*
|
||||
* @return bool Shows if the controller is used or not
|
||||
*/
|
||||
public static function checkForActiveController($filename, $navigation_controller)
|
||||
{
|
||||
$split_filename = explode("/", $filename);
|
||||
$active_controller = $split_filename[0];
|
||||
|
||||
if ($active_controller == $navigation_controller) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed string is the currently active controller-action (=method).
|
||||
* Useful for handling the navigation's active/non-active link.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $navigation_action
|
||||
*
|
||||
* @return bool Shows if the action/method is used or not
|
||||
*/
|
||||
public static function checkForActiveAction($filename, $navigation_action)
|
||||
{
|
||||
$split_filename = explode("/", $filename);
|
||||
$active_action = $split_filename[1];
|
||||
|
||||
if ($active_action == $navigation_action) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed string is the currently active controller and controller-action.
|
||||
* Useful for handling the navigation's active/non-active link.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $navigation_controller_and_action
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkForActiveControllerAndAction($filename, $navigation_controller_and_action)
|
||||
{
|
||||
$split_filename = explode("/", $filename);
|
||||
$active_controller = $split_filename[0];
|
||||
$active_action = $split_filename[1];
|
||||
|
||||
$split_filename = explode("/", $navigation_controller_and_action);
|
||||
$navigation_controller = $split_filename[0];
|
||||
$navigation_action = $split_filename[1];
|
||||
|
||||
if ($active_controller == $navigation_controller AND $active_action == $navigation_action) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
<?php
|
||||
|
||||
class AvatarModel
|
||||
{
|
||||
/**
|
||||
* Gets a gravatar image link from given email address
|
||||
*
|
||||
* Gravatar is the #1 (free) provider for email address based global avatar hosting.
|
||||
* The URL (or image) returns always a .jpg file ! For deeper info on the different parameter possibilities:
|
||||
* @see http://gravatar.com/site/implement/images/
|
||||
* @source http://gravatar.com/site/implement/images/php/
|
||||
*
|
||||
* This method will return something like http://www.gravatar.com/avatar/79e2e5b48aec07710c08d50?s=80&d=mm&r=g
|
||||
* Note: the url does NOT have something like ".jpg" ! It works without.
|
||||
*
|
||||
* Set the configs inside the application/config/ files.
|
||||
*
|
||||
* @param string $email The email address
|
||||
* @return string
|
||||
*/
|
||||
public static function getGravatarLinkByEmail($email)
|
||||
{
|
||||
return 'http://www.gravatar.com/avatar/' .
|
||||
md5( strtolower( trim( $email ) ) ) .
|
||||
'?s=' . Config::get('AVATAR_SIZE') . '&d=' . Config::get('GRAVATAR_DEFAULT_IMAGESET') . '&r=' . Config::get('GRAVATAR_RATING');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user's avatar file path
|
||||
* @param int $user_has_avatar Marker from database
|
||||
* @param int $user_id User's id
|
||||
* @return string Avatar file path
|
||||
*/
|
||||
public static function getPublicAvatarFilePathOfUser($user_has_avatar, $user_id)
|
||||
{
|
||||
if ($user_has_avatar) {
|
||||
return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . $user_id . '.jpg';
|
||||
}
|
||||
|
||||
return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . Config::get('AVATAR_DEFAULT_IMAGE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user's avatar file path
|
||||
* @param $user_id integer The user's id
|
||||
* @return string avatar picture path
|
||||
*/
|
||||
public static function getPublicUserAvatarFilePathByUserId($user_id)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("SELECT user_has_avatar FROM users WHERE user_id = :user_id LIMIT 1");
|
||||
$query->execute(array(':user_id' => $user_id));
|
||||
|
||||
if ($query->fetch()->user_has_avatar) {
|
||||
return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . $user_id . '.jpg';
|
||||
}
|
||||
|
||||
return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . Config::get('AVATAR_DEFAULT_IMAGE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an avatar picture (and checks all necessary things too)
|
||||
* TODO decouple
|
||||
* TODO total rebuild
|
||||
*/
|
||||
public static function createAvatar()
|
||||
{
|
||||
// check avatar folder writing rights, check if upload fits all rules
|
||||
if (AvatarModel::isAvatarFolderWritable() AND AvatarModel::validateImageFile()) {
|
||||
|
||||
// create a jpg file in the avatar folder, write marker to database
|
||||
$target_file_path = Config::get('PATH_AVATARS') . Session::get('user_id');
|
||||
AvatarModel::resizeAvatarImage($_FILES['avatar_file']['tmp_name'], $target_file_path, Config::get('AVATAR_SIZE'), Config::get('AVATAR_SIZE'), Config::get('AVATAR_JPEG_QUALITY'));
|
||||
AvatarModel::writeAvatarToDatabase(Session::get('user_id'));
|
||||
Session::set('user_avatar_file', AvatarModel::getPublicUserAvatarFilePathByUserId(Session::get('user_id')));
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_AVATAR_UPLOAD_SUCCESSFUL'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the avatar folder exists and is writable
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function isAvatarFolderWritable()
|
||||
{
|
||||
if (is_dir(Config::get('PATH_AVATARS')) AND is_writable(Config::get('PATH_AVATARS'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_FOLDER_DOES_NOT_EXIST_OR_NOT_WRITABLE'));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the image
|
||||
* TODO totally decouple
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateImageFile()
|
||||
{
|
||||
if (!isset($_FILES['avatar_file'])) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_IMAGE_UPLOAD_FAILED'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($_FILES['avatar_file']['size'] > 5000000) {
|
||||
// if input file too big (>5MB)
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_UPLOAD_TOO_BIG'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the image width, height and mime type
|
||||
$image_proportions = getimagesize($_FILES['avatar_file']['tmp_name']);
|
||||
|
||||
// if input file too small
|
||||
if ($image_proportions[0] < Config::get('AVATAR_SIZE') OR $image_proportions[1] < Config::get('AVATAR_SIZE')) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_UPLOAD_TOO_SMALL'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($image_proportions['mime'] == 'image/jpeg')) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_UPLOAD_WRONG_TYPE'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes marker to database, saying user has an avatar now
|
||||
*
|
||||
* @param $user_id
|
||||
*/
|
||||
public static function writeAvatarToDatabase($user_id)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("UPDATE users SET user_has_avatar = TRUE WHERE user_id = :user_id LIMIT 1");
|
||||
$query->execute(array(':user_id' => $user_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize avatar image (while keeping aspect ratio and cropping it off sexy)
|
||||
*
|
||||
* TROUBLESHOOTING: You don't see the new image ? Press F5 or CTRL-F5 to refresh browser cache.
|
||||
*
|
||||
* @param string $source_image The location to the original raw image.
|
||||
* @param string $destination The location to save the new image.
|
||||
* @param int $final_width The desired width of the new image
|
||||
* @param int $final_height The desired height of the new image.
|
||||
* @param int $quality The quality of the JPG to produce 1 - 100
|
||||
*
|
||||
* TODO currently we just allow .jpg
|
||||
*
|
||||
* @return bool success state
|
||||
*/
|
||||
public static function resizeAvatarImage($source_image, $destination, $final_width = 44, $final_height = 44, $quality = 85)
|
||||
{
|
||||
list($width, $height) = getimagesize($source_image);
|
||||
|
||||
if (!$width || !$height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//saving the image into memory (for manipulation with GD Library)
|
||||
$myImage = imagecreatefromjpeg($source_image);
|
||||
|
||||
// calculating the part of the image to use for thumbnail
|
||||
if ($width > $height) {
|
||||
$y = 0;
|
||||
$x = ($width - $height) / 2;
|
||||
$smallestSide = $height;
|
||||
} else {
|
||||
$x = 0;
|
||||
$y = ($height - $width) / 2;
|
||||
$smallestSide = $width;
|
||||
}
|
||||
|
||||
// copying the part into thumbnail, maybe edit this for square avatars
|
||||
$thumb = imagecreatetruecolor($final_width, $final_height);
|
||||
imagecopyresampled($thumb, $myImage, 0, 0, $x, $y, $final_width, $final_height, $smallestSide, $smallestSide);
|
||||
|
||||
// add '.jpg' to file path, save it as a .jpg file with our $destination_filename parameter
|
||||
$destination .= '.jpg';
|
||||
imagejpeg($thumb, $destination, $quality);
|
||||
|
||||
// delete "working copy"
|
||||
imagedestroy($thumb);
|
||||
|
||||
if (file_exists($destination)) {
|
||||
return true;
|
||||
}
|
||||
// default return
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a user's avatar
|
||||
*
|
||||
* @param int $userId
|
||||
* @return bool success
|
||||
*/
|
||||
public static function deleteAvatar($userId)
|
||||
{
|
||||
if (!ctype_digit($userId)) {
|
||||
Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_FAILED"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to delete image, but still go on regardless of file deletion result
|
||||
self::deleteAvatarImageFile($userId);
|
||||
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sth = $database->prepare("UPDATE users SET user_has_avatar = 0 WHERE user_id = :user_id LIMIT 1");
|
||||
$sth->bindValue(":user_id", (int)$userId, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
|
||||
if ($sth->rowCount() == 1) {
|
||||
Session::set('user_avatar_file', self::getPublicUserAvatarFilePathByUserId($userId));
|
||||
Session::add("feedback_positive", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_SUCCESSFUL"));
|
||||
return true;
|
||||
} else {
|
||||
Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_FAILED"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the avatar image file from the filesystem
|
||||
*
|
||||
* @param $userId
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteAvatarImageFile($userId)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists(Config::get('PATH_AVATARS') . $userId . ".jpg")) {
|
||||
Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_NO_FILE"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete avatar file
|
||||
if (!unlink(Config::get('PATH_AVATARS') . $userId . ".jpg")) {
|
||||
Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_FAILED"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class CaptchaModel
|
||||
*
|
||||
* This model class handles all the captcha stuff.
|
||||
* Currently this uses the excellent Captcha generator lib from https://github.com/Gregwar/Captcha
|
||||
* Have a look there for more options etc.
|
||||
*/
|
||||
class CaptchaModel
|
||||
{
|
||||
/**
|
||||
* Generates the captcha, "returns" a real image, this is why there is header('Content-type: image/jpeg')
|
||||
* Note: This is a very special method, as this is echoes out binary data.
|
||||
*/
|
||||
public static function generateAndShowCaptcha()
|
||||
{
|
||||
// create a captcha with the CaptchaBuilder lib (loaded via Composer)
|
||||
$captcha = new Gregwar\Captcha\CaptchaBuilder;
|
||||
$captcha->build(
|
||||
Config::get('CAPTCHA_WIDTH'),
|
||||
Config::get('CAPTCHA_HEIGHT')
|
||||
);
|
||||
|
||||
// write the captcha character into session
|
||||
Session::set('captcha', $captcha->getPhrase());
|
||||
|
||||
// render an image showing the characters (=the captcha)
|
||||
header('Content-type: image/jpeg');
|
||||
$captcha->output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entered captcha is the same like the one from the rendered image which has been saved in session
|
||||
* @param $captcha string The captcha characters
|
||||
* @return bool success of captcha check
|
||||
*/
|
||||
public static function checkCaptcha($captcha)
|
||||
{
|
||||
if ($captcha == Session::get('captcha')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,270 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* LoginModel
|
||||
*
|
||||
* The login part of the model: Handles the login / logout stuff
|
||||
*/
|
||||
class LoginModel
|
||||
{
|
||||
/**
|
||||
* Login process (for DEFAULT user accounts).
|
||||
*
|
||||
* @param $user_name string The user's name
|
||||
* @param $user_password string The user's password
|
||||
* @param $set_remember_me_cookie mixed Marker for usage of remember-me cookie feature
|
||||
*
|
||||
* @return bool success state
|
||||
*/
|
||||
public static function login($user_name, $user_password, $set_remember_me_cookie = null)
|
||||
{
|
||||
// we do negative-first checks here, for simplicity empty username and empty password in one line
|
||||
if (empty($user_name) OR empty($user_password)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_OR_PASSWORD_FIELD_EMPTY'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// checks if user exists, if login is not blocked (due to failed logins) and if password fits the hash
|
||||
$result = self::validateAndGetUser($user_name, $user_password);
|
||||
|
||||
if (!$result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset the failed login counter for that user (if necessary)
|
||||
if ($result->user_last_failed_login > 0) {
|
||||
self::resetFailedLoginCounterOfUser($result->user_name);
|
||||
}
|
||||
|
||||
// save timestamp of this login in the database line of that user
|
||||
self::saveTimestampOfLoginOfUser($result->user_name);
|
||||
|
||||
// if user has checked the "remember me" checkbox, then write token into database and into cookie
|
||||
if ($set_remember_me_cookie) {
|
||||
self::setRememberMeInDatabaseAndCookie($result->user_id);
|
||||
}
|
||||
|
||||
// successfully logged in, so we write all necessary data into the session and set "user_logged_in" to true
|
||||
self::setSuccessfulLoginIntoSession(
|
||||
$result->user_id, $result->user_name, $result->user_email, $result->user_account_type
|
||||
);
|
||||
|
||||
// return true to make clear the login was successful
|
||||
// maybe do this in dependence of setSuccessfulLoginIntoSession ?
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the inputs of the users, checks if password is correct etc.
|
||||
* If successful, user is returned
|
||||
*
|
||||
* @param $user_name
|
||||
* @param $user_password
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private static function validateAndGetUser($user_name, $user_password)
|
||||
{
|
||||
// get all data of that user (to later check if password and password_hash fit)
|
||||
$result = UserModel::getUserDataByUsername($user_name);
|
||||
|
||||
// Check if that user exists. We don't give back a cause in the feedback to avoid giving an attacker details.
|
||||
if (!$result) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_LOGIN_FAILED'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// block login attempt if somebody has already failed 3 times and the last login attempt is less than 30sec ago
|
||||
if (($result->user_failed_logins >= 3) AND ($result->user_last_failed_login > (time() - 30))) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_WRONG_3_TIMES'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// if hash of provided password does NOT match the hash in the database: +1 failed-login counter
|
||||
if (!password_verify($user_password, $result->user_password_hash)) {
|
||||
self::incrementFailedLoginCounterOfUser($result->user_name);
|
||||
// we say "password wrong" here, but less details like "login failed" would be better (= less information)
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_WRONG'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// if user is not active (= has not verified account by verification mail)
|
||||
if ($result->user_active != 1) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_NOT_ACTIVATED_YET'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* performs the login via cookie (for DEFAULT user account, FACEBOOK-accounts are handled differently)
|
||||
* TODO add throttling here ?
|
||||
*
|
||||
* @param $cookie string The cookie "remember_me"
|
||||
*
|
||||
* @return bool success state
|
||||
*/
|
||||
public static function loginWithCookie($cookie)
|
||||
{
|
||||
if (!$cookie) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_COOKIE_INVALID'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// check cookie's contents, check if cookie contents belong together or token is empty
|
||||
list ($user_id, $token, $hash) = explode(':', $cookie);
|
||||
if ($hash !== hash('sha256', $user_id . ':' . $token) OR empty($token)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_COOKIE_INVALID'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get data of user that has this id and this token
|
||||
$result = UserModel::getUserDataByUserIdAndToken($user_id, $token);
|
||||
if ($result) {
|
||||
// successfully logged in, so we write all necessary data into the session and set "user_logged_in" to true
|
||||
self::setSuccessfulLoginIntoSession($result->user_id, $result->user_name, $result->user_email, $result->user_account_type);
|
||||
// save timestamp of this login in the database line of that user
|
||||
self::saveTimestampOfLoginOfUser($result->user_name);
|
||||
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_COOKIE_LOGIN_SUCCESSFUL'));
|
||||
return true;
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_COOKIE_INVALID'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out process: delete cookie, delete session
|
||||
*/
|
||||
public static function logout()
|
||||
{
|
||||
self::deleteCookie();
|
||||
Session::destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* The real login process: The user's data is written into the session.
|
||||
* Cheesy name, maybe rename. Also maybe refactoring this, using an array.
|
||||
*
|
||||
* @param $user_id
|
||||
* @param $user_name
|
||||
* @param $user_email
|
||||
* @param $user_account_type
|
||||
*/
|
||||
public static function setSuccessfulLoginIntoSession($user_id, $user_name, $user_email, $user_account_type)
|
||||
{
|
||||
Session::init();
|
||||
Session::set('user_id', $user_id);
|
||||
Session::set('user_name', $user_name);
|
||||
Session::set('user_email', $user_email);
|
||||
Session::set('user_account_type', $user_account_type);
|
||||
Session::set('user_provider_type', 'DEFAULT');
|
||||
|
||||
// get and set avatars
|
||||
Session::set('user_avatar_file', AvatarModel::getPublicUserAvatarFilePathByUserId($user_id));
|
||||
Session::set('user_gravatar_image_url', AvatarModel::getGravatarLinkByEmail($user_email));
|
||||
|
||||
// finally, set user as logged-in
|
||||
Session::set('user_logged_in', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the failed-login counter of a user
|
||||
*
|
||||
* @param $user_name
|
||||
*/
|
||||
public static function incrementFailedLoginCounterOfUser($user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE users
|
||||
SET user_failed_logins = user_failed_logins+1, user_last_failed_login = :user_last_failed_login
|
||||
WHERE user_name = :user_name OR user_email = :user_name
|
||||
LIMIT 1";
|
||||
$sth = $database->prepare($sql);
|
||||
$sth->execute(array(':user_name' => $user_name, ':user_last_failed_login' => time() ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the failed-login counter of a user back to 0
|
||||
*
|
||||
* @param $user_name
|
||||
*/
|
||||
public static function resetFailedLoginCounterOfUser($user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE users
|
||||
SET user_failed_logins = 0, user_last_failed_login = NULL
|
||||
WHERE user_name = :user_name AND user_failed_logins != 0
|
||||
LIMIT 1";
|
||||
$sth = $database->prepare($sql);
|
||||
$sth->execute(array(':user_name' => $user_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write timestamp of this login into database (we only write a "real" login via login form into the database,
|
||||
* not the session-login on every page request
|
||||
*
|
||||
* @param $user_name
|
||||
*/
|
||||
public static function saveTimestampOfLoginOfUser($user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE users SET user_last_login_timestamp = :user_last_login_timestamp
|
||||
WHERE user_name = :user_name LIMIT 1";
|
||||
$sth = $database->prepare($sql);
|
||||
$sth->execute(array(':user_name' => $user_name, ':user_last_login_timestamp' => time()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write remember-me token into database and into cookie
|
||||
* Maybe splitting this into database and cookie part ?
|
||||
*
|
||||
* @param $user_id
|
||||
*/
|
||||
public static function setRememberMeInDatabaseAndCookie($user_id)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
// generate 64 char random string
|
||||
$random_token_string = hash('sha256', mt_rand());
|
||||
|
||||
// write that token into database
|
||||
$sql = "UPDATE users SET user_remember_me_token = :user_remember_me_token WHERE user_id = :user_id LIMIT 1";
|
||||
$sth = $database->prepare($sql);
|
||||
$sth->execute(array(':user_remember_me_token' => $random_token_string, ':user_id' => $user_id));
|
||||
|
||||
// generate cookie string that consists of user id, random string and combined hash of both
|
||||
$cookie_string_first_part = $user_id . ':' . $random_token_string;
|
||||
$cookie_string_hash = hash('sha256', $cookie_string_first_part);
|
||||
$cookie_string = $cookie_string_first_part . ':' . $cookie_string_hash;
|
||||
|
||||
// set cookie
|
||||
setcookie('remember_me', $cookie_string, time() + Config::get('COOKIE_RUNTIME'), Config::get('COOKIE_PATH'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the cookie
|
||||
* It's necessary to split deleteCookie() and logout() as cookies are deleted without logging out too!
|
||||
* Sets the remember-me-cookie to ten years ago (3600sec * 24 hours * 365 days * 10).
|
||||
* that's obviously the best practice to kill a cookie @see http://stackoverflow.com/a/686166/1114320
|
||||
*/
|
||||
public static function deleteCookie()
|
||||
{
|
||||
setcookie('remember_me', false, time() - (3600 * 24 * 3650), Config::get('COOKIE_PATH'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current state of the user's login
|
||||
*
|
||||
* @return bool user's login status
|
||||
*/
|
||||
public static function isUserLoggedIn()
|
||||
{
|
||||
return Session::userIsLoggedIn();
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* NoteModel
|
||||
* This is basically a simple CRUD (Create/Read/Update/Delete) demonstration.
|
||||
*/
|
||||
class NoteModel
|
||||
{
|
||||
/**
|
||||
* Get all notes (notes are just example data that the user has created)
|
||||
* @return array an array with several objects (the results)
|
||||
*/
|
||||
public static function getAllNotes()
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "SELECT user_id, note_id, note_text FROM notes WHERE user_id = :user_id";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':user_id' => Session::get('user_id')));
|
||||
|
||||
// fetchAll() is the PDO method that gets all result rows
|
||||
return $query->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single note
|
||||
* @param int $note_id id of the specific note
|
||||
* @return object a single object (the result)
|
||||
*/
|
||||
public static function getNote($note_id)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "SELECT user_id, note_id, note_text FROM notes WHERE user_id = :user_id AND note_id = :note_id LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':user_id' => Session::get('user_id'), ':note_id' => $note_id));
|
||||
|
||||
// fetch() is the PDO method that gets a single result
|
||||
return $query->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a note (create a new one)
|
||||
* @param string $note_text note text that will be created
|
||||
* @return bool feedback (was the note created properly ?)
|
||||
*/
|
||||
public static function createNote($note_text)
|
||||
{
|
||||
if (!$note_text || strlen($note_text) == 0) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_NOTE_CREATION_FAILED'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "INSERT INTO notes (note_text, user_id) VALUES (:note_text, :user_id)";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':note_text' => $note_text, ':user_id' => Session::get('user_id')));
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// default return
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_NOTE_CREATION_FAILED'));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing note
|
||||
* @param int $note_id id of the specific note
|
||||
* @param string $note_text new text of the specific note
|
||||
* @return bool feedback (was the update successful ?)
|
||||
*/
|
||||
public static function updateNote($note_id, $note_text)
|
||||
{
|
||||
if (!$note_id || !$note_text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE notes SET note_text = :note_text WHERE note_id = :note_id AND user_id = :user_id LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':note_id' => $note_id, ':note_text' => $note_text, ':user_id' => Session::get('user_id')));
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_NOTE_EDITING_FAILED'));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specific note
|
||||
* @param int $note_id id of the note
|
||||
* @return bool feedback (was the note deleted properly ?)
|
||||
*/
|
||||
public static function deleteNote($note_id)
|
||||
{
|
||||
if (!$note_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "DELETE FROM notes WHERE note_id = :note_id AND user_id = :user_id LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':note_id' => $note_id, ':user_id' => Session::get('user_id')));
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// default return
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_NOTE_DELETION_FAILED'));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class PasswordResetModel
|
||||
*
|
||||
* Handles all the stuff that is related to the password-reset process
|
||||
*/
|
||||
class PasswordResetModel
|
||||
{
|
||||
/**
|
||||
* Perform the necessary actions to send a password reset mail
|
||||
*
|
||||
* @param $user_name_or_email string Username or user's email
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function requestPasswordReset($user_name_or_email)
|
||||
{
|
||||
if (empty($user_name_or_email)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_EMAIL_FIELD_EMPTY'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if that username exists
|
||||
$result = UserModel::getUserDataByUserNameOrEmail($user_name_or_email);
|
||||
if (!$result) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USER_DOES_NOT_EXIST'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate integer-timestamp (to see when exactly the user (or an attacker) requested the password reset mail)
|
||||
// generate random hash for email password reset verification (40 char string)
|
||||
$temporary_timestamp = time();
|
||||
$user_password_reset_hash = sha1(uniqid(mt_rand(), true));
|
||||
|
||||
// set token (= a random hash string and a timestamp) into database ...
|
||||
$token_set = PasswordResetModel::setPasswordResetDatabaseToken($result->user_name, $user_password_reset_hash, $temporary_timestamp);
|
||||
if (!$token_set) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ... and send a mail to the user, containing a link with username and token hash string
|
||||
$mail_sent = PasswordResetModel::sendPasswordResetMail($result->user_name, $user_password_reset_hash, $result->user_email);
|
||||
if ($mail_sent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// default return
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password reset token in database (for DEFAULT user accounts)
|
||||
*
|
||||
* @param string $user_name username
|
||||
* @param string $user_password_reset_hash password reset hash
|
||||
* @param int $temporary_timestamp timestamp
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function setPasswordResetDatabaseToken($user_name, $user_password_reset_hash, $temporary_timestamp)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE users
|
||||
SET user_password_reset_hash = :user_password_reset_hash, user_password_reset_timestamp = :user_password_reset_timestamp
|
||||
WHERE user_name = :user_name AND user_provider_type = :provider_type LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(
|
||||
':user_password_reset_hash' => $user_password_reset_hash, ':user_name' => $user_name,
|
||||
':user_password_reset_timestamp' => $temporary_timestamp, ':provider_type' => 'DEFAULT'
|
||||
));
|
||||
|
||||
// check if exactly one row was successfully changed
|
||||
if ($query->rowCount() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// fallback
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_RESET_TOKEN_FAIL'));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the password reset mail
|
||||
*
|
||||
* @param string $user_name username
|
||||
* @param string $user_password_reset_hash password reset hash
|
||||
* @param string $user_email user email
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function sendPasswordResetMail($user_name, $user_password_reset_hash, $user_email)
|
||||
{
|
||||
// create email body
|
||||
$body = Config::get('EMAIL_PASSWORD_RESET_CONTENT') . ' ' . Config::get('URL') .
|
||||
Config::get('EMAIL_PASSWORD_RESET_URL') . '/' . urlencode($user_name) . '/' . urlencode($user_password_reset_hash);
|
||||
|
||||
// create instance of Mail class, try sending and check
|
||||
$mail = new Mail;
|
||||
$mail_sent = $mail->sendMail($user_email, Config::get('EMAIL_PASSWORD_RESET_FROM_EMAIL'),
|
||||
Config::get('EMAIL_PASSWORD_RESET_FROM_NAME'), Config::get('EMAIL_PASSWORD_RESET_SUBJECT'), $body
|
||||
);
|
||||
|
||||
if ($mail_sent) {
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_PASSWORD_RESET_MAIL_SENDING_SUCCESSFUL'));
|
||||
return true;
|
||||
}
|
||||
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_RESET_MAIL_SENDING_ERROR') . $mail->getError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the password reset request via the verification hash token (that's only valid for one hour)
|
||||
* @param string $user_name Username
|
||||
* @param string $verification_code Hash token
|
||||
* @return bool Success status
|
||||
*/
|
||||
public static function verifyPasswordReset($user_name, $verification_code)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
// check if user-provided username + verification code combination exists
|
||||
$sql = "SELECT user_id, user_password_reset_timestamp
|
||||
FROM users
|
||||
WHERE user_name = :user_name
|
||||
AND user_password_reset_hash = :user_password_reset_hash
|
||||
AND user_provider_type = :user_provider_type
|
||||
LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(
|
||||
':user_password_reset_hash' => $verification_code, ':user_name' => $user_name,
|
||||
':user_provider_type' => 'DEFAULT'
|
||||
));
|
||||
|
||||
// if this user with exactly this verification hash code does NOT exist
|
||||
if ($query->rowCount() != 1) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_RESET_COMBINATION_DOES_NOT_EXIST'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get result row (as an object)
|
||||
$result_user_row = $query->fetch();
|
||||
|
||||
// 3600 seconds are 1 hour
|
||||
$timestamp_one_hour_ago = time() - 3600;
|
||||
|
||||
// if password reset request was sent within the last hour (this timeout is for security reasons)
|
||||
if ($result_user_row->user_password_reset_timestamp > $timestamp_one_hour_ago) {
|
||||
// verification was successful
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_PASSWORD_RESET_LINK_VALID'));
|
||||
return true;
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_RESET_LINK_EXPIRED'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the new password to the database
|
||||
*
|
||||
* @param string $user_name username
|
||||
* @param string $user_password_hash
|
||||
* @param string $user_password_reset_hash
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveNewUserPassword($user_name, $user_password_hash, $user_password_reset_hash)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE users SET user_password_hash = :user_password_hash, user_password_reset_hash = NULL,
|
||||
user_password_reset_timestamp = NULL
|
||||
WHERE user_name = :user_name AND user_password_reset_hash = :user_password_reset_hash
|
||||
AND user_provider_type = :user_provider_type LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(
|
||||
':user_password_hash' => $user_password_hash, ':user_name' => $user_name,
|
||||
':user_password_reset_hash' => $user_password_reset_hash, ':user_provider_type' => 'DEFAULT'
|
||||
));
|
||||
|
||||
// if one result exists, return true, else false. Could be written even shorter btw.
|
||||
return ($query->rowCount() == 1 ? true : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new password (for DEFAULT user, FACEBOOK-users don't have a password)
|
||||
* Please note: At this point the user has already pre-verified via verifyPasswordReset() (within one hour),
|
||||
* so we don't need to check again for the 60min-limit here. In this method we authenticate
|
||||
* via username & password-reset-hash from (hidden) form fields.
|
||||
*
|
||||
* @param string $user_name
|
||||
* @param string $user_password_reset_hash
|
||||
* @param string $user_password_new
|
||||
* @param string $user_password_repeat
|
||||
*
|
||||
* @return bool success state of the password reset
|
||||
*/
|
||||
public static function setNewPassword($user_name, $user_password_reset_hash, $user_password_new, $user_password_repeat)
|
||||
{
|
||||
// validate the password
|
||||
if (!self::validateNewPassword($user_name, $user_password_reset_hash, $user_password_new, $user_password_repeat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// crypt the password (with the PHP 5.5+'s password_hash() function, result is a 60 character hash string)
|
||||
$user_password_hash = password_hash($user_password_new, PASSWORD_DEFAULT);
|
||||
|
||||
// write the password to database (as hashed and salted string), reset user_password_reset_hash
|
||||
if (PasswordResetModel::saveNewUserPassword($user_name, $user_password_hash, $user_password_reset_hash)) {
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_PASSWORD_CHANGE_SUCCESSFUL'));
|
||||
return true;
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_CHANGE_FAILED'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the password submission
|
||||
*
|
||||
* @param $user_name
|
||||
* @param $user_password_reset_hash
|
||||
* @param $user_password_new
|
||||
* @param $user_password_repeat
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateNewPassword($user_name, $user_password_reset_hash, $user_password_new, $user_password_repeat)
|
||||
{
|
||||
if (empty($user_name)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_FIELD_EMPTY'));
|
||||
return false;
|
||||
} else if (empty($user_password_reset_hash)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_RESET_TOKEN_MISSING'));
|
||||
return false;
|
||||
} else if (empty($user_password_new) || empty($user_password_repeat)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_FIELD_EMPTY'));
|
||||
return false;
|
||||
} else if ($user_password_new !== $user_password_repeat) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_REPEAT_WRONG'));
|
||||
return false;
|
||||
} else if (strlen($user_password_new) < 6) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_TOO_SHORT'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,278 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class RegistrationModel
|
||||
*
|
||||
* Everything registration-related happens here.
|
||||
*/
|
||||
class RegistrationModel
|
||||
{
|
||||
/**
|
||||
* Handles the entire registration process for DEFAULT users (not for people who register with
|
||||
* 3rd party services, like facebook) and creates a new user in the database if everything is fine
|
||||
*
|
||||
* @return boolean Gives back the success status of the registration
|
||||
*/
|
||||
public static function registerNewUser()
|
||||
{
|
||||
// TODO this could be written simpler and cleaner
|
||||
|
||||
// clean the input
|
||||
$user_name = strip_tags(Request::post('user_name'));
|
||||
$user_email = strip_tags(Request::post('user_email'));
|
||||
$user_password_new = Request::post('user_password_new');
|
||||
$user_password_repeat = Request::post('user_password_repeat');
|
||||
|
||||
// stop registration flow if registrationInputValidation() returns false (= anything breaks the input check rules)
|
||||
$validation_result = RegistrationModel::registrationInputValidation(Request::post('captcha'), $user_name, $user_password_new, $user_password_repeat, $user_email);
|
||||
if (!$validation_result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// crypt the password with the PHP 5.5's password_hash() function, results in a 60 character hash string.
|
||||
// @see php.net/manual/en/function.password-hash.php for more, especially for potential options
|
||||
$user_password_hash = password_hash($user_password_new, PASSWORD_DEFAULT);
|
||||
|
||||
// check if username already exists
|
||||
if (UserModel::doesUsernameAlreadyExist($user_name)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_ALREADY_TAKEN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if email already exists
|
||||
if (UserModel::doesEmailAlreadyExist($user_email)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USER_EMAIL_ALREADY_TAKEN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate random hash for email verification (40 char string)
|
||||
$user_activation_hash = sha1(uniqid(mt_rand(), true));
|
||||
|
||||
// write user data to database
|
||||
if (!RegistrationModel::writeNewUserToDatabase($user_name, $user_password_hash, $user_email, time(), $user_activation_hash)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_CREATION_FAILED'));
|
||||
}
|
||||
|
||||
// get user_id of the user that has been created, to keep things clean we DON'T use lastInsertId() here
|
||||
$user_id = UserModel::getUserIdByUsername($user_name);
|
||||
|
||||
if (!$user_id) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_UNKNOWN_ERROR'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// send verification email
|
||||
if (RegistrationModel::sendVerificationEmail($user_id, $user_email, $user_activation_hash)) {
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED'));
|
||||
return true;
|
||||
}
|
||||
|
||||
// if verification email sending failed: instantly delete the user
|
||||
RegistrationModel::rollbackRegistrationByUserId($user_id);
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_VERIFICATION_MAIL_SENDING_FAILED'));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the registration input
|
||||
*
|
||||
* @param $captcha
|
||||
* @param $user_name
|
||||
* @param $user_password_new
|
||||
* @param $user_password_repeat
|
||||
* @param $user_email
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function registrationInputValidation($captcha, $user_name, $user_password_new, $user_password_repeat, $user_email)
|
||||
{
|
||||
// perform all necessary checks
|
||||
if (!CaptchaModel::checkCaptcha($captcha)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_CAPTCHA_WRONG'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// if username, email and password are all correctly validated
|
||||
if (self::validateUserName($user_name) AND self::validateUserEmail($user_email) AND self::validateUserPassword($user_password_new, $user_password_repeat)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// otherwise, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the username
|
||||
*
|
||||
* @param $user_name
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateUserName($user_name)
|
||||
{
|
||||
if (empty($user_name)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_FIELD_EMPTY'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// if username is too short (2), too long (64) or does not fit the pattern (aZ09)
|
||||
if (!preg_match('/^[a-zA-Z0-9]{2,64}$/', $user_name)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_DOES_NOT_FIT_PATTERN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email
|
||||
*
|
||||
* @param $user_email
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateUserEmail($user_email)
|
||||
{
|
||||
if (empty($user_email)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_FIELD_EMPTY'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate the email with PHP's internal filter
|
||||
// side-fact: Max length seems to be 254 chars
|
||||
// @see http://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address
|
||||
if (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password
|
||||
*
|
||||
* @param $user_password_new
|
||||
* @param $user_password_repeat
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateUserPassword($user_password_new, $user_password_repeat)
|
||||
{
|
||||
if (empty($user_password_new) OR empty($user_password_repeat)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_FIELD_EMPTY'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user_password_new !== $user_password_repeat) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_REPEAT_WRONG'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($user_password_new) < 6) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_PASSWORD_TOO_SHORT'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the new user's data to the database
|
||||
*
|
||||
* @param $user_name
|
||||
* @param $user_password_hash
|
||||
* @param $user_email
|
||||
* @param $user_creation_timestamp
|
||||
* @param $user_activation_hash
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function writeNewUserToDatabase($user_name, $user_password_hash, $user_email, $user_creation_timestamp, $user_activation_hash)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
// write new users data into database
|
||||
$sql = "INSERT INTO users (user_name, user_password_hash, user_email, user_creation_timestamp, user_activation_hash, user_provider_type)
|
||||
VALUES (:user_name, :user_password_hash, :user_email, :user_creation_timestamp, :user_activation_hash, :user_provider_type)";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':user_name' => $user_name,
|
||||
':user_password_hash' => $user_password_hash,
|
||||
':user_email' => $user_email,
|
||||
':user_creation_timestamp' => $user_creation_timestamp,
|
||||
':user_activation_hash' => $user_activation_hash,
|
||||
':user_provider_type' => 'DEFAULT'));
|
||||
$count = $query->rowCount();
|
||||
if ($count == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the user from users table. Currently used to rollback a registration when verification mail sending
|
||||
* was not successful.
|
||||
*
|
||||
* @param $user_id
|
||||
*/
|
||||
public static function rollbackRegistrationByUserId($user_id)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("DELETE FROM users WHERE user_id = :user_id");
|
||||
$query->execute(array(':user_id' => $user_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the verification email (to confirm the account).
|
||||
* The construction of the mail $body looks weird at first, but it's really just a simple string.
|
||||
*
|
||||
* @param int $user_id user's id
|
||||
* @param string $user_email user's email
|
||||
* @param string $user_activation_hash user's mail verification hash string
|
||||
*
|
||||
* @return boolean gives back true if mail has been sent, gives back false if no mail could been sent
|
||||
*/
|
||||
public static function sendVerificationEmail($user_id, $user_email, $user_activation_hash)
|
||||
{
|
||||
$body = Config::get('EMAIL_VERIFICATION_CONTENT') . Config::get('URL') . Config::get('EMAIL_VERIFICATION_URL')
|
||||
. '/' . urlencode($user_id) . '/' . urlencode($user_activation_hash);
|
||||
|
||||
$mail = new Mail;
|
||||
$mail_sent = $mail->sendMail($user_email, Config::get('EMAIL_VERIFICATION_FROM_EMAIL'),
|
||||
Config::get('EMAIL_VERIFICATION_FROM_NAME'), Config::get('EMAIL_VERIFICATION_SUBJECT'), $body
|
||||
);
|
||||
|
||||
if ($mail_sent) {
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_VERIFICATION_MAIL_SENDING_SUCCESSFUL'));
|
||||
return true;
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_VERIFICATION_MAIL_SENDING_ERROR') . $mail->getError() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks the email/verification code combination and set the user's activation status to true in the database
|
||||
*
|
||||
* @param int $user_id user id
|
||||
* @param string $user_activation_verification_code verification token
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function verifyNewUser($user_id, $user_activation_verification_code)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "UPDATE users SET user_active = 1, user_activation_hash = NULL
|
||||
WHERE user_id = :user_id AND user_activation_hash = :user_activation_hash LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':user_id' => $user_id, ':user_activation_hash' => $user_activation_verification_code));
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_ACCOUNT_ACTIVATION_SUCCESSFUL'));
|
||||
return true;
|
||||
}
|
||||
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_ACTIVATION_FAILED'));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,331 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* UserModel
|
||||
* Handles all the PUBLIC profile stuff. This is not for getting data of the logged in user, it's more for handling
|
||||
* data of all the other users. Useful for display profile information, creating user lists etc.
|
||||
*/
|
||||
class UserModel
|
||||
{
|
||||
/**
|
||||
* Gets an array that contains all the users in the database. The array's keys are the user ids.
|
||||
* Each array element is an object, containing a specific user's data.
|
||||
* The avatar line is built using Ternary Operators, have a look here for more:
|
||||
* @see http://davidwalsh.name/php-shorthand-if-else-ternary-operators
|
||||
*
|
||||
* @return array The profiles of all users
|
||||
*/
|
||||
public static function getPublicProfilesOfAllUsers()
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "SELECT user_id, user_name, user_email, user_active, user_has_avatar FROM users";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute();
|
||||
|
||||
$all_users_profiles = array();
|
||||
|
||||
foreach ($query->fetchAll() as $user) {
|
||||
$all_users_profiles[$user->user_id] = new stdClass();
|
||||
$all_users_profiles[$user->user_id]->user_id = $user->user_id;
|
||||
$all_users_profiles[$user->user_id]->user_name = $user->user_name;
|
||||
$all_users_profiles[$user->user_id]->user_email = $user->user_email;
|
||||
$all_users_profiles[$user->user_id]->user_active = $user->user_active;
|
||||
$all_users_profiles[$user->user_id]->user_avatar_link = (Config::get('USE_GRAVATAR') ? AvatarModel::getGravatarLinkByEmail($user->user_email) : AvatarModel::getPublicAvatarFilePathOfUser($user->user_has_avatar, $user->user_id));
|
||||
}
|
||||
|
||||
return $all_users_profiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a user's profile data, according to the given $user_id
|
||||
* @param int $user_id The user's id
|
||||
* @return mixed The selected user's profile
|
||||
*/
|
||||
public static function getPublicProfileOfUser($user_id)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "SELECT user_id, user_name, user_email, user_active, user_has_avatar
|
||||
FROM users WHERE user_id = :user_id LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
$query->execute(array(':user_id' => $user_id));
|
||||
|
||||
$user = $query->fetch();
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
if (Config::get('USE_GRAVATAR')) {
|
||||
$user->user_avatar_link = AvatarModel::getGravatarLinkByEmail($user->user_email);
|
||||
} else {
|
||||
$user->user_avatar_link = AvatarModel::getPublicAvatarFilePathOfUser($user->user_has_avatar, $user->user_id);
|
||||
}
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USER_DOES_NOT_EXIST'));
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user_name_or_email
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getUserDataByUserNameOrEmail($user_name_or_email)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("SELECT user_id, user_name, user_email FROM users
|
||||
WHERE (user_name = :user_name_or_email OR user_email = :user_name_or_email)
|
||||
AND user_provider_type = :provider_type LIMIT 1");
|
||||
$query->execute(array(':user_name_or_email' => $user_name_or_email, ':provider_type' => 'DEFAULT'));
|
||||
|
||||
return $query->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a username is already taken
|
||||
*
|
||||
* @param $user_name string username
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function doesUsernameAlreadyExist($user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("SELECT user_id FROM users WHERE user_name = :user_name LIMIT 1");
|
||||
$query->execute(array(':user_name' => $user_name));
|
||||
if ($query->rowCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a email is already used
|
||||
*
|
||||
* @param $user_email string email
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function doesEmailAlreadyExist($user_email)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("SELECT user_id FROM users WHERE user_email = :user_email LIMIT 1");
|
||||
$query->execute(array(':user_email' => $user_email));
|
||||
if ($query->rowCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes new username to database
|
||||
*
|
||||
* @param $user_id int user id
|
||||
* @param $new_user_name string new username
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveNewUserName($user_id, $new_user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("UPDATE users SET user_name = :user_name WHERE user_id = :user_id LIMIT 1");
|
||||
$query->execute(array(':user_name' => $new_user_name, ':user_id' => $user_id));
|
||||
if ($query->rowCount() == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes new email address to database
|
||||
*
|
||||
* @param $user_id int user id
|
||||
* @param $new_user_email string new email address
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveNewEmailAddress($user_id, $new_user_email)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("UPDATE users SET user_email = :user_email WHERE user_id = :user_id LIMIT 1");
|
||||
$query->execute(array(':user_email' => $new_user_email, ':user_id' => $user_id));
|
||||
$count = $query->rowCount();
|
||||
if ($count == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the user's name, provided in the editing form
|
||||
*
|
||||
* @param $new_user_name string The new username
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function editUserName($new_user_name)
|
||||
{
|
||||
// new username same as old one ?
|
||||
if ($new_user_name == Session::get('user_name')) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_SAME_AS_OLD_ONE'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// username cannot be empty and must be azAZ09 and 2-64 characters
|
||||
if (!preg_match("/^[a-zA-Z0-9]{2,64}$/", $new_user_name)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_DOES_NOT_FIT_PATTERN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// clean the input, strip usernames longer than 64 chars (maybe fix this ?)
|
||||
$new_user_name = substr(strip_tags($new_user_name), 0, 64);
|
||||
|
||||
// check if new username already exists
|
||||
if (UserModel::doesUsernameAlreadyExist($new_user_name)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_ALREADY_TAKEN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$status_of_action = UserModel::saveNewUserName(Session::get('user_id'), $new_user_name);
|
||||
if ($status_of_action) {
|
||||
Session::set('user_name', $new_user_name);
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_USERNAME_CHANGE_SUCCESSFUL'));
|
||||
return true;
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_UNKNOWN_ERROR'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the user's email
|
||||
*
|
||||
* @param $new_user_email
|
||||
*
|
||||
* @return bool success status
|
||||
*/
|
||||
public static function editUserEmail($new_user_email)
|
||||
{
|
||||
// email provided ?
|
||||
if (empty($new_user_email)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_FIELD_EMPTY'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if new email is same like the old one
|
||||
if ($new_user_email == Session::get('user_email')) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_SAME_AS_OLD_ONE'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// user's email must be in valid email format, also checks the length
|
||||
// @see http://stackoverflow.com/questions/21631366/php-filter-validate-email-max-length
|
||||
// @see http://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address
|
||||
if (!filter_var($new_user_email, FILTER_VALIDATE_EMAIL)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// strip tags, just to be sure
|
||||
$new_user_email = substr(strip_tags($new_user_email), 0, 254);
|
||||
|
||||
// check if user's email already exists
|
||||
if (UserModel::doesEmailAlreadyExist($new_user_email)) {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_USER_EMAIL_ALREADY_TAKEN'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// write to database, if successful ...
|
||||
// ... then write new email to session, Gravatar too (as this relies to the user's email address)
|
||||
if (UserModel::saveNewEmailAddress(Session::get('user_id'), $new_user_email)) {
|
||||
Session::set('user_email', $new_user_email);
|
||||
Session::set('user_gravatar_image_url', AvatarModel::getGravatarLinkByEmail($new_user_email));
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_EMAIL_CHANGE_SUCCESSFUL'));
|
||||
return true;
|
||||
}
|
||||
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_UNKNOWN_ERROR'));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user's id
|
||||
*
|
||||
* @param $user_name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getUserIdByUsername($user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "SELECT user_id FROM users WHERE user_name = :user_name AND user_provider_type = :provider_type LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
|
||||
// DEFAULT is the marker for "normal" accounts (that have a password etc.)
|
||||
// There are other types of accounts that don't have passwords etc. (FACEBOOK)
|
||||
$query->execute(array(':user_name' => $user_name, ':provider_type' => 'DEFAULT'));
|
||||
|
||||
// return one row (we only have one result or nothing)
|
||||
return $query->fetch()->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user's data
|
||||
*
|
||||
* @param $user_name string User's name
|
||||
*
|
||||
* @return mixed Returns false if user does not exist, returns object with user's data when user exists
|
||||
*/
|
||||
public static function getUserDataByUsername($user_name)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$sql = "SELECT user_id, user_name, user_email, user_password_hash, user_active, user_account_type,
|
||||
user_failed_logins, user_last_failed_login
|
||||
FROM users
|
||||
WHERE (user_name = :user_name OR user_email = :user_name)
|
||||
AND user_provider_type = :provider_type
|
||||
LIMIT 1";
|
||||
$query = $database->prepare($sql);
|
||||
|
||||
// DEFAULT is the marker for "normal" accounts (that have a password etc.)
|
||||
// There are other types of accounts that don't have passwords etc. (FACEBOOK)
|
||||
$query->execute(array(':user_name' => $user_name, ':provider_type' => 'DEFAULT'));
|
||||
|
||||
// return one row (we only have one result or nothing)
|
||||
return $query->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user's data by user's id and a token (used by login-via-cookie process)
|
||||
*
|
||||
* @param $user_id
|
||||
* @param $token
|
||||
*
|
||||
* @return mixed Returns false if user does not exist, returns object with user's data when user exists
|
||||
*/
|
||||
public static function getUserDataByUserIdAndToken($user_id, $token)
|
||||
{
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
// get real token from database (and all other data)
|
||||
$query = $database->prepare("SELECT user_id, user_name, user_email, user_password_hash, user_active,
|
||||
user_account_type, user_has_avatar, user_failed_logins, user_last_failed_login
|
||||
FROM users
|
||||
WHERE user_id = :user_id
|
||||
AND user_remember_me_token = :user_remember_me_token
|
||||
AND user_remember_me_token IS NOT NULL
|
||||
AND user_provider_type = :provider_type LIMIT 1");
|
||||
$query->execute(array(':user_id' => $user_id, ':user_remember_me_token' => $token, ':provider_type' => 'DEFAULT'));
|
||||
|
||||
// return one row (we only have one result or nothing)
|
||||
return $query->fetch();
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class UserRoleModel
|
||||
*
|
||||
* This class contains everything that is related to up- and downgrading accounts.
|
||||
*/
|
||||
class UserRoleModel
|
||||
{
|
||||
/**
|
||||
* Upgrades / downgrades the user's account. Currently it's just the field user_account_type in the database that
|
||||
* can be 1 or 2 (maybe "basic" or "premium"). Put some more complex stuff in here, maybe a pay-process or whatever
|
||||
* you like.
|
||||
*
|
||||
* @param $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function changeUserRole($type)
|
||||
{
|
||||
if (!$type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// save new role to database
|
||||
if (self::saveRoleToDatabase($type)) {
|
||||
Session::add('feedback_positive', Text::get('FEEDBACK_ACCOUNT_TYPE_CHANGE_SUCCESSFUL'));
|
||||
return true;
|
||||
} else {
|
||||
Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_TYPE_CHANGE_FAILED'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the new account type marker to the database and to the session
|
||||
*
|
||||
* @param $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveRoleToDatabase($type)
|
||||
{
|
||||
// if $type is not 1 or 2
|
||||
if (!in_array($type, [1, 2])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$database = DatabaseFactory::getFactory()->getConnection();
|
||||
|
||||
$query = $database->prepare("UPDATE users SET user_account_type = :new_type WHERE user_id = :user_id LIMIT 1");
|
||||
$query->execute(array(
|
||||
':new_type' => $type,
|
||||
':user_id' => Session::get('user_id')
|
||||
));
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
// set account type in session
|
||||
Session::set('user_account_type', $type);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
// get the feedback (they are arrays, to make multiple positive/negative messages possible)
|
||||
$feedback_positive = Session::get('feedback_positive');
|
||||
$feedback_negative = Session::get('feedback_negative');
|
||||
|
||||
// echo out positive messages
|
||||
if (isset($feedback_positive)) {
|
||||
foreach ($feedback_positive as $feedback) {
|
||||
echo '<div class="feedback success">'.$feedback.'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// echo out negative messages
|
||||
if (isset($feedback_negative)) {
|
||||
foreach ($feedback_negative as $feedback) {
|
||||
echo '<div class="feedback error">'.$feedback.'</div>';
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<div class="footer"></div>
|
||||
</div><!-- close class="wrapper" -->
|
||||
|
||||
<!-- the support button on the top right -->
|
||||
<a class="support-button" href="https://affiliates.a2hosting.com/idevaffiliate.php?id=4471&url=579" target="_blank"></a>
|
||||
</body>
|
||||
</html>
|
|
@ -1,66 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- META -->
|
||||
<meta charset="utf-8">
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="<?php echo Config::get('URL'); ?>css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- wrapper, to center website -->
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- logo -->
|
||||
<div class="logo"></div>
|
||||
|
||||
<!-- navigation -->
|
||||
<ul class="navigation">
|
||||
<li <?php if (View::checkForActiveController($filename, "index")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>index/index">Index</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveController($filename, "overview")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>profile/index">Profiles</a>
|
||||
</li>
|
||||
<?php if (Session::userIsLoggedIn()) { ?>
|
||||
<li <?php if (View::checkForActiveController($filename, "dashboard")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>dashboard/index">Dashboard</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveController($filename, "note")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>note/index">My Notes</a>
|
||||
</li>
|
||||
<?php } else { ?>
|
||||
<!-- for not logged in users -->
|
||||
<li <?php if (View::checkForActiveControllerAndAction($filename, "login/index")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/index">Login</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveControllerAndAction($filename, "login/register")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/register">Register</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
<!-- my account -->
|
||||
<ul class="navigation right">
|
||||
<?php if (Session::userIsLoggedIn()) : ?>
|
||||
<li <?php if (View::checkForActiveController($filename, "login")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/showprofile">My Account</a>
|
||||
<ul class="navigation-submenu">
|
||||
<li <?php if (View::checkForActiveController($filename, "login")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/changeUserRole">Change account type</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveController($filename, "login")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/editAvatar">Edit your avatar</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveController($filename, "login")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/editusername">Edit my username</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveController($filename, "login")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/edituseremail">Edit my email</a>
|
||||
</li>
|
||||
<li <?php if (View::checkForActiveController($filename, "login")) { echo ' class="active" '; } ?> >
|
||||
<a href="<?php echo Config::get('URL'); ?>login/logout">Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
|
@ -1,15 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>DashboardController/index</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<h3>What happens here ?</h3>
|
||||
<p>
|
||||
This is an area that's only visible for logged in users. Try to log out, an go to /dashboard/ again. You'll
|
||||
be redirected to /index/ as you are not logged in. You can protect a whole section in your app within the
|
||||
according controller by placing <i>Auth::handleLogin();</i> into the constructor.
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>Page not found</h1>
|
||||
<div class="box">
|
||||
<p class="red-text">This page does not exist.</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>IndexController/index</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<h3>What happens here ?</h3>
|
||||
<p>
|
||||
This is the homepage. As no real URL-route (like /login/register) is provided, the app uses the default
|
||||
controller and the default action, defined in application/config/config.php, by default it's
|
||||
IndexController and index()-method. So, the app will load application/controller/IndexController.php and
|
||||
run index() from that file. Easy. That index()-method (= the action) has just one line of code inside
|
||||
($this->view->render('index/index');) that loads application/view/index/index.php, which is basically
|
||||
this text you are reading right now.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,27 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>LoginController/changePassword</h1>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div class="box">
|
||||
<h2>Set new password</h2>
|
||||
|
||||
<p>FYI: ... Idenfitication process works via password-reset-token (hidden input field)</p>
|
||||
|
||||
<!-- new password form box -->
|
||||
<form method="post" action="<?php echo Config::get('URL'); ?>login/setNewPassword" name="new_password_form">
|
||||
<input type='hidden' name='user_name' value='<?php echo $this->user_name; ?>' />
|
||||
<input type='hidden' name='user_password_reset_hash' value='<?php echo $this->user_password_reset_hash; ?>' />
|
||||
<label for="reset_input_password_new">New password (min. 6 characters)</label>
|
||||
<input id="reset_input_password_new" class="reset_input" type="password"
|
||||
name="user_password_new" pattern=".{6,}" required autocomplete="off" />
|
||||
<label for="reset_input_password_repeat">Repeat new password</label>
|
||||
<input id="reset_input_password_repeat" class="reset_input" type="password"
|
||||
name="user_password_repeat" pattern=".{6,}" required autocomplete="off" />
|
||||
<input type="submit" name="submit_new_password" value="Submit new password" />
|
||||
</form>
|
||||
|
||||
<a href="<?php echo Config::get('URL'); ?>login/index">Back to Login Page</a>
|
||||
</div>
|
||||
</div>
|
|
@ -1,31 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>LoginController/changeUserRole</h1>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div class="box">
|
||||
<h2>Change account type</h2>
|
||||
<p>
|
||||
This page is a basic implementation of the upgrade-process.
|
||||
User can click on that button to upgrade their accounts from
|
||||
"basic account" to "premium account". This script simple offers
|
||||
a click-able button that will upgrade/downgrade the account instantly.
|
||||
In a real world application you would implement something like a
|
||||
pay-process.
|
||||
</p>
|
||||
<p>
|
||||
Please note: This whole process has been renamed from AccountType (v3.0) to UserRole (v3.1).
|
||||
</p>
|
||||
|
||||
<h2>Currently your account type is: <?php echo Session::get('user_account_type'); ?></h2>
|
||||
<!-- basic implementation for two account types: type 1 and type 2 -->
|
||||
<form action="<?php echo Config::get('URL'); ?>login/changeUserRole_action" method="post">
|
||||
<?php if (Session::get('user_account_type') == 1) { ?>
|
||||
<input type="submit" name="user_account_upgrade" value="Upgrade my account (to Premium User)" />
|
||||
<?php } else if (Session::get('user_account_type') == 2) { ?>
|
||||
<input type="submit" name="user_account_downgrade" value="Downgrade my account (to Basic User)" />
|
||||
<?php } ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,28 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>Edit your avatar</h1>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div class="box">
|
||||
<h3>Upload an Avatar</h3>
|
||||
|
||||
<div class="feedback info">
|
||||
If you still see the old picture after uploading a new one: Hard-Reload the page with F5! Your browser doesn't
|
||||
realize there's a new image as new and old one have the same filename.
|
||||
</div>
|
||||
|
||||
<form action="<?php echo Config::get('URL'); ?>login/uploadAvatar_action" method="post" enctype="multipart/form-data">
|
||||
<label for="avatar_file">Select an avatar image from your hard-disk (will be scaled to 44x44 px, only .jpg currently):</label>
|
||||
<input type="file" name="avatar_file" required />
|
||||
<!-- max size 5 MB (as many people directly upload high res pictures from their digital cameras) -->
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="5000000" />
|
||||
<input type="submit" value="Upload image" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3>Delete your avatar</h3>
|
||||
<p>Click this link to delete your (local) avatar: <a href="<?php echo Config::get('URL'); ?>login/deleteAvatar_action">Delete your avatar</a>
|
||||
</div>
|
||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>LoginController/editUserEmail</h1>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div class="box">
|
||||
<h2>Change your email address</h2>
|
||||
|
||||
<form action="<?php echo Config::get('URL'); ?>login/editUserEmail_action" method="post">
|
||||
<label>
|
||||
New email address: <input type="text" name="user_email" required />
|
||||
</label>
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>LoginController/editUsername</h1>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div class="box">
|
||||
<h2>Change your username</h2>
|
||||
|
||||
<form action="<?php echo Config::get('URL'); ?>login/editUserName_action" method="post">
|
||||
<!-- btw http://stackoverflow.com/questions/774054/should-i-put-input-tag-inside-label-tag -->
|
||||
<label>
|
||||
New username: <input type="text" name="user_name" required />
|
||||
</label>
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,34 +0,0 @@
|
|||
<div class="container">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div class="login-page-box">
|
||||
<div class="table-wrapper">
|
||||
|
||||
<!-- login box on left side -->
|
||||
<div class="login-box">
|
||||
<h2>Login here</h2>
|
||||
<form action="<?php echo Config::get('URL'); ?>login/login" method="post">
|
||||
<input type="text" name="user_name" placeholder="Username or email" required />
|
||||
<input type="password" name="user_password" placeholder="Password" required />
|
||||
<label for="set_remember_me_cookie" class="remember-me-label">
|
||||
<input type="checkbox" name="set_remember_me_cookie" class="remember-me-checkbox" />
|
||||
Remember me for 2 weeks
|
||||
</label>
|
||||
<input type="submit" class="login-submit-button" value="Log in"/>
|
||||
</form>
|
||||
<div class="link-forgot-my-password">
|
||||
<a href="<?php echo Config::get('URL'); ?>login/requestPasswordReset">I forgot my password</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- register box on right side -->
|
||||
<div class="register-box">
|
||||
<h2>No account yet ?</h2>
|
||||
<a href="<?php echo Config::get('URL'); ?>login/register">Register</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,37 +0,0 @@
|
|||
<div class="container">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<!-- login box on left side -->
|
||||
<div class="login-box" style="width: 50%; display: block;">
|
||||
<h2>Register a new account</h2>
|
||||
|
||||
<!-- register form -->
|
||||
<form method="post" action="<?php echo Config::get('URL'); ?>login/register_action">
|
||||
<!-- the user name input field uses a HTML5 pattern check -->
|
||||
<input type="text" pattern="[a-zA-Z0-9]{2,64}" name="user_name" placeholder="Username (letters/numbers, 2-64 chars)" required />
|
||||
<input type="text" name="user_email" placeholder="email address (a real address)" required />
|
||||
<input type="password" name="user_password_new" pattern=".{6,}" placeholder="Password (6+ characters)" required autocomplete="off" />
|
||||
<input type="password" name="user_password_repeat" pattern=".{6,}" required placeholder="Repeat your password" autocomplete="off" />
|
||||
|
||||
<!-- show the captcha by calling the login/showCaptcha-method in the src attribute of the img tag -->
|
||||
<img id="captcha" src="<?php echo Config::get('URL'); ?>login/showCaptcha" />
|
||||
<input type="text" name="captcha" placeholder="Please enter above characters" required />
|
||||
|
||||
<!-- quick & dirty captcha reloader -->
|
||||
<a href="#" style="display: block; font-size: 11px; margin: 5px 0 15px 0; text-align: center"
|
||||
onclick="document.getElementById('captcha').src = '<?php echo Config::get('URL'); ?>login/showCaptcha?' + Math.random(); return false">Reload Captcha</a>
|
||||
|
||||
<input type="submit" value="Register" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<p style="display: block; font-size: 11px; color: #999;">
|
||||
Please note: This captcha will be generated when the img tag requests the captcha-generation
|
||||
(= a real image) from YOURURL/login/showcaptcha. As this is a client-side triggered request, a
|
||||
$_SESSION["captcha"] dump will not show the captcha characters. The captcha generation
|
||||
happens AFTER the request that generates THIS page has been finished.
|
||||
</p>
|
||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>Request a password reset</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<!-- request password reset form box -->
|
||||
<form method="post" action="<?php echo Config::get('URL'); ?>login/requestPasswordReset_action">
|
||||
<label>
|
||||
Enter your username or email and you'll get a mail with instructions:
|
||||
<input type="text" name="user_name_or_email" required />
|
||||
</label>
|
||||
<input type="submit" value="Send me a password-reset mail" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -1,21 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>LoginController/showProfile</h1>
|
||||
|
||||
<div class="box">
|
||||
<h2>Your profile</h2>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<div>Your username: <?= $this->user_name; ?></div>
|
||||
<div>Your email: <?= $this->user_email; ?></div>
|
||||
<div>Your avatar image:
|
||||
<?php if (Config::get('USE_GRAVATAR')) { ?>
|
||||
Your gravatar pic (on gravatar.com): <img src='<?= $this->user_gravatar_image_url; ?>' />
|
||||
<?php } else { ?>
|
||||
Your avatar pic (saved locally): <img src='<?= $this->user_avatar_file; ?>' />
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div>Your account type is: <?= $this->user_account_type; ?></div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,12 +0,0 @@
|
|||
<div class="container">
|
||||
|
||||
<h1>Verification</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<a href="<?php echo Config::get('URL'); ?>">Go back to home page</a>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -1,22 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>NoteController/edit/:note_id</h1>
|
||||
|
||||
<div class="box">
|
||||
<h2>Edit a note</h2>
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<?php if ($this->note) { ?>
|
||||
<form method="post" action="<?php echo Config::get('URL'); ?>note/editSave">
|
||||
<label>Change text of note: </label>
|
||||
<!-- we use htmlentities() here to prevent user input with " etc. break the HTML -->
|
||||
<input type="hidden" name="note_id" value="<?php echo htmlentities($this->note->note_id); ?>" />
|
||||
<input type="text" name="note_text" value="<?php echo htmlentities($this->note->note_text); ?>" />
|
||||
<input type="submit" value='Change' />
|
||||
</form>
|
||||
<?php } else { ?>
|
||||
<p>This note does not exist.</p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
|
@ -1,43 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>NoteController/index</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<h3>What happens here ?</h3>
|
||||
<p>
|
||||
This is just a simple CRUD implementation. Creating, reading, updating and deleting things.
|
||||
</p>
|
||||
<p>
|
||||
<form method="post" action="<?php echo Config::get('URL');?>note/create">
|
||||
<label>Text of new note: </label><input type="text" name="note_text" />
|
||||
<input type="submit" value='Create this note' autocomplete="off" />
|
||||
</form>
|
||||
</p>
|
||||
|
||||
<?php if ($this->notes) { ?>
|
||||
<table class="note-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Id</td>
|
||||
<td>Note</td>
|
||||
<td>EDIT</td>
|
||||
<td>DELETE</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($this->notes as $key => $value) { ?>
|
||||
<tr>
|
||||
<td><?= htmlentities($value->note_text); ?></td>
|
||||
<td><a href="<?= Config::get('URL') . 'note/edit/' . $value->note_id; ?>">Edit</a></td>
|
||||
<td><a href="<?= Config::get('URL') . 'note/delete/' . $value->note_id; ?>">Delete</a></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php } else { ?>
|
||||
<div>No notes yet. Create some !</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
|
@ -1,44 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>ProfileController/index</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<h3>What happens here ?</h3>
|
||||
<div>
|
||||
This controller/action/view shows a list of all users in the system. You could use the underlying code to
|
||||
build things that use profile information of one or multiple/all users.
|
||||
</div>
|
||||
<div>
|
||||
<table class="overview-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Id</td>
|
||||
<td>Avatar</td>
|
||||
<td>Username</td>
|
||||
<td>User's email</td>
|
||||
<td>Activated ?</td>
|
||||
<td>Link to user's profile</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php foreach ($this->users as $user) { ?>
|
||||
<tr class="<?= ($user->user_active == 0 ? 'inactive' : 'active'); ?>">
|
||||
<td><?= $user->user_id; ?></td>
|
||||
<td class="avatar">
|
||||
<?php if (isset($user->user_avatar_link)) { ?>
|
||||
<img src="<?= $user->user_avatar_link; ?>" />
|
||||
<?php } ?>
|
||||
</td>
|
||||
<td><?= $user->user_name; ?></td>
|
||||
<td><?= $user->user_email; ?></td>
|
||||
<td><?= ($user->user_active == 0 ? 'No' : 'Yes'); ?></td>
|
||||
<td>
|
||||
<a href="<?= Config::get('URL') . 'profile/showProfile/' . $user->user_id; ?>">Profile</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,41 +0,0 @@
|
|||
<div class="container">
|
||||
<h1>ProfileController/showProfile/:id</h1>
|
||||
<div class="box">
|
||||
|
||||
<!-- echo out the system feedback (error and success messages) -->
|
||||
<?php $this->renderFeedbackMessages(); ?>
|
||||
|
||||
<h3>What happens here ?</h3>
|
||||
<div>This controller/action/view shows all public information about a certain user.</div>
|
||||
|
||||
<?php if ($this->user) { ?>
|
||||
<div>
|
||||
<table class="overview-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Id</td>
|
||||
<td>Avatar</td>
|
||||
<td>Username</td>
|
||||
<td>User's email</td>
|
||||
<td>Activated ?</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="<?= ($this->user->user_active == 0 ? 'inactive' : 'active'); ?>">
|
||||
<td><?= $this->user->user_id; ?></td>
|
||||
<td class="avatar">
|
||||
<?php if (isset($this->user->user_avatar_link)) { ?>
|
||||
<img src="<?= $this->user->user_avatar_link; ?>" />
|
||||
<?php } ?>
|
||||
</td>
|
||||
<td><?= $this->user->user_name; ?></td>
|
||||
<td><?= $this->user->user_email; ?></td>
|
||||
<td><?= ($this->user->user_active == 0 ? 'No' : 'Yes'); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"name": "panique/huge",
|
||||
"type": "project",
|
||||
"description": "A full-feature user authentication / login system embedded into a simple but powerful MVC framework structure",
|
||||
"keywords": ["login", "auth", "user", "authentication", "mvc", "membership"],
|
||||
"homepage": "https://github.com/panique/huge",
|
||||
"license": "MIT",
|
||||
"require-dev": {
|
||||
"php": ">=5.5.0",
|
||||
"phpmailer/phpmailer": "~5.2",
|
||||
"gregwar/captcha": "~1.0.12",
|
||||
"phpunit/phpunit": "~4.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "": ["application/core/", "application/model/"] }
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
# Necessary to prevent problems when using a controller named "index" and having a root index.php
|
||||
# more here: http://httpd.apache.org/docs/2.2/content-negotiation.html
|
||||
Options -MultiViews
|
||||
|
||||
# Activates URL rewriting (like myproject.com/controller/action/1/2/3)
|
||||
RewriteEngine On
|
||||
|
||||
# Prevent people from looking directly into folders
|
||||
Options -Indexes
|
||||
|
||||
# If the following conditions are true, then rewrite the URL:
|
||||
# If the requested filename is not a directory,
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
# and if the requested filename is not a regular file that exists,
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
# and if the requested filename is not a symbolic link,
|
||||
RewriteCond %{REQUEST_FILENAME} !-l
|
||||
# then rewrite the URL in the following way:
|
||||
# Take the whole request filename and provide it as the value of a
|
||||
# "url" query parameter to index.php. Append any query string from
|
||||
# the original URL as further query parameters (QSA), and stop
|
||||
# processing this .htaccess file (L).
|
||||
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
|
|
@ -1,7 +0,0 @@
|
|||
# TODO is this really safe ?
|
||||
# this disallows direct access to the folder listing
|
||||
# and disallows access to any executables files (that users may upload)
|
||||
# the script allows only .jpg/.png uploads, but we never know...
|
||||
Options -Indexes
|
||||
Options -ExecCGI
|
||||
AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi
|
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
File diff suppressed because one or more lines are too long
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* A super-simple user-authentication solution, embedded into a small framework.
|
||||
*
|
||||
* HUGE
|
||||
*
|
||||
* @link https://github.com/panique/huge
|
||||
* @license http://opensource.org/licenses/MIT MIT License
|
||||
*/
|
||||
|
||||
// auto-loading the classes (currently only from application/libs) via Composer's PSR-4 auto-loader
|
||||
// later it might be useful to use a namespace here, but for now let's keep it as simple as possible
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
// start our application
|
||||
new Application();
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ConfigTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/*
|
||||
* Create fake values, necessary to run the tests
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$_SERVER['HTTP_HOST'] = 'localhost';
|
||||
$_SERVER['SCRIPT_NAME'] = 'index.php';
|
||||
Config::$config = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset everything
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
putenv('APPLICATION_ENV=');
|
||||
Config::$config = null;
|
||||
}
|
||||
|
||||
public function testGetDefaultEnvironment()
|
||||
{
|
||||
// fake application constants
|
||||
putenv('APPLICATION_ENV=development');
|
||||
|
||||
// call for environment should return "development"
|
||||
$this->assertEquals('index', Config::get('DEFAULT_ACTION'));
|
||||
}
|
||||
|
||||
public function testGetFailingEnvironment()
|
||||
{
|
||||
// fake application constants
|
||||
putenv('APPLICATION_ENV=foobar');
|
||||
|
||||
// call for environment should return false because config.foobar.php does not exist
|
||||
$this->assertEquals(false, Config::get('DEFAULT_ACTION'));
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
class EnvironmentTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetDefault()
|
||||
{
|
||||
// call for environment should return "development"
|
||||
$this->assertEquals('development', Environment::get());
|
||||
}
|
||||
|
||||
public function testGetDevelopment()
|
||||
{
|
||||
putenv('APPLICATION_ENV=development');
|
||||
// call for environment should return "development"
|
||||
$this->assertEquals('development', Environment::get());
|
||||
}
|
||||
|
||||
public function testGetProduction()
|
||||
{
|
||||
putenv('APPLICATION_ENV=production');
|
||||
$this->assertEquals('production', Environment::get());
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
class RequestTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testPost()
|
||||
{
|
||||
$_POST["test"] = 22;
|
||||
$this->assertEquals(22, Request::post('test'));
|
||||
$this->assertEquals(null, Request::post('not_existing_key'));
|
||||
|
||||
// test trim & strip_tags: Method is used with second argument "true", triggering a cleaning of the input
|
||||
$_POST["attacker_string"] = ' <script>alert("yo!");</script> ';
|
||||
$this->assertEquals('alert("yo!");', Request::post('attacker_string', true));
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$_GET["test"] = 33;
|
||||
$this->assertEquals(33, Request::get('test'));
|
||||
$this->assertEquals(null, Request::get('not_existing_key'));
|
||||
}
|
||||
|
||||
public function testCookie()
|
||||
{
|
||||
$_COOKIE["test"] = 44;
|
||||
$this->assertEquals(44, Request::cookie('test'));
|
||||
$this->assertEquals(null, Request::cookie('not_existing_key'));
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
class TextTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* When argument is existing key, then existing value should be returned
|
||||
*/
|
||||
public function testGet()
|
||||
{
|
||||
$this->assertEquals('Password was wrong.', Text::get('FEEDBACK_PASSWORD_WRONG'));
|
||||
}
|
||||
|
||||
/**
|
||||
* When argument is null, should return null
|
||||
*/
|
||||
public function testGetWithNullKey()
|
||||
{
|
||||
$this->assertEquals(null, Text::get(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* When key does not exist in text data file, should return null
|
||||
*/
|
||||
public function testGetWithNonExistingKey()
|
||||
{
|
||||
$this->assertEquals(null, Text::get('XXX'));
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="../vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false">
|
||||
<testsuites>
|
||||
<testsuite name="Core Suite">
|
||||
<directory>./core/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
|
@ -1,7 +0,0 @@
|
|||
<VirtualHost *:80>
|
||||
DocumentRoot "%TRAVIS_BUILD_DIR%/public"
|
||||
<Directory "%TRAVIS_BUILD_DIR%/public">
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
</VirtualHost>
|
Binary file not shown.
|
@ -1,46 +0,0 @@
|
|||
ServerTokens Prod
|
||||
ServerSignature Off
|
||||
|
||||
TraceEnable Off
|
||||
|
||||
ServerName sevppdlmp01.nexen.net
|
||||
ServerRoot /etc/apache2
|
||||
PidFile ${APACHE_PID_FILE}
|
||||
Timeout 300
|
||||
KeepAlive Off
|
||||
MaxKeepAliveRequests 100
|
||||
KeepAliveTimeout 15
|
||||
LimitRequestFieldSize 8190
|
||||
|
||||
User www-data
|
||||
Group www-data
|
||||
|
||||
AccessFileName .htaccess
|
||||
<FilesMatch "^\.ht">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
<Directory />
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
</Directory>
|
||||
|
||||
HostnameLookups Off
|
||||
LogLevel warn
|
||||
EnableSendfile On
|
||||
Include "/etc/apache2/mods-enabled/*.load"
|
||||
Include "/etc/apache2/mods-enabled/*.conf"
|
||||
Include "/etc/apache2/ports.conf"
|
||||
|
||||
LogFormat "%{X-Forwarded-For}i %a %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %b %D %T %P %V:%p" syslog
|
||||
CustomLog "|/bin/sh -c 'logger -p local7.info -t apache_access_log'" syslog
|
||||
ErrorLog "|/bin/sh -c 'logger -p local7.err -t apache_error_log'"
|
||||
IncludeOptional "/etc/apache2/conf.d/*.conf"
|
||||
IncludeOptional "/etc/apache2/sites-enabled/*"
|
||||
|
||||
## Settings debugging information in headers.
|
||||
SetEnvIf Remote_Addr 127.0.0.1 DEBUG
|
||||
<IfModule mod_headers.c>
|
||||
Header set X-Apache-Server-ID "sevppdlmp01" env=DEBUG
|
||||
</IfModule>
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# Read the documentation before enabling AddDefaultCharset.
|
||||
# In general, it is only a good idea if you know that all your files
|
||||
# have this encoding. It will override any encoding given in the files
|
||||
# in meta http-equiv or xml encoding tags.
|
||||
|
||||
#AddDefaultCharset UTF-8
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
|
@ -1,5 +0,0 @@
|
|||
Alias /javascript /usr/share/javascript/
|
||||
|
||||
<Directory "/usr/share/javascript/">
|
||||
Options FollowSymLinks MultiViews
|
||||
</Directory>
|
|
@ -1,81 +0,0 @@
|
|||
# Customizable error responses come in three flavors:
|
||||
# 1) plain text
|
||||
# 2) local redirects
|
||||
# 3) external redirects
|
||||
#
|
||||
# Some examples:
|
||||
#ErrorDocument 500 "The server made a boo boo."
|
||||
#ErrorDocument 404 /missing.html
|
||||
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
|
||||
#ErrorDocument 402 http://www.example.com/subscription_info.html
|
||||
#
|
||||
|
||||
#
|
||||
# Putting this all together, we can internationalize error responses.
|
||||
#
|
||||
# We use Alias to redirect any /error/HTTP_<error>.html.var response to
|
||||
# our collection of by-error message multi-language collections. We use
|
||||
# includes to substitute the appropriate text.
|
||||
#
|
||||
# You can modify the messages' appearance without changing any of the
|
||||
# default HTTP_<error>.html.var files by adding the line:
|
||||
#
|
||||
#Alias /error/include/ "/your/include/path/"
|
||||
#
|
||||
# which allows you to create your own set of files by starting with the
|
||||
# /usr/share/apache2/error/include/ files and copying them to /your/include/path/,
|
||||
# even on a per-VirtualHost basis. If you include the Alias in the global server
|
||||
# context, is has to come _before_ the 'Alias /error/ ...' line.
|
||||
#
|
||||
# The default include files will display your Apache version number and your
|
||||
# ServerAdmin email address regardless of the setting of ServerSignature.
|
||||
#
|
||||
# WARNING: The configuration below will NOT work out of the box if you have a
|
||||
# SetHandler directive in a <Location /> context somewhere. Adding
|
||||
# the following three lines AFTER the <Location /> context should
|
||||
# make it work in most cases:
|
||||
# <Location /error/>
|
||||
# SetHandler none
|
||||
# </Location>
|
||||
#
|
||||
# The internationalized error documents require mod_alias, mod_include
|
||||
# and mod_negotiation. To activate them, uncomment the following 37 lines.
|
||||
|
||||
#<IfModule mod_negotiation.c>
|
||||
# <IfModule mod_include.c>
|
||||
# <IfModule mod_alias.c>
|
||||
#
|
||||
# Alias /error/ "/usr/share/apache2/error/"
|
||||
#
|
||||
# <Directory "/usr/share/apache2/error">
|
||||
# Options IncludesNoExec
|
||||
# AddOutputFilter Includes html
|
||||
# AddHandler type-map var
|
||||
# Order allow,deny
|
||||
# Allow from all
|
||||
# LanguagePriority en cs de es fr it nl sv pt-br ro
|
||||
# ForceLanguagePriority Prefer Fallback
|
||||
# </Directory>
|
||||
#
|
||||
# ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
|
||||
# ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
|
||||
# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
|
||||
# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
|
||||
# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
|
||||
# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
|
||||
# ErrorDocument 410 /error/HTTP_GONE.html.var
|
||||
# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
|
||||
# ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
|
||||
# ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
|
||||
# ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
|
||||
# ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
|
||||
# ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
|
||||
# ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
|
||||
# ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
|
||||
# ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
|
||||
# ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
|
||||
# </IfModule>
|
||||
# </IfModule>
|
||||
#</IfModule>
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
|
@ -1,4 +0,0 @@
|
|||
# Define an access log for VirtualHosts that don't define their own logfile
|
||||
CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
|
@ -1,72 +0,0 @@
|
|||
#
|
||||
# Disable access to the entire file system except for the directories that
|
||||
# are explicitly allowed later.
|
||||
#
|
||||
# This currently breaks the configurations that come with some web application
|
||||
# Debian packages.
|
||||
#
|
||||
#<Directory />
|
||||
# AllowOverride None
|
||||
# Order Deny,Allow
|
||||
# Deny from all
|
||||
#</Directory>
|
||||
|
||||
|
||||
# Changing the following options will not really affect the security of the
|
||||
# server, but might make attacks slightly more difficult in some cases.
|
||||
|
||||
#
|
||||
# ServerTokens
|
||||
# This directive configures what you return as the Server HTTP response
|
||||
# Header. The default is 'Full' which sends information about the OS-Type
|
||||
# and compiled in modules.
|
||||
# Set to one of: Full | OS | Minimal | Minor | Major | Prod
|
||||
# where Full conveys the most information, and Prod the least.
|
||||
ServerTokens Prod
|
||||
|
||||
#
|
||||
# Optionally add a line containing the server version and virtual host
|
||||
# name to server-generated pages (internal error documents, FTP directory
|
||||
# listings, mod_status and mod_info output etc., but not CGI generated
|
||||
# documents or custom error documents).
|
||||
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
|
||||
# Set to one of: On | Off | EMail
|
||||
ServerSignature Off
|
||||
#ServerSignature On
|
||||
|
||||
#
|
||||
# Allow TRACE method
|
||||
#
|
||||
# Set to "extended" to also reflect the request body (only for testing and
|
||||
# diagnostic purposes).
|
||||
#
|
||||
# Set to one of: On | Off | extended
|
||||
TraceEnable Off
|
||||
#TraceEnable On
|
||||
|
||||
#
|
||||
# Forbid access to version control directories
|
||||
#
|
||||
# If you use version control systems in your document root, you should
|
||||
# probably deny access to their directories. For example, for subversion:
|
||||
#
|
||||
#<DirectoryMatch "/\.svn">
|
||||
# Require all denied
|
||||
#</DirectoryMatch>
|
||||
|
||||
#
|
||||
# Setting this header will prevent MSIE from interpreting files as something
|
||||
# else than declared by the content type in the HTTP headers.
|
||||
# Requires mod_headers to be enabled.
|
||||
#
|
||||
#Header set X-Content-Type-Options: "nosniff"
|
||||
|
||||
#
|
||||
# Setting this header will prevent other sites from embedding pages from this
|
||||
# site as frames. This defends against clickjacking attacks.
|
||||
# Requires mod_headers to be enabled.
|
||||
#
|
||||
#Header set X-Frame-Options: "sameorigin"
|
||||
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
|
@ -1,20 +0,0 @@
|
|||
<IfModule mod_alias.c>
|
||||
<IfModule mod_cgi.c>
|
||||
Define ENABLE_USR_LIB_CGI_BIN
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_cgid.c>
|
||||
Define ENABLE_USR_LIB_CGI_BIN
|
||||
</IfModule>
|
||||
|
||||
<IfDefine ENABLE_USR_LIB_CGI_BIN>
|
||||
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
||||
<Directory "/usr/lib/cgi-bin">
|
||||
AllowOverride None
|
||||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||
Require all granted
|
||||
</Directory>
|
||||
</IfDefine>
|
||||
</IfModule>
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
|
@ -1 +0,0 @@
|
|||
../conf-available/charset.conf
|
|
@ -1 +0,0 @@
|
|||
../conf-available/localized-error-pages.conf
|
|
@ -1 +0,0 @@
|
|||
../conf-available/other-vhosts-access-log.conf
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue