first commit
54
.claude/settings.local.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(powershell -Command \"Compress-Archive -Path ''*'' -DestinationPath ''../../updates/0.20/ver_0.295.zip'' -Force\")",
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(php phpunit.phar:*)",
|
||||
"Bash(powershell -Command \"Compress-Archive -Path ''*'' -DestinationPath ''../../updates/0.20/ver_0.296.zip'' -Force\")",
|
||||
"Bash(ls:*)",
|
||||
"Bash(git -C \"C:/visual studio code/projekty/shopPRO\" rev-parse --show-toplevel)",
|
||||
"Bash(powershell -File:*)",
|
||||
"Bash(git status:*)",
|
||||
"Bash(powershell -Command \"& { Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::OpenRead\\(''updates/0.20/ver_0.296.zip''\\).Entries | ForEach-Object { Write-Output $_.FullName } }\")",
|
||||
"Bash(powershell -Command \"Compress-Archive -Path ''*'' -DestinationPath ''../ver_0.296.zip'' -Force\")",
|
||||
"Bash(powershell -Command \"Add-Type -AssemblyName System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::OpenRead\\(\\(Resolve-Path ''updates/0.20/ver_0.296.zip''\\)\\).Entries.FullName\")",
|
||||
"Bash(powershell -Command \"Compress-Archive -Path ''*'' -DestinationPath ''../ver_0.297.zip'' -Force\")",
|
||||
"Bash(powershell -Command \"Compress-Archive -Path ''*'' -DestinationPath ''../../updates/0.20/ver_0.299.zip'' -Force\")",
|
||||
"Bash(powershell -Command \"Remove-Item -Recurse -Force 'c:/visual studio code/projekty/shopPRO/temp/temp_299'\":*)",
|
||||
"Bash(powershell -Command \"\\(Get-ChildItem ''c:/visual studio code/projekty/shopPRO/updates/0.20/ver_0.299.zip''\\).Length; [System.IO.Compression.ZipFile]::OpenRead\\(''c:/visual studio code/projekty/shopPRO/updates/0.20/ver_0.299.zip''\\).Entries | ForEach-Object { $_.FullName }\")",
|
||||
"Bash(powershell -Command \"Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::OpenRead\\(''c:/visual studio code/projekty/shopPRO/updates/0.20/ver_0.299.zip''\\).Entries | ForEach-Object { $_.FullName }\")",
|
||||
"Bash(unzip:*)",
|
||||
"mcp__serena__find_symbol",
|
||||
"mcp__serena__find_file",
|
||||
"mcp__serena__activate_project",
|
||||
"mcp__serena__check_onboarding_performed",
|
||||
"Bash(tail:*)",
|
||||
"WebFetch(domain:shoppro.project-dc.pl)",
|
||||
"Bash(cd:*)",
|
||||
"mcp__serena__get_symbols_overview",
|
||||
"mcp__serena__search_for_pattern",
|
||||
"mcp__serena__read_file",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && powershell.exe -ExecutionPolicy Bypass -File \"C:/visual studio code/projekty/shopPRO/test.ps1\" 2>&1)",
|
||||
"mcp__serena__replace_content",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && npx sass admin/layout/style-scss/style.scss admin/layout/style-css/style.css --source-map 2>&1)",
|
||||
"Bash(head:*)",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && rm -rf temp/temp_304 && powershell -File \"./build-update.ps1\" -FromTag v0.303 -ToTag v0.304 -ChangelogEntry \"NEW - konfigurowalne limity kwotowe metod platnosci \\(min/max kwota zamowienia\\)\" 2>&1)",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && rm -rf temp/temp_305 && powershell -File \"./build-update.ps1\" -FromTag v0.304 -ToTag v0.305 -ChangelogEntry \"FIX - naprawa kolejnosci atrybutow permutacji, NEW - pasek postepu darmowej dostawy w koszyku\" 2>&1)",
|
||||
"Bash(xxd:*)",
|
||||
"mcp__serena__list_dir",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && powershell -ExecutionPolicy Bypass -File build-update.ps1 -FromTag v0.305 -ToTag v0.306 -ChangelogEntry \"FIX - ukrywanie form dostawy gdy nie ma dostepnych form platnosci\" 2>&1)",
|
||||
"Bash(powershell:*)",
|
||||
"Bash(powershell.exe:*)",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && rm -f updates/0.30/ver_0.304.zip updates/0.30/ver_0.304_manifest.json updates/0.30/ver_0.304_sql.txt updates/0.30/ver_0.304_files.txt && powershell -ExecutionPolicy Bypass -File build-update.ps1 -FromTag v0.303 -ToTag v0.304 -ChangelogEntry \"NEW - konfigurowalne limity kwotowe metod platnosci \\(min/max kwota zamowienia\\)\" 2>&1)",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && rm -f updates/0.30/ver_0.305.zip updates/0.30/ver_0.305_manifest.json updates/0.30/ver_0.305_sql.txt updates/0.30/ver_0.305_files.txt && powershell -ExecutionPolicy Bypass -File build-update.ps1 -FromTag v0.304 -ToTag v0.305 -ChangelogEntry \"FIX - naprawa kolejnosci atrybutow permutacji, NEW - pasek postepu darmowej dostawy w koszyku\" 2>&1)",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && rm -rf temp/temp_305 && powershell -ExecutionPolicy Bypass -File build-update.ps1 -FromTag v0.304 -ToTag v0.305 -ChangelogEntry \"FIX - naprawa kolejnosci atrybutow permutacji, NEW - pasek postepu darmowej dostawy w koszyku\" 2>&1)",
|
||||
"Bash(cd \"/c/visual studio code/projekty/shopPRO\" && rm -rf temp/temp_305 && sleep 2 && powershell -ExecutionPolicy Bypass -Command \"& { \\\\$env:DOTNET_GCServer = 1; & './build-update.ps1' -FromTag v0.304 -ToTag v0.305 -ChangelogEntry 'FIX - naprawa kolejnosci atrybutow permutacji, NEW - pasek postepu darmowej dostawy w koszyku' }\" 2>&1)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(python:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(grep ^<b>ver:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vscode/ftp-kr.sync.cache.json
|
||||
122
.htaccess
Normal file
@@ -0,0 +1,122 @@
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
Options +FollowSymlinks
|
||||
Options -Indexes
|
||||
|
||||
RewriteCond %{REQUEST_METHOD} ^(GET|HEAD)$
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]RewriteCond %{REQUEST_METHOD} ^(GET|HEAD)$
|
||||
RewriteCond %{HTTP_HOST} !^www\. [NC]
|
||||
RewriteRule ^ %{REQUEST_SCHEME}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
RewriteCond %{REQUEST_METHOD} ^(GET|HEAD)$
|
||||
RewriteCond %{REQUEST_URI} !^/admin(/|$) [NC]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} !/$
|
||||
RewriteRule ^(.+)$ %{REQUEST_SCHEME}://%{HTTP_HOST}/$1/ [L,R=301]
|
||||
|
||||
|
||||
ErrorDocument 404 /404.html
|
||||
|
||||
RewriteCond %{REQUEST_URI} !^(.*)/libraries/(.*) [NC]
|
||||
RewriteCond %{REQUEST_URI} !^(.*)/css/(.*) [NC]
|
||||
RewriteRule ^admin/([^/]*)/([^/]*)/(.*)$ admin/index.php?module=$1&action=$2&$3 [L]
|
||||
|
||||
|
||||
RewriteRule ^admin/$ admin/index.php [L]
|
||||
RewriteRule ^wyszukiwarka(|/)$ index.php?search=true&lang=pl [L]
|
||||
RewriteRule ^wersja-tymczasowa(|/)$ index.php?devel=true&lang=pl [L]
|
||||
RewriteRule ^pixieset/(.*)$ index.php?module=articles&action=image&hash=$1 [L]
|
||||
RewriteRule ^pixieset-wszystkie/(.*)$ index.php?module=articles&action=images_download&hash=$1 [L]
|
||||
RewriteRule ^audyt-seo/wynik(|/)$ index.php?module=auditSEO&action=main_view&%{QUERY_STRING} [L]
|
||||
|
||||
RewriteCond %{REQUEST_URI} ^/auditSEO/(.*) [NC]
|
||||
RewriteRule ^([^/]*)/([^/]*)/(.*)$ index.php?module=$1&action=$2&$3 [L]
|
||||
|
||||
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index.php
|
||||
RewriteRule ^ /%1 [R=301,L]
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
|
||||
</IfModule>
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive on
|
||||
ExpiresDefault "access plus 1 year"
|
||||
ExpiresByType text/css "access plus 1 year"
|
||||
ExpiresByType application/json "access plus 0 seconds"
|
||||
ExpiresByType application/xml "access plus 0 seconds"
|
||||
ExpiresByType text/xml "access plus 0 seconds"
|
||||
ExpiresByType image/x-icon "access plus 1 week"
|
||||
ExpiresByType text/x-component "access plus 1 year"
|
||||
ExpiresByType text/html "access plus 0 seconds"
|
||||
ExpiresByType application/javascript "access plus 1 year"
|
||||
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
|
||||
ExpiresByType text/cache-manifest "access plus 0 seconds"
|
||||
ExpiresByType audio/ogg "access plus 1 year"
|
||||
ExpiresByType image/gif "access plus 1 year"
|
||||
ExpiresByType image/jpeg "access plus 1 year"
|
||||
ExpiresByType image/webp "access plus 1 year"
|
||||
ExpiresByType image/png "access plus 1 year"
|
||||
ExpiresByType video/mp4 "access plus 1 year"
|
||||
ExpiresByType video/ogg "access plus 1 year"
|
||||
ExpiresByType video/webm "access plus 1 year"
|
||||
ExpiresByType application/atom+xml "access plus 1 hour"
|
||||
ExpiresByType application/rss+xml "access plus 1 hour"
|
||||
ExpiresByType application/font-woff "access plus 1 year"
|
||||
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
|
||||
ExpiresByType application/x-font-ttf "access plus 1 year"
|
||||
ExpiresByType font/opentype "access plus 1 year"
|
||||
ExpiresByType image/svg+xml "access plus 1 year"
|
||||
</IfModule>
|
||||
<Files *.conf>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
<Files *.log>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
<Files *.ini>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
RewriteRule ^pl/$ index.php?a=change_language&id=pl [L]
|
||||
RewriteRule ^en/$ index.php?a=change_language&id=en [L]
|
||||
|
||||
RewriteRule ^$ index.php?a=page&id=40&lang=pl&%{QUERY_STRING} [L]
|
||||
|
||||
RewriteCond %{REQUEST_URI} ^/home(|/)$
|
||||
RewriteRule ^(.*)$ https://www.cmspro.project-dc.pl/ [R=301,L]
|
||||
RewriteCond %{REQUEST_URI} ^/home/s/1$
|
||||
RewriteRule ^(.*)$ https://www.cmspro.project-dc.pl/ [R=301,L]
|
||||
RewriteCond %{REQUEST_URI} "^/$"
|
||||
RewriteRule ^$ index.php?a=page&id=40&lang=pl [L]
|
||||
|
||||
RewriteRule ^home(|/)$ index.php?a=page&id=40&lang=pl&%{QUERY_STRING} [L]
|
||||
RewriteRule ^home/s/1(|/)$ home [R=301,L]
|
||||
RewriteRule ^home/s/([0-9]+)(|/)$ index.php?a=page&id=40&lang=pl&bs=$1&%{QUERY_STRING} [L]
|
||||
|
||||
RewriteRule ^zdrowie(|/)$ index.php?a=page&id=41&lang=pl&%{QUERY_STRING} [L]
|
||||
RewriteRule ^zdrowie/s/1(|/)$ zdrowie [R=301,L]
|
||||
RewriteRule ^zdrowie/s/([0-9]+)(|/)$ index.php?a=page&id=41&lang=pl&bs=$1&%{QUERY_STRING} [L]
|
||||
|
||||
RewriteRule ^inne(|/)$ index.php?a=page&id=50&lang=pl&%{QUERY_STRING} [L]
|
||||
RewriteRule ^inne/s/1(|/)$ inne [R=301,L]
|
||||
RewriteRule ^inne/s/([0-9]+)(|/)$ index.php?a=page&id=50&lang=pl&bs=$1&%{QUERY_STRING} [L]
|
||||
|
||||
RewriteRule ^udar-mozgu-kluczowe-znaczenie-wczesnej-diagnostyki-i-interwencji-medycznej-1(|/)$ index.php?article=22&lang=pl&%{QUERY_STRING} [L]
|
||||
|
||||
RewriteRule ^en/home(|/)$ index.php?a=page&id=40&lang=en&%{QUERY_STRING} [L]
|
||||
RewriteRule ^en/home/s/1(|/)$ en/home [R=301,L]
|
||||
RewriteRule ^en/home/s/([0-9]+)(|/)$ index.php?a=page&id=40&lang=en&bs=$1&%{QUERY_STRING} [L]
|
||||
|
||||
|
||||
RewriteCond %{QUERY_STRING} !=""
|
||||
RewriteRule tag/tag1(|/) %{REQUEST_URI}? [R=301,L]
|
||||
RewriteRule ^tag/tag1(|/)$ index.php?tag=1 [L]
|
||||
RewriteCond %{QUERY_STRING} !=""
|
||||
RewriteRule tag/tag2(|/) %{REQUEST_URI}? [R=301,L]
|
||||
RewriteRule ^tag/tag2(|/)$ index.php?tag=2 [L]
|
||||
RewriteRule ^oferty-pracy(|/)$ index.php?module=globelusAdverts&action=adverts_list&cp=1&%{QUERY_STRING} [L]
|
||||
RewriteRule ^newsletter/signin$ index.php?module=newsletter&action=signin [L]
|
||||
RewriteRule ^newsletter/confirm/hash=(.*)$ index.php?module=newsletter&action=confirm&hash=$1 [L]
|
||||
RewriteRule ^newsletter/unsubscribe/hash=(.*)$ index.php?module=newsletter&action=unsubscribe&hash=$1 [L]
|
||||
1
.serena/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/cache
|
||||
117
.serena/project.yml
Normal file
@@ -0,0 +1,117 @@
|
||||
# the name by which the project can be referenced within Serena
|
||||
project_name: "cmsPRO"
|
||||
|
||||
|
||||
# list of languages for which language servers are started; choose from:
|
||||
# al bash clojure cpp csharp
|
||||
# csharp_omnisharp dart elixir elm erlang
|
||||
# fortran fsharp go groovy haskell
|
||||
# java julia kotlin lua markdown
|
||||
# matlab nix pascal perl php
|
||||
# php_phpactor powershell python python_jedi r
|
||||
# rego ruby ruby_solargraph rust scala
|
||||
# swift terraform toml typescript typescript_vts
|
||||
# vue yaml zig
|
||||
# (This list may be outdated. For the current list, see values of Language enum here:
|
||||
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
|
||||
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
|
||||
# Note:
|
||||
# - For C, use cpp
|
||||
# - For JavaScript, use typescript
|
||||
# - For Free Pascal/Lazarus, use pascal
|
||||
# Special requirements:
|
||||
# Some languages require additional setup/installations.
|
||||
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
|
||||
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
||||
# The first language is the default language and the respective language server will be used as a fallback.
|
||||
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
||||
languages:
|
||||
- typescript
|
||||
|
||||
# the encoding used by text files in the project
|
||||
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
||||
encoding: "utf-8"
|
||||
|
||||
# whether to use project's .gitignore files to ignore files
|
||||
ignore_all_files_in_gitignore: true
|
||||
|
||||
# list of additional paths to ignore in this project.
|
||||
# Same syntax as gitignore, so you can use * and **.
|
||||
# Note: global ignored_paths from serena_config.yml are also applied additively.
|
||||
ignored_paths: []
|
||||
|
||||
# whether the project is in read-only mode
|
||||
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
||||
# Added on 2025-04-18
|
||||
read_only: false
|
||||
|
||||
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
||||
# Below is the complete list of tools for convenience.
|
||||
# To make sure you have the latest list of tools, and to view their descriptions,
|
||||
# execute `uv run scripts/print_tool_overview.py`.
|
||||
#
|
||||
# * `activate_project`: Activates a project by name.
|
||||
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
||||
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
||||
# * `delete_lines`: Deletes a range of lines within a file.
|
||||
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
||||
# * `execute_shell_command`: Executes a shell command.
|
||||
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
||||
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
||||
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
||||
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
||||
# * `initial_instructions`: Gets the initial instructions for the current project.
|
||||
# Should only be used in settings where the system prompt cannot be set,
|
||||
# e.g. in clients you have no control over, like Claude Desktop.
|
||||
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
||||
# * `insert_at_line`: Inserts content at a given line in a file.
|
||||
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
||||
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
||||
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
||||
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
||||
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
||||
# * `read_file`: Reads a file within the project directory.
|
||||
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
||||
# * `remove_project`: Removes a project from the Serena configuration.
|
||||
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
||||
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
||||
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
||||
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
||||
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
||||
# * `switch_modes`: Activates modes by providing a list of their names
|
||||
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
||||
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
||||
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
||||
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
||||
excluded_tools: []
|
||||
|
||||
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default)
|
||||
included_optional_tools: []
|
||||
|
||||
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
|
||||
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
|
||||
fixed_tools: []
|
||||
|
||||
# list of mode names to that are always to be included in the set of active modes
|
||||
# The full set of modes to be activated is base_modes + default_modes.
|
||||
# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
|
||||
# Otherwise, this setting overrides the global configuration.
|
||||
# Set this to [] to disable base modes for this project.
|
||||
# Set this to a list of mode names to always include the respective modes for this project.
|
||||
base_modes:
|
||||
|
||||
# list of mode names that are to be activated by default.
|
||||
# The full set of modes to be activated is base_modes + default_modes.
|
||||
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
|
||||
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
|
||||
# This setting can, in turn, be overridden by CLI parameters (--mode).
|
||||
default_modes:
|
||||
|
||||
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
||||
# (contrary to the memories, which are loaded on demand).
|
||||
initial_prompt: ""
|
||||
|
||||
# override of the corresponding setting in serena_config.yml, see the documentation there.
|
||||
# If null or missing, the value from the global config is used.
|
||||
symbol_info_budget:
|
||||
56
.updateignore
Normal file
@@ -0,0 +1,56 @@
|
||||
# Dokumentacja (tylko wewnetrzna/deweloperska)
|
||||
*.md
|
||||
docs/
|
||||
CLAUDE.md
|
||||
AGENTS.md
|
||||
|
||||
# Narzedzia deweloperskie
|
||||
.claude/
|
||||
.gitignore
|
||||
.git/
|
||||
tests/
|
||||
phpunit.xml
|
||||
phpunit.phar
|
||||
composer.json
|
||||
composer.lock
|
||||
vendor/
|
||||
test.ps1
|
||||
memory/
|
||||
|
||||
# Infrastruktura aktualizacji (meta, nie runtime)
|
||||
updates/
|
||||
.updateignore
|
||||
build-update.ps1
|
||||
migrations/
|
||||
|
||||
# Pliki konfiguracyjne klienta (wdrazane osobno)
|
||||
config.php
|
||||
.htaccess
|
||||
admin/.htaccess
|
||||
libraries/version.ini
|
||||
|
||||
# Narzedzia serwisowe
|
||||
test.php
|
||||
_backup.php
|
||||
_restore.php
|
||||
restore.php
|
||||
log.txt
|
||||
|
||||
# Pliki uzytkownika (nie nadpisywac)
|
||||
upload/
|
||||
images/
|
||||
templates_user/
|
||||
plugins/
|
||||
|
||||
# Temp / cache / backups
|
||||
temp/
|
||||
backups/
|
||||
cache/
|
||||
cron/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.serena/
|
||||
|
||||
# Cache testow
|
||||
.phpunit.result.cache
|
||||
17
.vscode/ftp-kr.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"host": "host117523.hostido.net.pl",
|
||||
"username": "www@cmspro.project-dc.pl",
|
||||
"password": "aNDCvhA6cnHSQfM24vUE",
|
||||
"remotePath": "/public_html",
|
||||
"protocol": "ftp",
|
||||
"port": 21,
|
||||
"fileNameEncoding": "utf8",
|
||||
"autoUpload": true,
|
||||
"autoDelete": false,
|
||||
"autoDownload": false,
|
||||
"ignoreRemoteModification": true,
|
||||
"ignore": [
|
||||
".git",
|
||||
"/.vscode"
|
||||
]
|
||||
}
|
||||
12
.vscode/sftp.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "host117523.hostido.net.pl",
|
||||
"host": "host117523.hostido.net.pl",
|
||||
"protocol": "ftp",
|
||||
"port": 21,
|
||||
"username": "www@cmspro.project-dc.pl",
|
||||
"password": "aNDCvhA6cnHSQfM24vUE",
|
||||
"remotePath": "/public_html",
|
||||
"uploadOnSave": false,
|
||||
"useTempFile": false,
|
||||
"openSsh": false
|
||||
}
|
||||
50
404.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Błąd 404</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.wrap {
|
||||
width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.logo {
|
||||
width: 300px;
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
#p404 {
|
||||
font-size: 180px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#btn a {
|
||||
color: #eee;
|
||||
font-size: 13px;
|
||||
padding: 5px 10px;
|
||||
background: #5b7fb1;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
#btn a:hover {
|
||||
background: #2E5386;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="logo">
|
||||
<p id="p404">404</p>
|
||||
<p>Przykro nam, żądana strona nie istnieje</p>
|
||||
<p id="btn"><a href="/">Wróć do strony głównej</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
970
PLAN_REFAKTORINGU.md
Normal file
@@ -0,0 +1,970 @@
|
||||
# PLAN REFAKTORINGU cmsPRO
|
||||
|
||||
## Cel
|
||||
|
||||
Przenieść architekturę z shopPRO do cmsPRO:
|
||||
- **Domain-Driven Design** z warstwą `\Domain\` (repozytoria z DI)
|
||||
- **Kontrolery z Dependency Injection** (zamiast statycznych `controls` + `factory`)
|
||||
- **Nowy system aktualizacji** z manifestami JSON, checksumami SHA256, backupami
|
||||
- **Shared utilities** w namespace `\Shared\`
|
||||
- **Testy PHPUnit**
|
||||
- **Automatyczny build paczek** (`build-update.ps1`)
|
||||
|
||||
---
|
||||
|
||||
## STAN OBECNY cmsPRO vs DOCELOWY
|
||||
|
||||
### Obecna architektura (legacy)
|
||||
|
||||
```
|
||||
autoload/
|
||||
├── admin/
|
||||
│ ├── class.Site.php ← Router (statyczne metody, global $mdb)
|
||||
│ ├── controls/ ← 16 kontrolerów (statyczne, global $mdb)
|
||||
│ ├── factory/ ← 15 klas logiki biznesowej (statyczne, global $mdb)
|
||||
│ └── view/ ← 17 klas widoków (statyczne)
|
||||
├── front/
|
||||
│ ├── controls/ ← 4 kontrolery
|
||||
│ ├── factory/ ← 13 klas logiki
|
||||
│ └── view/ ← 8 klas widoków
|
||||
├── class.S.php ← Mega-utility (sesja, cache, email, SEO, token, DOM...)
|
||||
├── class.Tpl.php ← Template engine
|
||||
├── class.Cache.php ← Cache plikowy (gzdeflate + MD5)
|
||||
├── class.Html.php ← Komponenty formularzy HTML
|
||||
├── class.Image.php ← ImageManipulator
|
||||
├── class.Article.php ← Model artykułu z ArrayAccess
|
||||
├── class.Scontainer.php ← Kontenery statyczne z ArrayAccess
|
||||
├── class.Page.php ← Model strony
|
||||
├── class.Mobile_Detect.php ← Detekcja mobilnych
|
||||
└── class.geoplugin.php ← GeoIP
|
||||
```
|
||||
|
||||
### Architektura docelowa (wzór: shopPRO)
|
||||
|
||||
```
|
||||
autoload/
|
||||
├── Domain/ ← NOWE: warstwa domenowa
|
||||
│ ├── Article/
|
||||
│ │ └── ArticleRepository.php
|
||||
│ ├── Banner/
|
||||
│ │ └── BannerRepository.php
|
||||
│ ├── Languages/
|
||||
│ │ └── LanguagesRepository.php
|
||||
│ ├── Layouts/
|
||||
│ │ └── LayoutsRepository.php
|
||||
│ ├── Newsletter/
|
||||
│ │ ├── NewsletterRepository.php
|
||||
│ │ └── NewsletterPreviewRenderer.php
|
||||
│ ├── Pages/
|
||||
│ │ └── PagesRepository.php
|
||||
│ ├── Scontainers/
|
||||
│ │ └── ScontainersRepository.php
|
||||
│ ├── Settings/
|
||||
│ │ └── SettingsRepository.php
|
||||
│ ├── Update/
|
||||
│ │ └── UpdateRepository.php
|
||||
│ ├── User/
|
||||
│ │ └── UserRepository.php
|
||||
│ ├── Author/
|
||||
│ │ └── AuthorRepository.php
|
||||
│ ├── SeoAdditional/
|
||||
│ │ └── SeoAdditionalRepository.php
|
||||
│ ├── Cache/
|
||||
│ │ └── CacheRepository.php
|
||||
│ ├── Email/
|
||||
│ │ └── EmailRepository.php
|
||||
│ └── Backup/
|
||||
│ └── BackupRepository.php
|
||||
├── Shared/ ← NOWE: wspólne utility
|
||||
│ ├── Helpers/
|
||||
│ │ └── Helpers.php ← Refaktor z class.S.php
|
||||
│ ├── Tpl/
|
||||
│ │ └── Tpl.php ← Refaktor z class.Tpl.php
|
||||
│ ├── Cache/
|
||||
│ │ └── CacheHandler.php ← Refaktor z class.Cache.php
|
||||
│ ├── Html/
|
||||
│ │ └── Html.php ← Refaktor z class.Html.php
|
||||
│ ├── Image/
|
||||
│ │ └── ImageManipulator.php ← Refaktor z class.Image.php
|
||||
│ └── Email/
|
||||
│ └── Email.php ← PHPMailer wrapper
|
||||
├── admin/
|
||||
│ ├── App.php ← NOWY: Router + DI container (zamienia Site.php)
|
||||
│ ├── Controllers/ ← NOWE: kontrolery z DI
|
||||
│ │ ├── ArticlesController.php
|
||||
│ │ ├── ArticlesArchiveController.php
|
||||
│ │ ├── AuthorsController.php
|
||||
│ │ ├── BackupsController.php
|
||||
│ │ ├── BannerController.php
|
||||
│ │ ├── EmailsController.php
|
||||
│ │ ├── FilemanagerController.php
|
||||
│ │ ├── LanguagesController.php
|
||||
│ │ ├── LayoutsController.php
|
||||
│ │ ├── NewsletterController.php
|
||||
│ │ ├── PagesController.php
|
||||
│ │ ├── ScontainersController.php
|
||||
│ │ ├── SeoAdditionalController.php
|
||||
│ │ ├── SettingsController.php
|
||||
│ │ ├── UpdateController.php
|
||||
│ │ └── UsersController.php
|
||||
│ ├── controls/ ← USUNĄĆ (po migracji)
|
||||
│ ├── factory/ ← USUNĄĆ (po migracji)
|
||||
│ └── view/ ← USUNĄĆ (po migracji — logic do Controllers)
|
||||
├── front/
|
||||
│ ├── App.php ← NOWY: Router + DI container
|
||||
│ ├── LayoutEngine.php ← NOWY: refaktor z front\view\Site::show()
|
||||
│ ├── Controllers/ ← NOWE: kontrolery z DI
|
||||
│ │ ├── NewsletterController.php
|
||||
│ │ └── SearchController.php (+ ewentualne inne)
|
||||
│ ├── Views/ ← NOWE: statyczne klasy renderujące (z front\view\)
|
||||
│ │ ├── Articles.php
|
||||
│ │ ├── Banners.php
|
||||
│ │ ├── Languages.php
|
||||
│ │ ├── Menu.php
|
||||
│ │ ├── Newsletter.php
|
||||
│ │ ├── Scontainers.php
|
||||
│ │ └── Search.php
|
||||
│ ├── controls/ ← USUNĄĆ (po migracji)
|
||||
│ ├── factory/ ← USUNĄĆ (po migracji)
|
||||
│ └── view/ ← USUNĄĆ (po migracji — do Views/ + LayoutEngine)
|
||||
└── (stare class.*.php) ← USUNĄĆ (po migracji do Shared/)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FAZY REFAKTORINGU
|
||||
|
||||
Każda faza kończy się działającym systemem. Stary i nowy kod koegzystują aż do pełnej migracji.
|
||||
|
||||
---
|
||||
|
||||
## FAZA 0: Przygotowanie infrastruktury
|
||||
|
||||
### 0.1 Aktualizacja autoloadera
|
||||
|
||||
**Obecny autoloader** (index.php, admin/index.php) szuka tylko `class.{Name}.php`:
|
||||
```php
|
||||
$f = 'autoload/' . implode('/', $q) . '/class.' . $c . '.php';
|
||||
```
|
||||
|
||||
**Docelowy** — musi obsługiwać OBE konwencje (fallback PSR-4):
|
||||
```php
|
||||
function __autoload_my_classes($classname) {
|
||||
$q = explode('\\', $classname);
|
||||
$c = array_pop($q);
|
||||
|
||||
// 1. Legacy: class.ClassName.php
|
||||
$f = 'autoload/' . implode('/', $q) . '/class.' . $c . '.php';
|
||||
if (file_exists($f)) { require_once($f); return; }
|
||||
|
||||
// 2. PSR-4: ClassName.php
|
||||
$f = 'autoload/' . implode('/', $q) . '/' . $c . '.php';
|
||||
if (file_exists($f)) require_once($f);
|
||||
}
|
||||
```
|
||||
|
||||
**Pliki do zmiany:**
|
||||
- `index.php` (linia ~3-11)
|
||||
- `admin/index.php` (linia ~15-22, ścieżka `../autoload/`)
|
||||
- `ajax.php` (jeśli ma autoloader)
|
||||
- `admin/ajax.php`
|
||||
- `api.php`
|
||||
- `cron.php`
|
||||
|
||||
### 0.2 Utworzenie katalogów
|
||||
|
||||
```
|
||||
mkdir autoload/Domain
|
||||
mkdir autoload/Shared
|
||||
mkdir autoload/Shared/Helpers
|
||||
mkdir autoload/Shared/Tpl
|
||||
mkdir autoload/Shared/Cache
|
||||
mkdir autoload/Shared/Html
|
||||
mkdir autoload/Shared/Image
|
||||
mkdir autoload/Shared/Email
|
||||
mkdir autoload/admin/Controllers
|
||||
mkdir autoload/front/Controllers
|
||||
mkdir autoload/front/Views
|
||||
mkdir tests
|
||||
mkdir tests/Unit
|
||||
mkdir tests/Unit/Domain
|
||||
mkdir tests/stubs
|
||||
mkdir migrations
|
||||
mkdir docs
|
||||
mkdir backups
|
||||
```
|
||||
|
||||
### 0.3 Konfiguracja PHPUnit
|
||||
|
||||
Skopiować z shopPRO:
|
||||
- `phpunit.xml`
|
||||
- `phpunit.phar`
|
||||
- `test.ps1`
|
||||
- `tests/bootstrap.php`
|
||||
- `composer.json` (sekcja `require-dev`)
|
||||
|
||||
### 0.4 Git tagging — ustalenie punktu startowego
|
||||
|
||||
```bash
|
||||
git tag v1.689 # bieżąca wersja cmsPRO
|
||||
git push origin v1.689
|
||||
```
|
||||
|
||||
Od następnej wersji (1.690) zaczyna się nowy system aktualizacji.
|
||||
|
||||
### 0.5 Utworzenie CLAUDE.md i AGENTS.md
|
||||
|
||||
Skopiować strukturę z shopPRO, dostosować do cmsPRO (brak modułu sklepowego, inne moduły).
|
||||
|
||||
---
|
||||
|
||||
## FAZA 1: Shared Utilities (przeniesienie klas globalnych)
|
||||
|
||||
Kolejność: Helpers → Tpl → Cache → Html → Image → Email.
|
||||
Po każdym kroku starą klasę zostawiamy jako wrapper (deleguje do nowej), żeby nic się nie zepsuło.
|
||||
|
||||
### 1.1 `\Shared\Helpers\Helpers` (z `class.S.php`)
|
||||
|
||||
**Plik:** `autoload/Shared/Helpers/Helpers.php`
|
||||
|
||||
Skopiować WSZYSTKIE metody z `\S` do `\Shared\Helpers\Helpers`:
|
||||
- `get()`, `get_session()`, `set_session()`, `delete_session()`
|
||||
- `alert()`, `set_message()`, `lang()`
|
||||
- `send_email()`, `email_check()`
|
||||
- `seo()`, `noPL()`
|
||||
- `cache_write()`, `cache_read()`, `cache_file_url()`
|
||||
- `htacces()`
|
||||
- `delete_cache()`, `delete_dir()`, `is_empty_dir()`
|
||||
- `date_diff()`, `months()`, `months_short()`
|
||||
- `get_token()`, `is_token_valid()`
|
||||
- DOM manipulation: `suSetHtmlById()`, `suAddHtmlById()`, itd.
|
||||
- `get_version()`, `get_new_version()`
|
||||
- `Pre()`, `json_to_array()`, `is_bot()`, `is_mobile()`
|
||||
- `generate_webp_image()`
|
||||
|
||||
**Stary `class.S.php`** — zamienić na wrapper:
|
||||
```php
|
||||
class S {
|
||||
public static function __callStatic($name, $args) {
|
||||
return call_user_func_array(['\Shared\Helpers\Helpers', $name], $args);
|
||||
}
|
||||
// LUB: jawne delegacje dla każdej metody
|
||||
}
|
||||
```
|
||||
|
||||
**UWAGA:** `\S::` jest używane WSZĘDZIE w cmsPRO (controls, factory, view, templates, index.php). Delegacja przez wrapper pozwala na stopniową migrację referencji.
|
||||
|
||||
### 1.2 `\Shared\Tpl\Tpl` (z `class.Tpl.php`)
|
||||
|
||||
**Plik:** `autoload/Shared/Tpl/Tpl.php`
|
||||
**Namespace:** `\Shared\Tpl\`
|
||||
|
||||
Stary `class.Tpl.php` → wrapper delegujący do `\Shared\Tpl\Tpl`.
|
||||
|
||||
### 1.3 `\Shared\Cache\CacheHandler` (z `class.Cache.php`)
|
||||
|
||||
**Plik:** `autoload/Shared/Cache/CacheHandler.php`
|
||||
**Namespace:** `\Shared\Cache\`
|
||||
|
||||
cmsPRO używa cache plikowego (gzdeflate + MD5), NIE Redis.
|
||||
Zachować tę samą implementację, tylko przenieść do nowego namespace.
|
||||
|
||||
Stary `class.Cache.php` → wrapper.
|
||||
|
||||
### 1.4 `\Shared\Html\Html` (z `class.Html.php`)
|
||||
|
||||
**Plik:** `autoload/Shared/Html/Html.php`
|
||||
|
||||
Stary `class.Html.php` → wrapper.
|
||||
|
||||
### 1.5 `\Shared\Image\ImageManipulator` (z `class.Image.php`)
|
||||
|
||||
**Plik:** `autoload/Shared/Image/ImageManipulator.php`
|
||||
|
||||
Stary `class.Image.php` (klasa `ImageManipulator`) → wrapper lub alias.
|
||||
|
||||
### 1.6 `\Shared\Email\Email`
|
||||
|
||||
**Plik:** `autoload/Shared/Email/Email.php`
|
||||
|
||||
Nowa klasa opakowująca PHPMailer (wzór: shopPRO `Shared\Email\Email`).
|
||||
|
||||
### 1.7 Usunięcie starych klas globalnych
|
||||
|
||||
**PO PEŁNEJ MIGRACJI** wszystkich referencji (to będzie trwać przez kolejne fazy):
|
||||
- `class.Article.php` → logika do `Domain\Article\ArticleRepository`
|
||||
- `class.Scontainer.php` → logika do `Domain\Scontainers\ScontainersRepository`
|
||||
- `class.Page.php` → logika do `Domain\Pages\PagesRepository`
|
||||
|
||||
`class.Mobile_Detect.php` i `class.geoplugin.php` zostawić (biblioteki zewnętrzne).
|
||||
|
||||
---
|
||||
|
||||
## FAZA 2: Warstwa Domain (repozytoria)
|
||||
|
||||
Dla KAŻDEGO modułu: wyciągnąć logikę z `admin\factory\*` i `front\factory\*` do wspólnego repozytorium w `Domain\`.
|
||||
|
||||
### Wzorzec repozytorium (kopiowany z shopPRO)
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace Domain\Article;
|
||||
|
||||
class ArticleRepository
|
||||
{
|
||||
private $db;
|
||||
|
||||
public function __construct($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function find(int $id): ?array
|
||||
{
|
||||
return $this->db->get('pp_articles', '*', ['id' => $id]);
|
||||
}
|
||||
|
||||
// ... reszta metod
|
||||
}
|
||||
```
|
||||
|
||||
### Lista modułów do migracji (16 modułów)
|
||||
|
||||
| # | Moduł | Źródło (factory) | Cel (Domain) | Priorytet |
|
||||
|---|-------|-------------------|--------------|-----------|
|
||||
| 1 | **Settings** | `admin\factory\Settings` + `front\factory\Settings` | `Domain\Settings\SettingsRepository` | WYSOKI — używany wszędzie |
|
||||
| 2 | **Languages** | `admin\factory\Languages` + `front\factory\Languages` | `Domain\Languages\LanguagesRepository` | WYSOKI — używany w bootstrap |
|
||||
| 3 | **Users** | `admin\factory\Users` | `Domain\User\UserRepository` | WYSOKI — login, 2FA, uprawnienia |
|
||||
| 4 | **Pages** | `admin\factory\Pages` + `front\factory\Pages` | `Domain\Pages\PagesRepository` | WYSOKI — routing frontu |
|
||||
| 5 | **Articles** | `admin\factory\Articles` + `front\factory\Articles` + `class.Article.php` | `Domain\Article\ArticleRepository` | WYSOKI — główna funkcjonalność |
|
||||
| 6 | **Layouts** | `admin\factory\Layouts` + `front\factory\Layouts` | `Domain\Layouts\LayoutsRepository` | WYSOKI — layout engine |
|
||||
| 7 | **Scontainers** | `admin\factory\Scontainers` + `front\factory\Scontainers` + `class.Scontainer.php` | `Domain\Scontainers\ScontainersRepository` | ŚREDNI |
|
||||
| 8 | **Banners** | `admin\factory\Banners` + `front\factory\Banners` | `Domain\Banner\BannerRepository` | ŚREDNI |
|
||||
| 9 | **Newsletter** | `admin\factory\Newsletter` + `front\factory\Newsletter` | `Domain\Newsletter\NewsletterRepository` | ŚREDNI |
|
||||
| 10 | **Authors** | `admin\factory\Authors` + `front\factory\Authors` | `Domain\Author\AuthorRepository` | NISKI |
|
||||
| 11 | **Emails** | `admin\factory\Emails` | `Domain\Email\EmailRepository` | NISKI |
|
||||
| 12 | **Backups** | `admin\factory\Backups` | `Domain\Backup\BackupRepository` | NISKI |
|
||||
| 13 | **SeoAdditional** | `admin\factory\SeoAdditional` + `front\factory\SeoAdditional` | `Domain\SeoAdditional\SeoAdditionalRepository` | NISKI |
|
||||
| 14 | **ArticlesArchive** | `admin\factory\ArticlesArchive` | (część ArticleRepository) | NISKI |
|
||||
| 15 | **Menu** | `front\factory\Menu` | `Domain\Menu\MenuRepository` | ŚREDNI |
|
||||
| 16 | **Update** | `admin\factory\Update` | `Domain\Update\UpdateRepository` | WYSOKI — nowy system |
|
||||
|
||||
### Proces migracji jednego modułu (przykład: Settings)
|
||||
|
||||
1. **Utworzyć** `autoload/Domain/Settings/SettingsRepository.php`
|
||||
2. **Przenieść metody** z `admin\factory\Settings` i `front\factory\Settings`:
|
||||
- `settings_details()` → `allSettings()`
|
||||
- Zamienić `global $mdb` → `$this->db`
|
||||
3. **Napisać testy** w `tests/Unit/Domain/Settings/SettingsRepositoryTest.php`
|
||||
4. **Zaktualizować** wywołujących (controls, view, index.php):
|
||||
- `\front\factory\Settings::settings_details()` → `$settingsRepo->allSettings()`
|
||||
5. **Stary factory** — zostawić tymczasowo jako wrapper:
|
||||
```php
|
||||
namespace front\factory;
|
||||
class Settings {
|
||||
public static function settings_details() {
|
||||
global $mdb;
|
||||
return (new \Domain\Settings\SettingsRepository($mdb))->allSettings();
|
||||
}
|
||||
}
|
||||
```
|
||||
6. **Po migracji wszystkich wywołujących** — usunąć stary factory.
|
||||
|
||||
### Specjalne przypadki
|
||||
|
||||
**`class.Article.php`** — to model z ArrayAccess, nie zwykły factory:
|
||||
- Konstruktor ładuje artykuł z bazy + images + files + pages + tags + params
|
||||
- Szablony frontu używają `$article->field` (obiekt)
|
||||
- **Strategia:** Przenieść logikę do `ArticleRepository`, zwracać tablice. Szablony frontu zostawić na później (użyć wrappera ArrayAccess tymczasowo).
|
||||
|
||||
**`class.Scontainer.php`** — analogicznie, implementuje ArrayAccess.
|
||||
|
||||
---
|
||||
|
||||
## FAZA 3: Admin Controllers z DI
|
||||
|
||||
### 3.1 Nowy router: `admin\App`
|
||||
|
||||
**Plik:** `autoload/admin/App.php`
|
||||
|
||||
Wzorowany 1:1 na shopPRO `admin\App`. Kluczowe elementy:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace admin;
|
||||
|
||||
class App
|
||||
{
|
||||
const APP_SECRET_KEY = 'c3cb2537d25c0efc9e573d059d79c3b8';
|
||||
|
||||
private static $newControllers = [];
|
||||
|
||||
public static function special_actions() { /* z admin\Site */ }
|
||||
public static function finalize_admin_login(...) { /* z admin\Site */ }
|
||||
|
||||
public static function render(): string
|
||||
{
|
||||
global $user;
|
||||
|
||||
if (\Shared\Helpers\Helpers::get('module') === 'user'
|
||||
&& \Shared\Helpers\Helpers::get('action') === 'twofa') {
|
||||
$controller = self::createController('Users');
|
||||
return $controller->twofa();
|
||||
}
|
||||
|
||||
if (!$user || !$user['admin']) {
|
||||
$controller = self::createController('Users');
|
||||
return $controller->login_form();
|
||||
}
|
||||
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl->content = self::route();
|
||||
return $tpl->render('site/main-layout');
|
||||
}
|
||||
|
||||
public static function route()
|
||||
{
|
||||
$_SESSION['admin'] = true;
|
||||
|
||||
$moduleName = '';
|
||||
$parts = explode('_', (string)\Shared\Helpers\Helpers::get('module'));
|
||||
foreach ($parts as $part)
|
||||
$moduleName .= ucfirst($part);
|
||||
|
||||
$action = \Shared\Helpers\Helpers::get('action');
|
||||
|
||||
// Najpierw nowe kontrolery z DI
|
||||
$controller = self::createController($moduleName);
|
||||
if ($controller && method_exists($controller, $action))
|
||||
return $controller->$action();
|
||||
|
||||
// Fallback do starych controls (okres przejściowy)
|
||||
$class = '\admin\controls\\' . $moduleName;
|
||||
if (class_exists($class) && method_exists(new $class, $action))
|
||||
return call_user_func_array([$class, $action], []);
|
||||
|
||||
\Shared\Helpers\Helpers::alert('Nieprawidłowy adres url.');
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function createController(string $moduleName)
|
||||
{
|
||||
$factories = self::getControllerFactories();
|
||||
if (!isset($factories[$moduleName])) return null;
|
||||
$factory = $factories[$moduleName];
|
||||
return is_callable($factory) ? $factory() : null;
|
||||
}
|
||||
|
||||
private static function getControllerFactories(): array
|
||||
{
|
||||
if (!empty(self::$newControllers))
|
||||
return self::$newControllers;
|
||||
|
||||
self::$newControllers = [
|
||||
// Dodawane stopniowo w miarę migracji modułów
|
||||
];
|
||||
|
||||
return self::$newControllers;
|
||||
}
|
||||
|
||||
public static function update()
|
||||
{
|
||||
global $mdb;
|
||||
$repository = new \Domain\Update\UpdateRepository($mdb);
|
||||
$repository->runPendingMigrations();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Przełączenie:**
|
||||
- W `admin/index.php`: zamienić `\admin\Site::special_actions()` → `\admin\App::special_actions()`
|
||||
- Zamienić `\admin\view\Page::show()` → `\admin\App::render()`
|
||||
- Dodać `\admin\App::update()` (migracje SQL)
|
||||
|
||||
Fallback do starych `\admin\controls\*` zapewnia, że system działa ZANIM wszystkie kontrolery zostaną zmigrowane.
|
||||
|
||||
### 3.2 Nowe kontrolery admin (po jednym na moduł)
|
||||
|
||||
**Wzorzec kontrolera** (kopiowany z shopPRO):
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace admin\Controllers;
|
||||
|
||||
use Domain\Article\ArticleRepository;
|
||||
use Domain\Languages\LanguagesRepository;
|
||||
|
||||
class ArticlesController
|
||||
{
|
||||
private $articleRepo;
|
||||
private $langRepo;
|
||||
|
||||
public function __construct(
|
||||
ArticleRepository $articleRepo,
|
||||
LanguagesRepository $langRepo
|
||||
) {
|
||||
$this->articleRepo = $articleRepo;
|
||||
$this->langRepo = $langRepo;
|
||||
}
|
||||
|
||||
public function list()
|
||||
{
|
||||
// logika z admin\controls\Articles::view_list()
|
||||
// + renderowanie szablonu
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
// logika z admin\controls\Articles::article_edit()
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
// logika z admin\controls\Articles::article_save()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Kolejność migracji kontrolerów admin
|
||||
|
||||
| # | Kontroler | Factory → Repository | Wiring w App |
|
||||
|---|-----------|---------------------|--------------|
|
||||
| 1 | `UsersController` | `Users` → `UserRepository` | `'Users' => fn() => new UsersController(new UserRepository($mdb))` |
|
||||
| 2 | `SettingsController` | `Settings` → `SettingsRepository` | `'Settings' => fn() => ...` |
|
||||
| 3 | `UpdateController` | `Update` → `UpdateRepository` | `'Update' => fn() => ...` |
|
||||
| 4 | `LanguagesController` | `Languages` → `LanguagesRepository` | |
|
||||
| 5 | `PagesController` | `Pages` → `PagesRepository` | |
|
||||
| 6 | `ArticlesController` | `Articles` → `ArticleRepository` | |
|
||||
| 7 | `ArticlesArchiveController` | `ArticlesArchive` | |
|
||||
| 8 | `LayoutsController` | `Layouts` → `LayoutsRepository` | |
|
||||
| 9 | `ScontainersController` | `Scontainers` → `ScontainersRepository` | |
|
||||
| 10 | `BannerController` | `Banners` → `BannerRepository` | |
|
||||
| 11 | `NewsletterController` | `Newsletter` → `NewsletterRepository` | |
|
||||
| 12 | `AuthorsController` | `Authors` → `AuthorRepository` | |
|
||||
| 13 | `EmailsController` | `Emails` → `EmailRepository` | |
|
||||
| 14 | `BackupsController` | `Backups` → `BackupRepository` | |
|
||||
| 15 | `SeoAdditionalController` | `SeoAdditional` → `SeoAdditionalRepository` | |
|
||||
| 16 | `FilemanagerController` | (brak factory — sam w sobie) | |
|
||||
|
||||
### 3.4 Mapowanie akcji (stare → nowe nazwy metod)
|
||||
|
||||
Konwencja shopPRO: camelCase zamiast snake_case.
|
||||
|
||||
| Stara akcja (URL) | Nowa metoda |
|
||||
|--------------------|-------------|
|
||||
| `view_list` | `list()` |
|
||||
| `article_edit` | `edit()` |
|
||||
| `article_save` | `save()` |
|
||||
| `article_delete` | `delete()` |
|
||||
| `main_view` | `main_view()` (bez zmian, bo URL tego wymaga) |
|
||||
|
||||
**UWAGA:** URL w admin to `?module=articles&action=view_list`. Router konwertuje `_` na ucfirst, ale akcja jest przekazywana dosłownie. Trzeba zachować dokładne nazwy metod odpowiadające `action` w URL, LUB dodać mapowanie camelCase.
|
||||
|
||||
Rekomendacja: dodać konwersję w routerze (jak shopPRO front\App robi `lcfirst(implode('', array_map('ucfirst', explode('_', $action))))`) LUB zostawić snake_case w nazwach metod kontrolerów.
|
||||
|
||||
---
|
||||
|
||||
## FAZA 4: Frontend (App + Controllers + Views + LayoutEngine)
|
||||
|
||||
### 4.1 `front\App` — nowy router
|
||||
|
||||
**Plik:** `autoload/front/App.php`
|
||||
|
||||
Wzorowany na shopPRO. Kluczowe:
|
||||
- `checkUrlParams()` — obsługa `?a=page`, `?a=change_language`
|
||||
- `route()` — routing do artykułów + kontrolerów DI + fallback do starych controls
|
||||
- `getControllerFactories()` — fabryki kontrolerów
|
||||
- `pageTitle()`, `title()` — tytuły stron
|
||||
|
||||
### 4.2 `front\LayoutEngine` — silnik szablonów
|
||||
|
||||
**Plik:** `autoload/front/LayoutEngine.php`
|
||||
|
||||
Refaktor z `front\view\Site::show()`. Odpowiedzialny za:
|
||||
- Ładowanie layoutu (aktywny dla strony)
|
||||
- Zastępowanie tagów: `[MENU:id]`, `[KONTENER:id]`, `[AKTUALNOSCI:...]`, `[ZAWARTOSC]`, `[TITLE]`, `[LANG:key]`, itp.
|
||||
- Kontakt (formularz)
|
||||
- Dodatkowe kody (statystyki, cookies)
|
||||
|
||||
### 4.3 Frontend Views (statyczne)
|
||||
|
||||
Przenieść `front\view\*` → `front\Views\*` (nowy namespace):
|
||||
|
||||
| Stara klasa | Nowa klasa |
|
||||
|-------------|------------|
|
||||
| `\front\view\Articles` | `\front\Views\Articles` |
|
||||
| `\front\view\Banners` | `\front\Views\Banners` |
|
||||
| `\front\view\Languages` | `\front\Views\Languages` |
|
||||
| `\front\view\Menu` | `\front\Views\Menu` |
|
||||
| `\front\view\Newsletter` | `\front\Views\Newsletter` |
|
||||
| `\front\view\Scontainers` | `\front\Views\Scontainers` |
|
||||
| `\front\view\Search` | `\front\Views\Search` |
|
||||
| `\front\view\Site` | → `\front\LayoutEngine` + `\front\Views\*` |
|
||||
|
||||
**Klasy Views NIE mają DI** — to czyste renderery statyczne (wzór: shopPRO).
|
||||
|
||||
### 4.4 Frontend Controllers
|
||||
|
||||
| Kontroler | Źródło | DI |
|
||||
|-----------|--------|-----|
|
||||
| `NewsletterController` | `front\controls\Newsletter` + `front\factory\Newsletter` | `NewsletterRepository` |
|
||||
| `SearchController` | `front\controls\*` (jeśli istnieje logika) | brak |
|
||||
| `ArticlesController` (opcjonalnie) | `front\controls\Articles` | `ArticleRepository` |
|
||||
|
||||
### 4.5 Przełączenie entry pointów
|
||||
|
||||
**`index.php`:**
|
||||
```php
|
||||
// Stare:
|
||||
\front\controls\Site::check_url_params();
|
||||
$out = \front\view\Site::show();
|
||||
|
||||
// Nowe:
|
||||
\front\App::checkUrlParams();
|
||||
$out = \front\LayoutEngine::show();
|
||||
```
|
||||
|
||||
**`admin/index.php`:**
|
||||
```php
|
||||
// Stare:
|
||||
\admin\Site::special_actions();
|
||||
echo \admin\view\Page::show();
|
||||
|
||||
// Nowe:
|
||||
\admin\App::special_actions();
|
||||
\admin\App::update();
|
||||
echo \admin\App::render();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FAZA 5: Nowy system aktualizacji
|
||||
|
||||
### KLUCZOWA ZASADA: Pierwsza paczka musi być legacy!
|
||||
|
||||
**Pierwsza aktualizacja (v1.690) MUSI być opublikowana starą metodą** (ZIP + `_sql.txt` + `_files.txt`, BEZ manifestu). To dlatego, że v1.690 właśnie wgrywa nowy `UpdateRepository` z obsługą manifestów JSON na serwery klientów. Klienci mają jeszcze stary kod aktualizacji (`admin\factory\Update::update()`), który rozumie TYLKO legacy format.
|
||||
|
||||
**Sekwencja:**
|
||||
1. **v1.690** — budujemy **ręcznie starą metodą** (lub `build-update.ps1` z flagą `--legacy-only`). Ta paczka zawiera nowy `UpdateRepository`, nowy `admin\App`, nowy autoloader — całą infrastrukturę.
|
||||
2. **v1.691+** — od tego momentu budujemy normalnie z manifestem JSON. Klienci już mają nowy `UpdateRepository` (wgrany przez v1.690), który obsługuje oba formaty.
|
||||
|
||||
Innymi słowy: v1.690 to "paczka-most" — dostarczana starym kanałem, ale wgrywająca nowy silnik aktualizacji.
|
||||
|
||||
### 5.1 `Domain\Update\UpdateRepository` — pełna logika aktualizacji
|
||||
|
||||
**Plik:** `autoload/Domain/Update/UpdateRepository.php`
|
||||
|
||||
Skopiować z shopPRO `Domain\Update\UpdateRepository` i dostosować:
|
||||
- URL serwera: `https://cmspro.project-dc.pl/updates/` (zamiast shoppro)
|
||||
- Plik wersji: `libraries/version.ini` (jak jest teraz)
|
||||
|
||||
Kluczowe metody:
|
||||
```php
|
||||
public function update(): array
|
||||
private function downloadAndApply(string $ver, string $dir, array $log): array
|
||||
private function downloadAndApplyWithManifest(string $ver, string $dir, array $manifest, array $log): array
|
||||
private function downloadAndApplyLegacy(string $ver, string $dir, array $log): array
|
||||
private function verifyChecksum(string $filePath, string $expectedChecksum, array $log): array
|
||||
private function createBackup(array $manifest, array $log): array
|
||||
private function extractZip(string $fileName, array $log): array
|
||||
public function runPendingMigrations(): void
|
||||
```
|
||||
|
||||
**Kompatybilność wsteczna:** Metoda `downloadAndApply()` próbuje najpierw manifest. Jeśli brak → fallback do legacy (ZIP + _sql.txt + _files.txt). Dzięki temu stare paczki (v1.001-v1.689) nadal działają.
|
||||
|
||||
### 5.2 `admin\Controllers\UpdateController`
|
||||
|
||||
```php
|
||||
namespace admin\Controllers;
|
||||
|
||||
use Domain\Update\UpdateRepository;
|
||||
|
||||
class UpdateController
|
||||
{
|
||||
private $repository;
|
||||
|
||||
public function __construct(UpdateRepository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
public function main_view(): string { /* widok panelu aktualizacji */ }
|
||||
public function update(): void { /* POST: wykonaj update */ }
|
||||
public function updateAll(): void { /* AJAX: pętla aktualizacji */ }
|
||||
public function checkUpdate(): void { /* AJAX: sprawdź dostępność */ }
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 Nowy `updates/versions.php`
|
||||
|
||||
Dostosować do nowego formatu (wzór shopPRO):
|
||||
```php
|
||||
<?
|
||||
$current_ver = 1690; // Pierwsza wersja z nowym systemem
|
||||
|
||||
for ($i = 1; $i <= $current_ver; $i++)
|
||||
{
|
||||
$dir = substr(number_format($i / 1000, 3), 0, strlen(number_format($i / 1000, 3)) - 2) . '0';
|
||||
$version_new = number_format($i / 1000, 3);
|
||||
|
||||
if (file_exists('../updates/' . $dir . '/ver_' . $version_new . '.zip'))
|
||||
$versions[] = $version_new;
|
||||
}
|
||||
|
||||
// ... licencje (bez zmian) ...
|
||||
```
|
||||
|
||||
### 5.4 Auto-generowany `updates/changelog.php`
|
||||
|
||||
Skopiować z shopPRO — skanuje `_manifest.json` + `changelog-legacy.json`.
|
||||
|
||||
### 5.5 `changelog-legacy.json`
|
||||
|
||||
Przenieść dotychczasowe wpisy z `updates/changelog.php` do JSON:
|
||||
```json
|
||||
[
|
||||
{"version": "1.689", "date": "01.01.2026", "text": "- opis zmian v1.689"},
|
||||
{"version": "1.688", "date": "...", "text": "- ..."},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
### 5.6 `build-update.ps1`
|
||||
|
||||
Skopiować z shopPRO i dostosować:
|
||||
- Zmienić header: `=== cmsPRO Build Update ===`
|
||||
- Wersja: `v1.690` (format `X.XXX`, nie `0.XXX`)
|
||||
- Katalog: `updates/1.60/` (dla 1.690), `updates/1.70/` (dla 1.700) itd.
|
||||
- URL: `https://cmspro.project-dc.pl/updates/`
|
||||
|
||||
### 5.7 `.updateignore`
|
||||
|
||||
Skopiować z shopPRO, dostosować ścieżki:
|
||||
```
|
||||
*.md
|
||||
docs/
|
||||
CLAUDE.md
|
||||
AGENTS.md
|
||||
.claude/
|
||||
.gitignore
|
||||
.git/
|
||||
tests/
|
||||
phpunit.xml
|
||||
phpunit.phar
|
||||
composer.json
|
||||
composer.lock
|
||||
vendor/
|
||||
test.ps1
|
||||
memory/
|
||||
updates/
|
||||
.updateignore
|
||||
build-update.ps1
|
||||
migrations/
|
||||
config.php
|
||||
.htaccess
|
||||
admin/.htaccess
|
||||
libraries/version.ini
|
||||
layout/style-css/style.css
|
||||
layout/style-css/style.css.map
|
||||
layout/style-scss/style.scss
|
||||
layout/style-scss/_mixins.scss
|
||||
layout/style-scss/_mixins.css
|
||||
temp/
|
||||
backups/
|
||||
cache/
|
||||
cron/temp/
|
||||
.vscode/
|
||||
.serena/
|
||||
.phpunit.result.cache
|
||||
```
|
||||
|
||||
### 5.8 Katalog `migrations/`
|
||||
|
||||
Migracje SQL w formacie `{version}.sql`:
|
||||
```
|
||||
migrations/
|
||||
├── 1.690.sql
|
||||
├── 1.691.sql
|
||||
└── ...
|
||||
```
|
||||
|
||||
`UpdateRepository::runPendingMigrations()` skanuje katalog i wykonuje migracje nowsze niż `version.ini`.
|
||||
|
||||
---
|
||||
|
||||
## FAZA 6: Testy PHPUnit
|
||||
|
||||
### 6.1 Struktura testów
|
||||
|
||||
```
|
||||
tests/
|
||||
├── bootstrap.php
|
||||
├── stubs/
|
||||
│ ├── CacheHandler.php ← stub dla \Shared\Cache\CacheHandler
|
||||
│ └── Helpers.php ← stub dla \Shared\Helpers\Helpers
|
||||
└── Unit/
|
||||
└── Domain/
|
||||
├── Article/
|
||||
│ └── ArticleRepositoryTest.php
|
||||
├── Settings/
|
||||
│ └── SettingsRepositoryTest.php
|
||||
├── User/
|
||||
│ └── UserRepositoryTest.php
|
||||
├── Languages/
|
||||
│ └── LanguagesRepositoryTest.php
|
||||
└── ...
|
||||
```
|
||||
|
||||
### 6.2 Wzorzec testu
|
||||
|
||||
```php
|
||||
class ArticleRepositoryTest extends TestCase
|
||||
{
|
||||
private $db;
|
||||
private $repo;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->db = $this->createMock(\medoo::class);
|
||||
$this->repo = new \Domain\Article\ArticleRepository($this->db);
|
||||
}
|
||||
|
||||
public function testFindReturnsArticleArray(): void
|
||||
{
|
||||
$this->db->method('get')
|
||||
->willReturn(['id' => 1, 'status' => 1]);
|
||||
|
||||
$result = $this->repo->find(1);
|
||||
$this->assertIsArray($result);
|
||||
$this->assertEquals(1, $result['id']);
|
||||
}
|
||||
|
||||
public function testFindReturnsNullWhenNotFound(): void
|
||||
{
|
||||
$this->db->method('get')->willReturn(null);
|
||||
$this->assertNull($this->repo->find(999));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FAZA 7: Dokumentacja
|
||||
|
||||
Utworzyć w `docs/`:
|
||||
- `PROJECT_STRUCTURE.md` — architektura, katalogi, namespace'y, routing
|
||||
- `DATABASE_STRUCTURE.md` — schemat bazy danych (tabele `pp_*`)
|
||||
- `TESTING.md` — jak uruchamiać testy
|
||||
- `CHANGELOG.md` — historia zmian
|
||||
- `UPDATE_INSTRUCTIONS.md` — jak budować paczki aktualizacji
|
||||
|
||||
---
|
||||
|
||||
## FAZA 8: Porządki (po pełnej migracji)
|
||||
|
||||
### 8.1 Usunięcie starych katalogów
|
||||
|
||||
```
|
||||
rm -rf autoload/admin/controls/
|
||||
rm -rf autoload/admin/factory/
|
||||
rm -rf autoload/admin/view/
|
||||
rm -rf autoload/front/controls/
|
||||
rm -rf autoload/front/factory/
|
||||
rm -rf autoload/front/view/
|
||||
rm autoload/class.S.php
|
||||
rm autoload/class.Tpl.php
|
||||
rm autoload/class.Cache.php
|
||||
rm autoload/class.Html.php
|
||||
rm autoload/class.Image.php
|
||||
rm autoload/class.Article.php
|
||||
rm autoload/class.Page.php
|
||||
rm autoload/class.Scontainer.php
|
||||
rm autoload/admin/class.Site.php
|
||||
```
|
||||
|
||||
### 8.2 Usunięcie wrappera `\S`
|
||||
|
||||
Przeszukać CAŁY kod i zamienić:
|
||||
- `\S::get()` → `\Shared\Helpers\Helpers::get()`
|
||||
- `\S::get_session()` → `\Shared\Helpers\Helpers::get_session()`
|
||||
- `\S::alert()` → `\Shared\Helpers\Helpers::alert()`
|
||||
- itd.
|
||||
|
||||
### 8.3 Usunięcie wrappera `\Tpl`
|
||||
|
||||
- `\Tpl::view(...)` → `\Shared\Tpl\Tpl::view(...)`
|
||||
- `new \Tpl` → `new \Shared\Tpl\Tpl`
|
||||
|
||||
---
|
||||
|
||||
## PODSUMOWANIE — KOLEJNOŚĆ PRAC
|
||||
|
||||
| Faza | Co robimy | Szacunkowa złożoność |
|
||||
|------|-----------|---------------------|
|
||||
| **0** | Autoloader, katalogi, PHPUnit, git tag, CLAUDE.md | Mała |
|
||||
| **1** | Shared utilities (S→Helpers, Tpl, Cache, Html, Image, Email) | Średnia |
|
||||
| **2** | Domain repositories (16 modułów: Settings, Languages, Users, Pages, Articles...) | **Duża** |
|
||||
| **3** | Admin Controllers + App router (16 kontrolerów) | **Duża** |
|
||||
| **4** | Frontend App + LayoutEngine + Views + Controllers | Średnia |
|
||||
| **5** | Nowy system aktualizacji (UpdateRepository, build-update.ps1, manifesty) | Średnia |
|
||||
| **6** | Testy PHPUnit | Średnia |
|
||||
| **7** | Dokumentacja | Mała |
|
||||
| **8** | Porządki — usunięcie starych klas | Mała |
|
||||
|
||||
### Zasada naczelna
|
||||
|
||||
**Każda faza musi zostawić działający system.** Stary i nowy kod koegzystują dzięki:
|
||||
- Fallback w routerze (nowy kontroler → stary controls)
|
||||
- Wrappery w starych klasach (delegujące do nowych)
|
||||
- Stopniowe przenoszenie referencji
|
||||
|
||||
### Kolejność prac wewnątrz fazy 2+3 (moduł po module)
|
||||
|
||||
Rekomendowana kolejność modułów (od najprostszych do najtrudniejszych):
|
||||
|
||||
1. **Settings** (1 metoda, zero zależności)
|
||||
2. **Languages** (kilka metod, używany w bootstrap)
|
||||
3. **Users** (login, 2FA, uprawnienia — kluczowe dla admin)
|
||||
4. **Update** (nowy system aktualizacji)
|
||||
5. **Pages** (routing frontu)
|
||||
6. **Layouts** (layout engine)
|
||||
7. **Scontainers** (kontenery statyczne)
|
||||
8. **Banners** (banery)
|
||||
9. **Authors** (autorzy)
|
||||
10. **Menu** (menu — tylko front)
|
||||
11. **Articles** (NAJTRUDNIEJSZY — class.Article.php z ArrayAccess, images, files, params, tags)
|
||||
12. **Newsletter** (newsletter + preview renderer)
|
||||
13. **SeoAdditional** (SEO per URL)
|
||||
14. **Emails** (log kontaktowy)
|
||||
15. **Backups** (backup bazy)
|
||||
16. **ArticlesArchive** (archiwum — część ArticleRepository)
|
||||
|
||||
---
|
||||
|
||||
## CHECKLIST "KONIEC PRACY" (dla cmsPRO)
|
||||
|
||||
Po zakończeniu każdej sesji pracy:
|
||||
1. Uruchom testy: `./test.ps1`
|
||||
2. Zaktualizuj docs jeśli potrzeba
|
||||
3. SQL migracje → `migrations/{version}.sql`
|
||||
4. `updates/versions.php` — ustawić `$current_ver`
|
||||
5. Commit + push
|
||||
6. Git tag: `git tag v1.XXX` + `git push origin v1.XXX`
|
||||
|
||||
---
|
||||
|
||||
## RÓŻNICE cmsPRO vs shopPRO
|
||||
|
||||
| Aspekt | cmsPRO | shopPRO |
|
||||
|--------|--------|---------|
|
||||
| Cache | Plikowy (gzdeflate + MD5) | Redis (CacheHandler + RedisConnection) |
|
||||
| Moduły sklepowe | BRAK | Product, Category, Order, Basket, Client, Coupon, Promotion, Transport, PaymentMethod, Producer, Attribute, ProductSet, ShopStatus, Integrations, Dashboard |
|
||||
| Wersjonowanie | v1.689 (4 cyfry) | v0.308 (3 cyfry) |
|
||||
| URL aktualizacji | cmspro.project-dc.pl | shoppro.project-dc.pl |
|
||||
| API REST | Minimalny (api.php) | Rozbudowany (ApiRouter + 3 kontrolery) |
|
||||
| Pixieset | TAK | NIE |
|
||||
| AuditSEO | TAK | NIE |
|
||||
| FormEdit System | NIE | TAK (ViewModels + FormValidator + FormFieldRenderer) |
|
||||
| Remember-me | Legacy JSON cookie (hash hasła!) | HMAC-SHA256 signed payload |
|
||||
|
||||
**UWAGA na bezpieczeństwo:** W `admin/index.php` cmsPRO cookie remember-me przechowuje hash hasła w JSON — to luka! W ramach migracji Users należy to zmienić na HMAC-SHA256 (jak w shopPRO `admin\App::finalize_admin_login()`).
|
||||
219
_backup.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
define('TMP_FILE', __DIR__ . '/backup_tmp.json');
|
||||
define('FILES_PER_STEP', 50);
|
||||
|
||||
// Sprawdzenie czy możemy użyć shell_exec + zip/tar
|
||||
function canUseShell() {
|
||||
return function_exists('shell_exec') && !in_array('shell_exec', explode(',', ini_get('disable_functions')));
|
||||
}
|
||||
|
||||
function commandAvailable($cmd) {
|
||||
$check = shell_exec("command -v $cmd 2>/dev/null");
|
||||
return !empty($check);
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'init') {
|
||||
$filename = 'backup_' . date("Ymd_His");
|
||||
$response = ['success' => false];
|
||||
|
||||
if (canUseShell()) {
|
||||
if (commandAvailable('tar')) {
|
||||
$tarName = "$filename.tar";
|
||||
shell_exec("tar -cf $tarName .");
|
||||
if (file_exists($tarName)) {
|
||||
$response = [
|
||||
'success' => true,
|
||||
'method' => 'shell_tar',
|
||||
'file' => $tarName
|
||||
];
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
} elseif (commandAvailable('zip')) {
|
||||
$zipName = "$filename.zip";
|
||||
shell_exec("zip -r $zipName . -x '*backup_*.zip' '*.git*' 'node_modules/*' 'vendor/*'");
|
||||
if (file_exists($zipName)) {
|
||||
$response = [
|
||||
'success' => true,
|
||||
'method' => 'shell_zip',
|
||||
'file' => $zipName
|
||||
];
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Jeśli nie ma shell_exec lub zip/tar — fallback na ZipArchive krok po kroku
|
||||
$zipName = "$filename.zip";
|
||||
$zipPath = __DIR__ . '/' . $zipName;
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS)
|
||||
);
|
||||
|
||||
$files = [];
|
||||
foreach ($iterator as $file) {
|
||||
$path = $file->getPathname();
|
||||
if (strpos($path, $zipName) !== false) continue;
|
||||
$files[] = $path;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nie można utworzyć ZIP']);
|
||||
exit;
|
||||
}
|
||||
$zip->addEmptyDir('__INIT__');
|
||||
$zip->close();
|
||||
|
||||
file_put_contents(TMP_FILE, json_encode([
|
||||
'method' => 'php_zip',
|
||||
'files' => $files,
|
||||
'index' => 0,
|
||||
'zipfile' => $zipPath,
|
||||
'zipname' => $zipName
|
||||
]));
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'method' => 'php_zip'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'step') {
|
||||
if (!file_exists(TMP_FILE)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Brak danych tymczasowych']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents(TMP_FILE), true);
|
||||
$files = $data['files'];
|
||||
$index = $data['index'];
|
||||
$zipfile = $data['zipfile'];
|
||||
$zipname = $data['zipname'];
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipfile) !== true) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nie można otworzyć ZIP']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$end = min($index + FILES_PER_STEP, count($files));
|
||||
for ($i = $index; $i < $end; $i++) {
|
||||
$filePath = $files[$i];
|
||||
if (is_file($filePath)) {
|
||||
$localname = substr($filePath, strlen(__DIR__) + 1);
|
||||
$zip->addFile($filePath, $localname);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
$data['index'] = $end;
|
||||
file_put_contents(TMP_FILE, json_encode($data));
|
||||
|
||||
$progress = $end / count($files);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'method' => 'php_zip',
|
||||
'progress' => round($progress * 100, 2),
|
||||
'done' => $end >= count($files),
|
||||
'zipfile' => $zipname
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Backup dynamiczny</title>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<style>
|
||||
#progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
height: 20px;
|
||||
width: 0;
|
||||
background-color: #4caf50;
|
||||
text-align: center;
|
||||
color: white;
|
||||
line-height: 20px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Automatyczny backup plików</h2>
|
||||
<button id="start-backup">Rozpocznij</button>
|
||||
|
||||
<div id="progress-bar" style="display:none;">
|
||||
<div id="progress-bar-inner">0.00%</div>
|
||||
</div>
|
||||
|
||||
<div id="status"></div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let method = '';
|
||||
let zipFile = '';
|
||||
|
||||
$("#start-backup").click(function(){
|
||||
$("#status").text("Inicjalizowanie...");
|
||||
$("#progress-bar").show();
|
||||
$("#progress-bar-inner").css("width", "0%").text("0.00%");
|
||||
|
||||
$.post("", { action: "init" }, function(res){
|
||||
if (!res.success) {
|
||||
$("#status").text("Błąd: " + res.message);
|
||||
return;
|
||||
}
|
||||
|
||||
method = res.method;
|
||||
|
||||
if (method === 'shell_tar' || method === 'shell_zip') {
|
||||
$("#progress-bar-inner").css("width", "100%").text("100%");
|
||||
$("#status").html("✅ Gotowe! <a href='" + res.file + "' download>Pobierz</a>");
|
||||
} else if (method === 'php_zip') {
|
||||
doStep();
|
||||
}
|
||||
}, "json");
|
||||
});
|
||||
|
||||
function doStep() {
|
||||
$.post("", { action: "step" }, function(res){
|
||||
if (res.success && res.method === 'php_zip') {
|
||||
let percent = parseFloat(res.progress).toFixed(2);
|
||||
$("#progress-bar-inner").css("width", percent + "%").text(percent + "%");
|
||||
|
||||
if (res.done) {
|
||||
$("#status").html("✅ Backup gotowy! <a href='" + res.zipfile + "' download>Pobierz ZIP</a>");
|
||||
} else {
|
||||
setTimeout(doStep, 300);
|
||||
}
|
||||
} else {
|
||||
$("#status").text("Błąd: " + res.message);
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
186
_restore.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
define('TMP_UNZIP_FILE', __DIR__ . '/unzip_tmp.json');
|
||||
define('UNZIP_STEP_FILES', 50); // ile plików rozpakowywać w jednym kroku
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($_POST['action'] === 'init') {
|
||||
$zipFile = isset($_POST['zipfile']) ? basename($_POST['zipfile']) : '';
|
||||
$zipPath = __DIR__ . '/' . $zipFile;
|
||||
|
||||
if (!file_exists($zipPath)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Plik ZIP nie istnieje']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipPath) !== true) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nie można otworzyć ZIP']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$fileList = [];
|
||||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||||
$fileList[] = $zip->getNameIndex($i);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
// Zapisz listę plików do rozpakowania
|
||||
file_put_contents(TMP_UNZIP_FILE, json_encode([
|
||||
'zipfile' => $zipPath,
|
||||
'files' => $fileList,
|
||||
'index' => 0
|
||||
]));
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_POST['action'] === 'step') {
|
||||
if (!file_exists(TMP_UNZIP_FILE)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Brak danych tymczasowych']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents(TMP_UNZIP_FILE), true);
|
||||
$zipfile = $data['zipfile'];
|
||||
$files = $data['files'];
|
||||
$index = $data['index'];
|
||||
|
||||
if (!file_exists($zipfile)) {
|
||||
echo json_encode(['success' => false, 'message' => 'ZIP nie istnieje: ' . $zipfile]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipfile) !== true) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nie można otworzyć ZIP']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$end = min($index + UNZIP_STEP_FILES, count($files));
|
||||
|
||||
for ($i = $index; $i < $end; $i++) {
|
||||
$entryName = $files[$i];
|
||||
$targetPath = __DIR__ . '/' . $entryName;
|
||||
|
||||
if (substr($entryName, -1) === '/') {
|
||||
// Katalog
|
||||
@mkdir($targetPath, 0755, true);
|
||||
} else {
|
||||
$dir = dirname($targetPath);
|
||||
@mkdir($dir, 0755, true); // utwórz katalog, jeśli nie istnieje
|
||||
copy("zip://$zipfile#$entryName", $targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
$data['index'] = $end;
|
||||
file_put_contents(TMP_UNZIP_FILE, json_encode($data));
|
||||
|
||||
$progress = $end / count($files);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'progress' => round($progress * 100, 2),
|
||||
'done' => $end >= count($files)
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => false, 'message' => 'Nieznana akcja']);
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Rozpakowywanie ZIP z postępem</title>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<style>
|
||||
#progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
height: 20px;
|
||||
width: 0;
|
||||
background-color: #2196f3;
|
||||
text-align: center;
|
||||
color: white;
|
||||
line-height: 20px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Rozpakuj plik ZIP</h2>
|
||||
|
||||
<form id="unzip-form">
|
||||
<label for="zipfile">Nazwa pliku ZIP:</label>
|
||||
<input type="text" id="zipfile" name="zipfile" placeholder="np. backup_20250321_123456.zip" required>
|
||||
<button type="submit">Rozpakuj</button>
|
||||
</form>
|
||||
|
||||
<div id="progress-bar">
|
||||
<div id="progress-bar-inner">0.00%</div>
|
||||
</div>
|
||||
|
||||
<div id="status"></div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let unzipInProgress = false;
|
||||
let currentZip = "";
|
||||
|
||||
$("#unzip-form").submit(function(e){
|
||||
e.preventDefault();
|
||||
if (unzipInProgress) return;
|
||||
|
||||
currentZip = $("#zipfile").val();
|
||||
$("#status").text("Inicjalizowanie...");
|
||||
$("#progress-bar-inner").css("width", "0%").text("0.00%");
|
||||
unzipInProgress = true;
|
||||
|
||||
$.post("", { action: "init", zipfile: currentZip }, function(res){
|
||||
if (res.success) {
|
||||
doUnzipStep();
|
||||
} else {
|
||||
$("#status").text("Błąd: " + res.message);
|
||||
unzipInProgress = false;
|
||||
}
|
||||
}, "json");
|
||||
});
|
||||
|
||||
function doUnzipStep() {
|
||||
$.post("", { action: "step" }, function(res){
|
||||
if (res.success) {
|
||||
let percent = parseFloat(res.progress).toFixed(2);
|
||||
$("#progress-bar-inner").css("width", percent + "%").text(percent + "%");
|
||||
|
||||
if (res.done) {
|
||||
$("#status").html("✅ Rozpakowywanie zakończone.");
|
||||
unzipInProgress = false;
|
||||
} else {
|
||||
setTimeout(doUnzipStep, 300);
|
||||
}
|
||||
} else {
|
||||
$("#status").text("Błąd: " + res.message);
|
||||
unzipInProgress = false;
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
38
admin/ajax.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?
|
||||
error_reporting( E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED );
|
||||
function __autoload_my_classes( $classname )
|
||||
{
|
||||
$q = explode( '\\' , $classname );
|
||||
$c = array_pop( $q );
|
||||
$f = '../autoload/' . implode( '/' , $q ) . '/class.' . $c . '.php';
|
||||
if ( $c == 'Savant3' )
|
||||
{
|
||||
require_once( '../autoload/Savant3.php' );
|
||||
return true;
|
||||
}
|
||||
if ( file_exists( $f ) )
|
||||
require_once( $f );
|
||||
}
|
||||
spl_autoload_register( '__autoload_my_classes' );
|
||||
|
||||
require_once '../config.php';
|
||||
require_once '../libraries/medoo/medoo.php';
|
||||
require_once '../libraries/grid/config.php';
|
||||
date_default_timezone_set('Europe/Warsaw');
|
||||
|
||||
session_start();
|
||||
|
||||
$mdb = new medoo( [
|
||||
'database_type' => 'mysql',
|
||||
'database_name' => $database['name'],
|
||||
'server' => $database['host'],
|
||||
'username' => $database['user'],
|
||||
'password' => $database['password'],
|
||||
'charset' => 'utf8'
|
||||
] );
|
||||
|
||||
require_once 'ajax/pages.php';
|
||||
require_once 'ajax/articles.php';
|
||||
require_once 'ajax/users.php';
|
||||
require_once 'ajax/newsletter.php';
|
||||
?>
|
||||
54
admin/ajax/articles.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
$a = \S::get( 'a' );
|
||||
|
||||
if ( $a == 'article_image_delete' )
|
||||
{
|
||||
$response = [ 'status' => 'error', 'msg' => 'Podczas usuwania zdjecia wystąpił błąd. Proszę spróbować ponownie.' ];
|
||||
|
||||
if ( \admin\factory\Articles::delete_img( \S::get( 'image_id' ) ) )
|
||||
$response = [ 'status' => 'ok' ];
|
||||
|
||||
echo json_encode( $response );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $a == 'article_file_delete' )
|
||||
{
|
||||
$response = [ 'status' => 'error', 'msg' => 'Podczas usuwania załącznika wystąpił błąd. Proszę spróbować ponownie.' ];
|
||||
|
||||
if ( \admin\factory\Articles::delete_file( \S::get( 'file_id' ) ) )
|
||||
$response = [ 'status' => 'ok' ];
|
||||
|
||||
echo json_encode( $response );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $a == 'article_image_alt_change' )
|
||||
{
|
||||
$response = [ 'status' => 'error', 'msg' => 'Podczas zmiany atrybutu alt zdjęcia wystąpił błąd. Proszę spróbować ponownie.' ];
|
||||
|
||||
if ( \admin\factory\Articles::image_alt_change( \S::get( 'image_id' ), \S::get( 'image_alt' ) ) )
|
||||
$response = [ 'status' => 'ok' ];
|
||||
|
||||
echo json_encode( $response );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $a == 'article_file_name_change' )
|
||||
{
|
||||
$response = [ 'status' => 'error', 'msg' => 'Podczas zmiany nazwy załącznika wystąpił błąd. Proszę spróbować ponownie.' ];
|
||||
|
||||
if ( \admin\factory\Articles::file_name_change( \S::get( 'file_id' ), \S::get( 'file_name' ) ) )
|
||||
$response = [ 'status' => 'ok' ];
|
||||
|
||||
echo json_encode( $response );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $a == 'google_url_preview_article' )
|
||||
{
|
||||
if ( \S::get( 'article_id' ) )
|
||||
echo $_SERVER['SERVER_NAME'] . '/a-' . \S::get( 'article_id' ) . '-' . \S::seo( \S::get( 'title' ) );
|
||||
else
|
||||
echo $_SERVER['SERVER_NAME'] . '/a-' . ( \S::max_db_value( 'pp_articles', 'id' ) + 1 ) . '-' . \S::seo( \S::get( 'title' ) );
|
||||
}
|
||||
16
admin/ajax/newsletter.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
$a = \S::get( 'a' );
|
||||
|
||||
if ( $a == 'newsletter-preview' )
|
||||
{
|
||||
$dates = explode( ' - ', \S::get( 'dates' ) );
|
||||
$template = \S::get('template');
|
||||
|
||||
echo \admin\view\Newsletter::preview(
|
||||
\admin\factory\Articles::articles_by_date_add( $dates[0], $dates[1] ),
|
||||
\admin\factory\Settings::settings_details(),
|
||||
\admin\factory\Newsletter::email_template_detalis( $template ),
|
||||
\S::get( 'dates' )
|
||||
);
|
||||
exit;
|
||||
}
|
||||
91
admin/ajax/pages.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
$a = \S::get('a');
|
||||
|
||||
if ($a == 'save_articles_order') {
|
||||
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania kolejności wyświetlania artykułów wystąpił błąd. Proszę spróbować ponownie.'];
|
||||
|
||||
if (\admin\factory\Pages::save_articles_order(\S::get('page_id'), \S::get('articles')))
|
||||
$response = ['status' => 'ok'];
|
||||
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($a == 'save_pages_order') {
|
||||
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania kolejności stron wystąpił błąd. Proszę spróbować ponownie.'];
|
||||
|
||||
if (\admin\factory\Pages::save_pages_order(\S::get('menu_id'), \S::get('pages')))
|
||||
$response = ['status' => 'ok'];
|
||||
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($a == 'generate_seo_link') {
|
||||
$response = ['status' => 'error', 'msg' => 'Podczas generowania pola "seo link" wystąpił błąd. Proszę spróbować ponownie.'];
|
||||
|
||||
if ($seo_link = \admin\factory\Pages::generate_seo_link(\S::get('title'), \S::get('page_id'), \S::get('article_id'), \S::get('lang'), \S::get('pid')))
|
||||
$response = ['status' => 'ok', 'seo_link' => $seo_link];
|
||||
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($a == 'cookie_menus') {
|
||||
$array = unserialize($_COOKIE['cookie_menus']);
|
||||
|
||||
if ($array[\S::get('menu_id')] == 0)
|
||||
$array[\S::get('menu_id')] = 1;
|
||||
else
|
||||
$array[\S::get('menu_id')] = 0;
|
||||
|
||||
$array = serialize($array);
|
||||
|
||||
setcookie('cookie_menus', $array, time() + 3600 * 24 * 365);
|
||||
}
|
||||
|
||||
if ($a == 'cookie_pages') {
|
||||
$array = unserialize($_COOKIE['cookie_pages']);
|
||||
|
||||
if ($array[\S::get('page_id')] == 0)
|
||||
$array[\S::get('page_id')] = 1;
|
||||
else
|
||||
$array[\S::get('page_id')] = 0;
|
||||
|
||||
$array = serialize($array);
|
||||
|
||||
setcookie('cookie_pages', $array, time() + 3600 * 24 * 365);
|
||||
}
|
||||
|
||||
if ( $a == 'google_url_preview' )
|
||||
{
|
||||
$settings = \front\factory\Settings::settings_details();
|
||||
$structure = $settings['links_structure'];
|
||||
|
||||
if ( $structure )
|
||||
{
|
||||
if ( \S::get( 'page_id' ) )
|
||||
{
|
||||
$seo_link = \admin\factory\Pages::google_url_preview(\S::get('page_id'), \S::get('title'), \S::get('lang_id'), \S::get('pid'), 0, \S::get('seo_link'));
|
||||
echo $seo_link;
|
||||
}
|
||||
else
|
||||
{
|
||||
$seo_link = \admin\factory\Pages::google_url_preview(0, \S::get('title'), \S::get('lang_id'), \S::get('pid'), \S::max_db_value('pp_pages', 'id') + 1, \S::get('seo_link'));
|
||||
echo $seo_link;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( \S::get( 'seo_link' ) )
|
||||
echo \S::get( 'seo_link' );
|
||||
else
|
||||
{
|
||||
if ( \S::get( 'page_id' ) )
|
||||
echo $prefix . 's-' . \S::get('page_id') . '-' . \S::seo(\S::get('title'));
|
||||
else
|
||||
echo $prefix . 's-' . ( \S::max_db_value('pp_pages', 'id') + 1 ) . '-' . \S::seo(\S::get('title'));
|
||||
}
|
||||
}
|
||||
}
|
||||
9
admin/ajax/users.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
$a = \S::get( 'a' );
|
||||
|
||||
if ( $a == 'check_login' )
|
||||
{
|
||||
$response = \admin\factory\Users::check_login( \S::get( 'login' ), \S::get( 'user_id' ) );
|
||||
echo json_encode( $response );
|
||||
exit;
|
||||
}
|
||||
20
admin/css/.htaccess
Normal file
@@ -0,0 +1,20 @@
|
||||
# Wyłącz listowanie
|
||||
Options -Indexes
|
||||
|
||||
# Domyślnie blokujemy wszystko…
|
||||
Require all denied
|
||||
|
||||
# …a dopiero potem pozwalamy na pliki statyczne
|
||||
<FilesMatch "\.(css|js|map|mjs|png|jpe?g|gif|svgz?|webp|ico|woff2?|woff|ttf|eot)$">
|
||||
Require all granted
|
||||
</FilesMatch>
|
||||
|
||||
# Twardo blokuj cokolwiek, co mogłoby się wykonać
|
||||
<FilesMatch "\.(php|phtml|php[0-9]?|phar|pht|cgi|pl|py|sh)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
# Nie serwuj plików ukrytych (.env itp.)
|
||||
<FilesMatch "^\.(.*)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
2
admin/css/ckeditor.css
Normal file
@@ -0,0 +1,2 @@
|
||||
blockquote{padding-left:25px;border-left:5px solid #ccc}
|
||||
/*# sourceMappingURL=ckeditor.css.map */
|
||||
1
admin/css/ckeditor.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["ckeditor.scss"],"names":[],"mappings":"AACA,WACE,aAAc,KACd,YAAa,IAAA,MAAA"}
|
||||
5
admin/css/ckeditor.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
//out: ckeditor.css, compress: true, sourceMap: true
|
||||
blockquote {
|
||||
padding-left: 25px;
|
||||
border-left: 5px solid #ccc;
|
||||
}
|
||||
2
admin/css/custom.css
Normal file
1
admin/css/custom.css.map
Normal file
1382
admin/css/custom.scss
Normal file
1
admin/css/icons/backup-line.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="36" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 36 36" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path class="clr-i-outline clr-i-outline-path-1" d="M6 22h24v2H6z" fill="#8691b2"/><path class="clr-i-outline clr-i-outline-path-2" d="M30.84 13.37A1.94 1.94 0 0 0 28.93 12h-2.38a3 3 0 0 1-.14 2h2.54c1.05 2.94 2.77 7.65 3.05 8.48V30H4v-7.52C4.28 21.65 7.05 14 7.05 14h2.53a3 3 0 0 1-.14-2H7.07a1.92 1.92 0 0 0-1.9 1.32C2 22 2 22.1 2 22.33V30a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2v-7.67c0-.23 0-.33-3.16-8.96z" fill="#8691b2"/><path class="clr-i-outline clr-i-outline-path-3" d="M18 19.84l6.38-6.35A1 1 0 1 0 23 12.08L19 16V4a1 1 0 1 0-2 0v12l-4-3.95a1 1 0 0 0-1.41 1.42z" fill="#8691b2"/><rect x="0" y="0" width="36" height="36" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 917 B |
1
admin/css/icons/bx-at.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10c1.466 0 2.961-.371 4.442-1.104l-.885-1.793C14.353 19.698 13.156 20 12 20c-4.411 0-8-3.589-8-8s3.589-8 8-8s8 3.589 8 8v1c0 .692-.313 2-1.5 2c-1.396 0-1.494-1.819-1.5-2V8h-2v.025A4.954 4.954 0 0 0 12 7c-2.757 0-5 2.243-5 5s2.243 5 5 5c1.45 0 2.748-.631 3.662-1.621c.524.89 1.408 1.621 2.838 1.621c2.273 0 3.5-2.061 3.5-4v-1c0-5.514-4.486-10-10-10zm0 13c-1.654 0-3-1.346-3-3s1.346-3 3-3s3 1.346 3 3s-1.346 3-3 3z" fill="#8691b2"/><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 814 B |
1
admin/css/icons/bx-news.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M19.875 3H4.125C2.953 3 2 3.897 2 5v14c0 1.103.953 2 2.125 2h15.75C21.047 21 22 20.103 22 19V5c0-1.103-.953-2-2.125-2zm0 16H4.125c-.057 0-.096-.016-.113-.016c-.007 0-.011.002-.012.008L3.988 5.046c.007-.01.052-.046.137-.046h15.75c.079.001.122.028.125.008l.012 13.946c-.007.01-.052.046-.137.046z" fill="#8691b2"/><path d="M6 7h6v6H6zm7 8H6v2h12v-2h-4zm1-4h4v2h-4zm0-4h4v2h-4z" fill="#8691b2"/><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 736 B |
1
admin/css/icons/container-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="36" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 36 36" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M32 6H4a2 2 0 0 0-2 2v20a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM9.63 24.23a.79.79 0 0 1-.81.77a.79.79 0 0 1-.82-.77V11.77a.79.79 0 0 1 .82-.77a.79.79 0 0 1 .81.77zm6 0a.79.79 0 0 1-.82.77a.79.79 0 0 1-.81-.77V11.77a.79.79 0 0 1 .81-.77a.79.79 0 0 1 .82.77zm6.21 0a.79.79 0 0 1-.82.77a.79.79 0 0 1-.81-.77V11.77a.79.79 0 0 1 .81-.77a.79.79 0 0 1 .82.77zm6.12 0a.79.79 0 0 1-.82.77a.79.79 0 0 1-.81-.77V11.77a.79.79 0 0 1 .81-.77a.79.79 0 0 1 .82.77z" class="clr-i-solid clr-i-solid-path-1" fill="#8691b2"/><rect x="0" y="0" width="36" height="36" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 859 B |
1
admin/css/icons/double-right-outlined.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" preserveAspectRatio="xMidYMid meet" viewBox="0 0 1024 1024" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M533.2 492.3L277.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H188c-6.7 0-10.4 7.7-6.3 12.9L447.1 512L181.7 851.1A7.98 7.98 0 0 0 188 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5zm304 0L581.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H492c-6.7 0-10.4 7.7-6.3 12.9L751.1 512L485.7 851.1A7.98 7.98 0 0 0 492 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5z" fill="#8691b2"/><rect x="0" y="0" width="1024" height="1024" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 747 B |
1
admin/css/icons/email.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M28 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zm-2.2 2L16 14.78L6.2 8zM4 24V8.91l11.43 7.91a1 1 0 0 0 1.14 0L28 8.91V24z" fill="#8691b2"/><rect x="0" y="0" width="32" height="32" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 508 B |
1
admin/css/icons/image.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g fill="none"><path d="M2 6a4 4 0 0 1 4-4h12a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V6z" stroke="#8691b2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="8.5" cy="8.5" r="2.5" stroke="#8691b2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M14.526 12.621L6 22h12.27A3.73 3.73 0 0 0 22 18.27c0-.466-.175-.915-.49-1.26l-4.03-4.395a2 2 0 0 0-2.954.006z" stroke="#8691b2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></g><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 837 B |
1
admin/css/icons/language.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1792" height="1792" preserveAspectRatio="xMidYMid meet" viewBox="0 0 1792 1792" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M891 689q-6-87-66-144q-30-27-50-37.5T715 488q1-5 4.5-26t6.5-35l-91-12l-10 50q-79-14-136 3V354q151-6 306-23l-14-94q-126 21-286 29q2-30 6-49t6-37q-5 0-36-.5t-53-.5q-2 18-5.5 40t-5.5 51l-154 3l14 94l120-6l5 137q-100 50-150.5 114T191 781q0 64 30 97t75 33.5t94-17t89-49.5l18 36l72-46l-21-43q34-34 54-56.5t50.5-71.5T700 562q60 17 82 43t19 86q-48 10-80 48t-32 88v25q-37 10-81 13l46 73q5-1 35-6v68H179q-31 0-53-22.5T104 924V179q0-31 22-53t53-22h745q31 0 53.5 22t22.5 53v510H891zm212 0V138q0-57-41-97.5T965 0H138Q81 0 40.5 40.5T0 138v827q0 56 40.5 97t97.5 41h551v551q0 57 41 97.5t97 40.5h827q57 0 97.5-40.5t40.5-97.5V827q0-56-40.5-97t-97.5-41h-551zM401 584q10 120 32 181q-17 16-40.5 31T343 821t-44-1.5t-18-47.5q0-60 33-111t87-77zm90-33q54-26 119-7q-7 25-19.5 47.5t-22.5 35t-28 34.5l-27 33q-5-13-9-26t-6-21t-3.5-24t-2-20.5t-1-26t-.5-25.5zm504 1069H863l310-758h135l310 758h-132l-89-218h-312zm246-599l-116 281h231z" fill="#8691b2"/><rect x="0" y="0" width="1792" height="1792" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
admin/css/icons/letter-aa.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M23 13h-5v2h5v2h-4a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h6v-8a2 2 0 0 0-2-2zm0 8h-4v-2h4z" fill="#8691b2"/><path d="M13 9H9a2 2 0 0 0-2 2v12h2v-5h4v5h2V11a2 2 0 0 0-2-2zm-4 7v-5h4v5z" fill="#8691b2"/><rect x="0" y="0" width="32" height="32" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 537 B |
1
admin/css/icons/list-settings-line.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M2 18h7v2H2v-2zm0-7h9v2H2v-2zm0-7h20v2H2V4zm18.674 9.025l1.156-.391l1 1.732l-.916.805a4.017 4.017 0 0 1 0 1.658l.916.805l-1 1.732l-1.156-.391c-.41.37-.898.655-1.435.83L19 21h-2l-.24-1.196a3.996 3.996 0 0 1-1.434-.83l-1.156.392l-1-1.732l.916-.805a4.017 4.017 0 0 1 0-1.658l-.916-.805l1-1.732l1.156.391c.41-.37.898-.655 1.435-.83L17 11h2l.24 1.196c.536.174 1.024.46 1.434.83zM18 18a2 2 0 1 0 0-4a2 2 0 0 0 0 4z" fill="#8691b2"/><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 771 B |
1
admin/css/icons/menu-alt.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" preserveAspectRatio="xMidYMid meet" viewBox="0 0 20 20" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M3 11h14V9H3v2zm0 5h14v-2H3v2zM3 4v2h14V4H3z" fill="#8691b2"/><rect x="0" y="0" width="20" height="20" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 407 B |
1
admin/css/icons/news-24-regular.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g fill="none"><path d="M18.75 20H5.25a3.25 3.25 0 0 1-3.245-3.066L2 16.75V6.25a2.25 2.25 0 0 1 2.096-2.245L4.25 4h12.5a2.25 2.25 0 0 1 2.245 2.096L19 6.25V7h.75a2.25 2.25 0 0 1 2.245 2.096L22 9.25v7.5a3.25 3.25 0 0 1-3.066 3.245L18.75 20H5.25h13.5zm-13.5-1.5h13.5a1.75 1.75 0 0 0 1.744-1.607l.006-.143v-7.5a.75.75 0 0 0-.648-.743L19.75 8.5H19v7.75a.75.75 0 0 1-.648.743L18.25 17a.75.75 0 0 1-.743-.648l-.007-.102v-10a.75.75 0 0 0-.648-.743L16.75 5.5H4.25a.75.75 0 0 0-.743.648L3.5 6.25v10.5a1.75 1.75 0 0 0 1.606 1.744l.144.006h13.5h-13.5zm6.996-4h3.006a.75.75 0 0 1 .102 1.493l-.102.007h-3.006a.75.75 0 0 1-.102-1.493l.102-.007h3.006h-3.006zm-3.003-3.495a.75.75 0 0 1 .75.75v3.495a.75.75 0 0 1-.75.75H5.748a.75.75 0 0 1-.75-.75v-3.495a.75.75 0 0 1 .75-.75h3.495zm-.75 1.5H6.498V14.5h1.995v-1.995zm3.753-1.5h3.006a.75.75 0 0 1 .102 1.493l-.102.007h-3.006a.75.75 0 0 1-.102-1.494l.102-.006h3.006h-3.006zM5.748 7.502h9.504a.75.75 0 0 1 .102 1.494l-.102.006H5.748a.75.75 0 0 1-.102-1.493l.102-.007h9.504h-9.504z" fill="#8691b2"/></g><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
admin/css/icons/people-fill.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g fill="#8691b2"><path d="M7 14s-1 0-1-1s1-4 5-4s5 3 5 4s-1 1-1 1H7zm4-6a3 3 0 1 0 0-6a3 3 0 0 0 0 6z"/><path fill-rule="evenodd" d="M5.216 14A2.238 2.238 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1h4.216z"/><path d="M4.5 8a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5z"/></g><rect x="0" y="0" width="16" height="16" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 641 B |
1
admin/css/icons/photo-video.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="512" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 512" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M608 0H160a32 32 0 0 0-32 32v96h160V64h192v320h128a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zM232 103a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm352 208a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm-168 57H32a32 32 0 0 0-32 32v288a32 32 0 0 0 32 32h384a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32zM96 224a32 32 0 1 1-32 32a32 32 0 0 1 32-32zm288 224H64v-32l64-64l32 32l128-128l96 96z" fill="#8691b2"/><rect x="0" y="0" width="640" height="512" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 939 B |
1
admin/css/icons/send.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g fill="none" stroke="#8691b2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 2L11 13"/><path d="M22 2l-7 20l-4-9l-9-4l20-7z"/></g><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 498 B |
1
admin/css/icons/settings-20-filled.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" preserveAspectRatio="xMidYMid meet" viewBox="0 0 20 20" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g fill="none"><path d="M1.91 7.383a8.491 8.491 0 0 1 1.781-3.08a.5.5 0 0 1 .54-.135l1.918.686a1 1 0 0 0 1.32-.762l.365-2.006a.5.5 0 0 1 .388-.4a8.532 8.532 0 0 1 3.555 0a.5.5 0 0 1 .388.4l.366 2.006a1 1 0 0 0 1.32.762l1.919-.686a.5.5 0 0 1 .539.136a8.491 8.491 0 0 1 1.78 3.079a.5.5 0 0 1-.152.535l-1.555 1.32a1 1 0 0 0 0 1.524l1.555 1.32a.5.5 0 0 1 .152.535a8.491 8.491 0 0 1-1.78 3.08a.5.5 0 0 1-.54.135l-1.918-.686a1 1 0 0 0-1.32.762l-.367 2.007a.5.5 0 0 1-.387.399a8.53 8.53 0 0 1-3.555 0a.5.5 0 0 1-.388-.4l-.365-2.006a1 1 0 0 0-1.32-.762l-1.919.686a.5.5 0 0 1-.539-.136a8.49 8.49 0 0 1-1.78-3.079a.5.5 0 0 1 .152-.535l1.555-1.32a1 1 0 0 0 0-1.524l-1.555-1.32a.5.5 0 0 1-.152-.535zM8 10a2 2 0 1 0 4 0a2 2 0 0 0-4 0z" fill="#8691b2"/></g><rect x="0" y="0" width="20" height="20" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
admin/css/icons/template-2.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><path d="M26 6v4H6V6h20m0-2H6a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h20a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z" fill="#8691b2"/><path d="M10 16v10H6V16h4m0-2H6a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V16a2 2 0 0 0-2-2z" fill="#8691b2"/><path d="M26 16v10H16V16h10m0-2H16a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V16a2 2 0 0 0-2-2z" fill="#8691b2"/><rect x="0" y="0" width="32" height="32" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 679 B |
1
admin/css/icons/template.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g class="icon-tabler" fill="none" stroke="#8691b2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="4" rx="1"/><rect x="4" y="12" width="6" height="8" rx="1"/><path d="M14 12h6"/><path d="M14 16h6"/><path d="M14 20h6"/></g><rect x="0" y="0" width="24" height="24" fill="rgba(0, 0, 0, 0)" /></svg>
|
||||
|
After Width: | Height: | Size: 612 B |
BIN
admin/css/lang-de.jpg
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
admin/css/lang-en.jpg
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
admin/css/lang-fr.jpg
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
admin/css/lang-it.jpg
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
admin/css/lang-pl.jpg
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
admin/css/lang-ru.jpg
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
admin/css/lang-uk.jpg
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
admin/css/user-icon.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
86
admin/index.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?
|
||||
if ( file_exists( 'ip.conf' ) )
|
||||
{
|
||||
$ips = file_get_contents( 'ip.conf' );
|
||||
$ips = preg_split( "/\\r\\n|\\r|\\n/", $ips );
|
||||
$ips = array_filter( $ips );
|
||||
if ( is_array( $ips ) and !empty( $ips ) )
|
||||
{
|
||||
if ( !in_array( $_SERVER['REMOTE_ADDR'], $ips ) )
|
||||
die( 'Brak dostępu.' );
|
||||
}
|
||||
}
|
||||
|
||||
error_reporting( E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED );
|
||||
function __autoload_my_classes( $classname )
|
||||
{
|
||||
$q = explode( '\\' , $classname );
|
||||
$c = array_pop( $q );
|
||||
$f = '../autoload/' . implode( '/' , $q ) . '/class.' . $c . '.php';
|
||||
if ( file_exists( $f ) )
|
||||
require_once( $f );
|
||||
}
|
||||
spl_autoload_register( '__autoload_my_classes' );
|
||||
|
||||
require_once '../config.php';
|
||||
require_once '../libraries/medoo/medoo.php';
|
||||
require_once '../libraries/grid/config.php';
|
||||
date_default_timezone_set( 'Europe/Warsaw' );
|
||||
|
||||
$settings = \front\factory\Settings::settings_details();
|
||||
|
||||
if ( file_exists( 'config.php' ) )
|
||||
include 'config.php';
|
||||
|
||||
session_start();
|
||||
|
||||
if ( !isset( $_SESSION['check'] ) )
|
||||
{
|
||||
session_regenerate_id();
|
||||
$_SESSION['check'] = true;
|
||||
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
if ( $_SESSION['ip'] !== $_SERVER['REMOTE_ADDR'] )
|
||||
{
|
||||
session_destroy();
|
||||
header( 'Location: /admin/' );
|
||||
exit;
|
||||
}
|
||||
|
||||
$mdb = new medoo( [
|
||||
'database_type' => 'mysql',
|
||||
'database_name' => $database['name'],
|
||||
'server' => $database['host'],
|
||||
'username' => $database['user'],
|
||||
'password' => $database['password'],
|
||||
'charset' => 'utf8'
|
||||
] );
|
||||
|
||||
$user = \S::get_session( 'user' , true );
|
||||
|
||||
\admin\Site::special_actions();
|
||||
|
||||
$domain = preg_replace( '#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME'] );
|
||||
$cookie_name = str_replace( '.', '-', $domain );
|
||||
|
||||
if ( isset( $_COOKIE[$cookie_name] ) && !isset( $_SESSION['user'] ) )
|
||||
{
|
||||
$obj = json_decode( $_COOKIE[$cookie_name] );
|
||||
$login = $obj -> {'login'};
|
||||
$password = $obj -> {'hash'};
|
||||
|
||||
if ( $mdb -> get( 'pp_users', '*',
|
||||
[ 'AND' =>
|
||||
[ 'login' => $login, 'status' => 1, 'password' => $password,
|
||||
'OR' => [ 'active_to[>=]' => date( 'Y-m-d' ), 'active_to' => null ]
|
||||
]
|
||||
] ) )
|
||||
{
|
||||
\S::set_session( 'user', \admin\factory\Users::details( $login ) );
|
||||
header( 'Location: /admin/articles/view_list/' );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo \admin\view\Page::show();
|
||||
?>
|
||||
0
admin/ip.conf
Normal file
BIN
admin/temp/4/b/s_cache_4b916ae533b4ded88ddc3edfe99de1be
Normal file
20
admin/templates/.htaccess
Normal file
@@ -0,0 +1,20 @@
|
||||
# Wyłącz listowanie
|
||||
Options -Indexes
|
||||
|
||||
# Domyślnie blokujemy wszystko…
|
||||
Require all denied
|
||||
|
||||
# …a dopiero potem pozwalamy na pliki statyczne
|
||||
<FilesMatch "\.(css|js|map|mjs|png|jpe?g|gif|svgz?|webp|ico|woff2?|woff|ttf|eot)$">
|
||||
Require all granted
|
||||
</FilesMatch>
|
||||
|
||||
# Twardo blokuj cokolwiek, co mogłoby się wykonać
|
||||
<FilesMatch "\.(php|phtml|php[0-9]?|phar|pht|cgi|pl|py|sh)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
# Nie serwuj plików ukrytych (.env itp.)
|
||||
<FilesMatch "^\.(.*)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
1205
admin/templates/articles/article-edit.php
Normal file
67
admin/templates/articles/articles-archive-list.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_articles' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> sql = 'SELECT *'
|
||||
. 'FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, date_add, date_modify, status, '
|
||||
. '( SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = pa.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_articles AS pa WHERE status = -1 '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] '
|
||||
. 'ORDER BY '
|
||||
. '[order_p1] [order_p2]';
|
||||
$grid -> sql_count = 'SELECT '
|
||||
. 'COUNT(0) FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, date_add, date_modify, status, '
|
||||
. '( SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = pa.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_articles AS pa WHERE status = -1 '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] ';
|
||||
$grid -> debug = true;
|
||||
$grid -> order = [ 'column' => 'date_add', 'type' => 'DESC' ];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Tytuł',
|
||||
'db' => 'id',
|
||||
'replace' => [ 'sql' => "SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = [id] AND title != '' ORDER BY o ASC LIMIT 1" ]
|
||||
],
|
||||
[
|
||||
'name' => 'Data dodania',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 140px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[date_add]" ) );'
|
||||
],
|
||||
[
|
||||
'name' => 'Data modyfikacji',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 140px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[date_modify]" ) );'
|
||||
],
|
||||
[
|
||||
'name' => 'Akcja',
|
||||
'th' => [ 'class' => 'g-center' ],
|
||||
'td' => [ 'class' => 'g-center', 'style' => 'width: 50px;' ],
|
||||
'content' => '<a href="/admin/articles_archive/article_restore/id=[id]">przywróć</a>'
|
||||
],
|
||||
[
|
||||
'name' => 'Akcja',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/articles_archive/article_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center' ],
|
||||
'td' => [ 'class' => 'g-center', 'style' => 'width: 50px;' ]
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
121
admin/templates/articles/articles-browse-list.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_articles' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> sql = 'SELECT *'
|
||||
. 'FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, date_add, date_modify, status, '
|
||||
. '( SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = pa.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title, '
|
||||
. '( SELECT login FROM pp_users AS pu WHERE pu.id = pa.modify_by ) AS user '
|
||||
. 'FROM '
|
||||
. 'pp_articles AS pa WHERE status != -1 '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] '
|
||||
. 'ORDER BY '
|
||||
. '[order_p1] [order_p2]';
|
||||
$grid -> sql_count = 'SELECT '
|
||||
. 'COUNT(0) FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, date_add, date_modify, status, '
|
||||
. '( SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = pa.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title, '
|
||||
. '( SELECT login FROM pp_users AS pu WHERE pu.id = pa.modify_by ) AS user '
|
||||
. 'FROM '
|
||||
. 'pp_articles AS pa WHERE status != -1 '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] ';
|
||||
$grid -> debug = true;
|
||||
$grid -> order = [ 'column' => 'date_add', 'type' => 'DESC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Tytuł', 'db' => 'title', 'type' => 'text' ],
|
||||
[ 'name' => 'Aktywny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ],
|
||||
[ 'name' => 'Data dodania', 'db' => 'date_add', 'type' => 'date_range' ],
|
||||
[ 'name' => 'Data modyfikacji', 'db' => 'date_modify', 'type' => 'date_range' ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Tytuł',
|
||||
'db' => 'title',
|
||||
'sort' => true,
|
||||
'php' => 'echo "[title]"; echo "<small class=\'text-muted\'>" . \admin\factory\Articles::article_pages( [id] ) . "</small>";'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Data dodania',
|
||||
'db' => 'date_add',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 220px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[date_add]" ) );'
|
||||
],
|
||||
[
|
||||
'name' => 'Data modyfikacji',
|
||||
'db' => 'date_modify',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 220px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[date_modify]" ) );'
|
||||
],
|
||||
[
|
||||
'name' => 'Modyfikowany przez',
|
||||
'db' => 'user',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 220px;' ],
|
||||
],
|
||||
[
|
||||
'name' => 'Akcja',
|
||||
'db' => 'id',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 120px;' ],
|
||||
'php' => 'echo "<a href=\'#\' class=\'button\' url=\'/" . \admin\factory\Articles::article_url( [id] ) . "\'>wybierz</a>";'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<style type="text/css">
|
||||
<? if ( $this -> modal ):?>
|
||||
.menu-left, .navbar {
|
||||
display: none;
|
||||
}
|
||||
.site-content {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
<? endif;?>
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function getUrlParam(paramName)
|
||||
{
|
||||
var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i');
|
||||
var match = window.location.search.match(reParam);
|
||||
|
||||
return (match && match.length > 1) ? match[1] : '';
|
||||
}
|
||||
|
||||
$( function()
|
||||
{
|
||||
$( '#sidebar_left, .navbar-fixed-top' ).hide();
|
||||
|
||||
var funcNum = getUrlParam('CKEditorFuncNum');
|
||||
|
||||
$( 'body' ).on( 'click', '.button', function()
|
||||
{
|
||||
window.opener.CKEDITOR.tools.callFunction(funcNum, $( this ).attr( 'url' ) );
|
||||
window.close();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
144
admin/templates/articles/articles-list.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_articles' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> sql = 'SELECT *'
|
||||
. 'FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, date_add, date_modify, status, '
|
||||
. '( SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = pa.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title, '
|
||||
. '( SELECT login FROM pp_users AS pu WHERE pu.id = pa.modify_by ) AS user '
|
||||
. 'FROM '
|
||||
. 'pp_articles AS pa WHERE status != -1 '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] '
|
||||
. 'ORDER BY '
|
||||
. '[order_p1] [order_p2]';
|
||||
$grid -> sql_count = 'SELECT '
|
||||
. 'COUNT(0) FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, date_add, date_modify, status, '
|
||||
. '( SELECT title FROM pp_articles_langs AS pal, pp_langs AS pl WHERE lang_id = pl.id AND article_id = pa.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title, '
|
||||
. '( SELECT login FROM pp_users AS pu WHERE pu.id = pa.modify_by ) AS user '
|
||||
. 'FROM '
|
||||
. 'pp_articles AS pa WHERE status != -1 '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] ';
|
||||
$grid -> debug = true;
|
||||
if ( !\S::get_session( 'gpp_articlesorder' ) )
|
||||
$grid -> order = [ 'column' => 'date_add', 'type' => 'DESC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Tytuł', 'db' => 'title', 'type' => 'text' ],
|
||||
[ 'name' => 'Aktywny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ],
|
||||
[ 'name' => 'Data dodania', 'db' => 'date_add', 'type' => 'date_range' ],
|
||||
[ 'name' => 'Data modyfikacji', 'db' => 'date_modify', 'type' => 'date_range' ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Tytuł',
|
||||
'db' => 'title',
|
||||
'sort' => true,
|
||||
'php' => 'echo "<a href=\'/admin/articles/article_edit/id=[id]\'>[title]</a>"; echo "<small class=\'text-muted\'>" . \admin\factory\Articles::article_pages( [id] ) . "</small>";'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Data dodania',
|
||||
'db' => 'date_add',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 220px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[date_add]" ) );',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Data modyfikacji',
|
||||
'db' => 'date_modify',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 220px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[date_modify]" ) );',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Modyfikowany przez',
|
||||
'db' => 'user',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 220px;' ],
|
||||
], [
|
||||
'name' => 'Akcja',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 120px;' ],
|
||||
'php' => 'echo "<a href=\'#\' class=\'duplicate-article\' article-id=\'[id]\'>duplikuj</a>";'
|
||||
], [
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/articles/article_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/articles/article_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj artykuł',
|
||||
'url' => '/admin/articles/article_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$( function() {
|
||||
$( 'body' ).on( 'click', '.duplicate-article', function(e) {
|
||||
e.preventDefault();
|
||||
var article_id = $( this ).attr( 'article-id' );
|
||||
$.alert(
|
||||
{
|
||||
title: 'Potwierdź',
|
||||
content: 'Na pewno chcesz zduplikować wybrany artykuł?',
|
||||
type: 'orange',
|
||||
closeIcon: true,
|
||||
closeIconClass: 'fa fa-close',
|
||||
typeAnimated: true,
|
||||
animation: 'opacity',
|
||||
theme: 'modern',
|
||||
columnClass: 'col-lg-8 col-lg-offset-2',
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: 'Zatwierdź',
|
||||
btnClass: 'btn-blue',
|
||||
keys: ['enter'],
|
||||
action: function() {
|
||||
document.location.href = '/admin/articles/duplicate_article/id=' + article_id;
|
||||
}
|
||||
},
|
||||
cancel:
|
||||
{
|
||||
text: 'Zamknij',
|
||||
btnClass: 'btn-dark',
|
||||
action: function() {}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
16
admin/templates/articles/subpages-list.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<? if ( is_array( $this -> pages ) ):?>
|
||||
<ol>
|
||||
<? foreach ( $this -> pages as $page ):?>
|
||||
<li id="list_<?= $page['id'];?>" idk="<?= $page['id'];?>" class="sort-nonesting list_<?= $page['id'];?>" menu="<?= $page['menu_id'];?>">
|
||||
<div class="content <?= $this -> step < 2 ? $tmp = 'content_page' : $tmp = 'content_page_last_level';?>" <? if ( !$page['status'] ) echo 'style="color: #cc0000;"';?>>
|
||||
<span class="disclose"><span></span></span>
|
||||
<input type="checkbox" class="g-checkbox" name="pages" value="<?= $page['id'];?>" <? if ( is_array( $this -> article_pages ) and in_array( $page['id'], $this -> article_pages ) ):?>checked="checked"<? endif;?> /><?= $page['title'];?>
|
||||
</div>
|
||||
<?
|
||||
if ( is_array( $page['subpages'] ) )
|
||||
echo \admin\view\Articles::subpages_list( $page['subpages'], $this -> article_pages, $page['id'], $this -> step + 1 );
|
||||
?>
|
||||
</li>
|
||||
<? endforeach;?>
|
||||
</ol>
|
||||
<? endif;?>
|
||||
112
admin/templates/authors/author-edit.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
|
||||
<?
|
||||
\S::set_session( 'admin', true );
|
||||
global $db;
|
||||
ob_start();
|
||||
?>
|
||||
<div id="settings-tabs">
|
||||
<ul class="resp-tabs-list settings-tabs">
|
||||
<li><i class="fa fa-wrench"></i>Ustawienia</li>
|
||||
<li><i class="fa fa-file"></i>Zawartość</li>
|
||||
</ul>
|
||||
<div class="resp-tabs-container settings-tabs">
|
||||
<div>
|
||||
<?= \Html::input( [
|
||||
'label' => 'Autor',
|
||||
'name' => 'author',
|
||||
'id' => 'author',
|
||||
'value' => $this -> author['author'],
|
||||
'class' => 'require'
|
||||
] );?>
|
||||
<?= \Html::input_icon( [
|
||||
'label' => 'Zdjęcie',
|
||||
'name' => 'image',
|
||||
'id' => 'image',
|
||||
'value' => $this -> author['image'],
|
||||
'icon_content' => 'przeglądaj',
|
||||
'icon_js' => "window.open ( '/libraries/filemanager-9.14.1/dialog.php?type=1&popup=1&field_id=image&akey=c3cb2537d25c0efc9e573d059d79c3b8', 'mywindow', 'location=1,status=1,scrollbars=1, width=1100,height=700');"
|
||||
] );?>
|
||||
</div>
|
||||
<div>
|
||||
<div id="languages-main">
|
||||
<ul class="resp-tabs-list languages-main">
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
<? if ( $lg['status'] ):?>
|
||||
<li><?= $lg['name'];?></a></li>
|
||||
<? endif;?>
|
||||
<? endforeach;
|
||||
endif;?>
|
||||
</ul>
|
||||
<div class="resp-tabs-container languages-main">
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
<? if ( $lg['status'] ):?>
|
||||
<div>
|
||||
<?= \Html::textarea( [
|
||||
'label' => 'Opis',
|
||||
'name' => 'description',
|
||||
'id' => 'description_' . $lg['id'],
|
||||
'value' => $this -> author['languages'][$lg['id']]['description']
|
||||
] );?>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('#description_<?= $lg['id'];?>').ckeditor({
|
||||
toolbar: 'MyTool',
|
||||
height: '300'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<? endif;?>
|
||||
<? endforeach; endif;?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'author-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja autora';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> author['id']
|
||||
]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/authors/save/', 'back_url' => '/admin/authors/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/authors/view_list/' ]
|
||||
];
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(function ()
|
||||
{
|
||||
disable_menu();
|
||||
|
||||
$( '#settings-tabs' ).easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'settings-tabs',
|
||||
type: 'vertical'
|
||||
});
|
||||
|
||||
$('#languages-main').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-main'
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>
|
||||
41
admin/templates/authors/view-list.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_authors' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'author', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'author' => 'Autor', 'db' => 'name', 'type' => 'text' ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
], [
|
||||
'name' => 'Autor',
|
||||
'db' => 'author',
|
||||
'sort' => true,
|
||||
'php' => 'echo "<a href=\"/admin/authors/edit/id=[id]\">[author]</a>";'
|
||||
], [
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/authors/edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
], [
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/authors/delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj autora',
|
||||
'url' => '/admin/authors/edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
65
admin/templates/backups/backup-list.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_backups' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> src = $this -> backups;
|
||||
$grid -> debug = true;
|
||||
$grid -> order = [ 'column' => 'name', 'type' => 'DESC' ];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Nazwa',
|
||||
'db' => 'name',
|
||||
'sort' => true,
|
||||
'php' => 'echo "<a href=\'/../backups/[name]\' target=\'_blank\'>[name]</a>";'
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/backups/backup_delete/name=[name]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Utwórz kopie zapasową',
|
||||
'url' => '#',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'confirm btn btn-success btn-sm mr5"'
|
||||
],
|
||||
[
|
||||
'label' => 'Pobierz plik restore.php',
|
||||
'url' => '/admin/backups/download_restore_file/',
|
||||
'icon' => 'fa-download',
|
||||
'class' => 'btn btn-system btn-sm mr5"'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script>
|
||||
$(document).ready(function ()
|
||||
{
|
||||
$('body').on('click', '.confirm', function ()
|
||||
{
|
||||
$.prompt('Na pewno chcesz utworzyć kopię zapasową ?',
|
||||
{
|
||||
title: 'Potwierdź utworzenie',
|
||||
submit: function (e, v, m, f)
|
||||
{
|
||||
if ( v === true)
|
||||
document.location.href = '/admin/backups/backup_save/';
|
||||
},
|
||||
buttons: {
|
||||
'tak': true, 'nie': false
|
||||
},
|
||||
focus: 1
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
185
admin/templates/banners/banner-edit.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
|
||||
<?
|
||||
\S::set_session( 'admin', true );
|
||||
global $db;
|
||||
|
||||
$_SESSION['rfm_akey'] = bin2hex(random_bytes(16));
|
||||
$_SESSION['rfm_akey_expires'] = time() + 20*60;
|
||||
$_SESSION['can_use_rfm'] = true;
|
||||
$rfmAkeyJS = $_SESSION['rfm_akey'];
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div id="settings-tabs">
|
||||
<ul class="resp-tabs-list settings-tabs">
|
||||
<li><i class="fa fa-wrench"></i>Ustawienia</li>
|
||||
<li><i class="fa fa-file"></i>Zawartość</li>
|
||||
</ul>
|
||||
<div class="resp-tabs-container settings-tabs">
|
||||
<div>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Nazwa',
|
||||
'name' => 'name',
|
||||
'id' => 'name',
|
||||
'value' => $this -> banner['name'],
|
||||
'class' => 'require'
|
||||
) );
|
||||
?>
|
||||
<?= \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Aktywny',
|
||||
'name' => 'status',
|
||||
'checked' => $this -> banner['status'] == 1 or ! $this -> banner['id'] ? true : false
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= Html::input(
|
||||
array(
|
||||
'label' => 'Data rozpoczęcia',
|
||||
'name' => 'date_start',
|
||||
'id' => 'date_start',
|
||||
'value' => $this -> banner['date_start'],
|
||||
'class' => 'date'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Data zakończenia',
|
||||
'name' => 'date_end',
|
||||
'id' => 'date_end',
|
||||
'value' => $this -> banner['date_end'],
|
||||
'class' => 'date'
|
||||
) );
|
||||
?>
|
||||
<?= \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Slajder / Strona główna',
|
||||
'name' => 'home_page',
|
||||
'checked' => $this -> banner['home_page'] == 1 ? true : false
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<div>
|
||||
<div id="languages-main">
|
||||
<ul class="resp-tabs-list languages-main">
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
<? if ( $lg['status'] ):?>
|
||||
<li><?= $lg['name'];?></a></li>
|
||||
<? endif;?>
|
||||
<? endforeach;
|
||||
endif;?>
|
||||
</ul>
|
||||
<div class="resp-tabs-container languages-main">
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
<? if ( $lg['status'] ):?>
|
||||
<div>
|
||||
<?= \Html::input_icon(
|
||||
array(
|
||||
'label' => 'Obraz',
|
||||
'name' => 'src',
|
||||
'id' => 'src_' . $lg['id'],
|
||||
'value' => $this -> banner['languages'][ $lg['id'] ]['src'],
|
||||
'icon_content' => 'przeglądaj',
|
||||
'icon_js' => "window.open ( '/libraries/filemanager-9.14.1/dialog.php?type=1&popup=1&field_id=src_" . $lg['id'] . "&akey=" . $rfmAkeyJS . "', 'mywindow', 'location=1,status=1,scrollbars=1, width=1100,height=700');"
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Url',
|
||||
'name' => 'url',
|
||||
'id' => 'url_' . $lg['id'],
|
||||
'value' => $this -> banner['languages'][ $lg['id'] ]['url']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::textarea(
|
||||
array(
|
||||
'label' => 'Kod html',
|
||||
'name' => 'html',
|
||||
'id' => 'html_' . $lg['id'],
|
||||
'value' => $this -> banner['languages'][$lg['id']]['html']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::textarea(
|
||||
array(
|
||||
'label' => 'Treść',
|
||||
'name' => 'text',
|
||||
'id' => 'text_' . $lg['id'],
|
||||
'value' => $this -> banner['languages'][$lg['id']]['text']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('#text_<?= $lg['id'];?>').ckeditor({
|
||||
toolbar: 'MyTool',
|
||||
height: '300'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<? endif;?>
|
||||
<? endforeach; endif;?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'banner-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja baneru';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> banner['id']
|
||||
]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/banners/banner_save/', 'back_url' => '/admin/banners/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/banners/view_list/' ]
|
||||
];
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(function ()
|
||||
{
|
||||
disable_menu();
|
||||
|
||||
$('input[type="text"].date').datetimepicker({
|
||||
format: "YYYY-MM-DD",
|
||||
pickTime: false
|
||||
});
|
||||
|
||||
$( '#settings-tabs' ).easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'settings-tabs',
|
||||
type: 'vertical'
|
||||
});
|
||||
|
||||
$('#languages-main').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-main'
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>
|
||||
78
admin/templates/banners/banners-list.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_banners' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'name', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Nazwa', 'db' => 'name', 'type' => 'text' ],
|
||||
[ 'name' => 'Aktywny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Nazwa',
|
||||
'db' => 'name',
|
||||
'sort' => true,
|
||||
'php' => 'echo "<a href=\"/admin/banners/banner_edit/id=[id]\">[name]</a>";'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Strona główna',
|
||||
'db' => 'home_page',
|
||||
'replace' => [ 'array' => [ 0 => 'nie', 1 => '<span class="text-system">tak</span>' ] ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Slajder',
|
||||
'db' => 'home_page',
|
||||
'replace' => [ 'array' => [ 1 => 'nie', 0 => '<span class="text-system">tak</span>' ] ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Data rozpoczęcia',
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 140px;' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'php' => 'if ( "[date_start]" ) echo date( "Y-m-d", strtotime( "[date_start]" ) ); else echo "-";'
|
||||
],
|
||||
[
|
||||
'name' => 'Data zakończenia',
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 140px;' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'php' => 'if ( "[date_end]" ) echo date( "Y-m-d", strtotime( "[date_end]" ) ); else echo "-";'
|
||||
],
|
||||
[
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/banners/banner_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/banners/banner_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj baner',
|
||||
'url' => '/admin/banners/banner_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
56
admin/templates/emails/email-details.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
global $db;
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="form-group ">
|
||||
<label class="col-lg-3 control-label text-right">Email:</label>
|
||||
<div class="col-lg-9">
|
||||
<p><?= $this -> email['email'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group ">
|
||||
<label class="col-lg-3 control-label text-right">Numer telefonu:</label>
|
||||
<div class="col-lg-9">
|
||||
<p><?= $this -> email['phone'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group ">
|
||||
<label class="col-lg-3 control-label text-right">Temat:</label>
|
||||
<div class="col-lg-9">
|
||||
<p><?= $this -> email['title'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group ">
|
||||
<label class="col-lg-3 control-label text-right">Wiadomość:</label>
|
||||
<div class="col-lg-9">
|
||||
<p><?= nl2br($this -> email['mail']);?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group ">
|
||||
<label class="col-lg-3 control-label text-right">Data wysłania:</label>
|
||||
<div class="col-lg-9">
|
||||
<p><?= date( "Y-m-d H:i", strtotime( $this -> email[add_date] ) )?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit();
|
||||
$grid -> id = 'email-details';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> title = 'Szczegóły Wiadomości';
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [ '' => '/admin/emails/view_list/', 'back_url' => '/admin/emails/view_list/'],
|
||||
'cancel' => [ 'url' => '/admin/emails/view_list/' ]
|
||||
];
|
||||
$grid -> form = false;
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<style>
|
||||
#g-edit-save{
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
41
admin/templates/emails/emails-list.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_contact_emails' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Data',
|
||||
'db' => 'add_date',
|
||||
'td' => [ ],
|
||||
'th' => ['style' => 'width: 220px;' ],
|
||||
'php' => 'echo date( "Y-m-d H:i", strtotime( "[add_date]" ) );',
|
||||
'sort' => true
|
||||
|
||||
],
|
||||
[
|
||||
'name' => 'Email',
|
||||
'db' => 'email',
|
||||
'content' => '<a href="/admin/emails/email_details/id=[id]">[email]</a>',
|
||||
'sort' => true ,
|
||||
],
|
||||
[
|
||||
'name' => 'Temat',
|
||||
'db' => 'title',
|
||||
],
|
||||
[
|
||||
'name' => 'Szczegóły',
|
||||
'content' => '<a href="/admin/emails/email_details/id=[id]">Szczegóły</a>',
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
|
||||
echo $grid -> draw();
|
||||
7
admin/templates/filemanager/filemanager.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?
|
||||
$_SESSION['rfm_akey'] = bin2hex(random_bytes(16));
|
||||
$_SESSION['rfm_akey_expires'] = time() + 20*60;
|
||||
$_SESSION['can_use_rfm'] = true;
|
||||
$rfmAkeyJS = $_SESSION['rfm_akey'];
|
||||
?>
|
||||
<iframe src="/libraries/filemanager-9.14.1/dialog.php?akey=<?= $rfmAkeyJS ?>" style="border: 0px; width: 100%; height: 800px; background: #FFF; padding: 5px;"></iframe>
|
||||
25
admin/templates/html/button.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?
|
||||
$out = '<a ';
|
||||
$out .= 'class="btn ' . $this -> params['class'] . '" ';
|
||||
|
||||
if ( $this -> params['style'] )
|
||||
$out .= 'style="' . $this -> params['style'] . '" ';
|
||||
|
||||
if ( $this -> params['js'] )
|
||||
$out .= 'onclick="' . htmlspecialchars( $this -> params['js'] ) . '" ';
|
||||
|
||||
if ( $this -> params['url'] )
|
||||
$out .= 'href="' . htmlspecialchars( $this -> params['url'] ) . '" ';
|
||||
|
||||
if ( $this -> params['id'] )
|
||||
$out .= 'id="' . $this -> params['id'] . '" ';
|
||||
|
||||
if ( $this -> params['title'] )
|
||||
$out .= 'title="' . htmlspecialchars( $this -> params['title'] ) . '" ';
|
||||
$out .= '>';
|
||||
if ( $this -> params['icon'] )
|
||||
$out .= '<i class="fa ' . $this -> params['icon'] . ' mr5"></i>';
|
||||
$out .= $this -> params['text'];
|
||||
$out .= '</a>';
|
||||
|
||||
echo $out;
|
||||
8
admin/templates/html/form-text.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label"><?= $this -> params['label'];?>:</label>
|
||||
<div class="col-lg-9">
|
||||
<p class="form-control-static" id="<?= $this -> params['id'];?>">
|
||||
<?= $this -> params['text'];?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
70
admin/templates/html/input-icon.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '<div class="form-group ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'pl10 pr10';
|
||||
$out .= '">';
|
||||
$out .= '<label class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-3 ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'mb5 ';
|
||||
$out .= 'control-label">' . $this -> params['label'] . ':</label>';
|
||||
$out .= '<div class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-9';
|
||||
$out .= '">';
|
||||
}
|
||||
$out .= '<div class="input-group">';
|
||||
$out .= '<input ';
|
||||
$out .= 'type="' . $this -> params['type'] . '" ';
|
||||
|
||||
if ( $this -> params['id'] )
|
||||
$out .= 'id="' . $this -> params['id'] . '" ';
|
||||
|
||||
if ( $this -> params['class'] or $this -> params['label'] )
|
||||
{
|
||||
if ( $this -> params['label'] )
|
||||
$out .= 'class="' . $this -> params['class'] . ' form-control" ';
|
||||
else if ( $this -> params['class'] )
|
||||
$out .= 'class="' . $this -> params['class'] . '" ';
|
||||
}
|
||||
|
||||
$out .= 'name="' . $this -> params['name'] . '" ';
|
||||
$out .= 'value="' . $this -> secureHTML( $this -> params['value'] ) . '" ';
|
||||
|
||||
if ( $this -> params['js'] )
|
||||
$out .= 'onchange="' . htmlspecialchars( $this -> params['js'] ) . '" ';
|
||||
|
||||
if ( $this -> params['js_key'] )
|
||||
$out .= 'onkeyup="' . htmlspecialchars( $this -> params['js_key'] ) . '" ';
|
||||
|
||||
if ( $this -> params['style'] )
|
||||
$out .= 'style="' . $this -> params['style'] . '" ';
|
||||
|
||||
if ( $this -> params['readonly'] )
|
||||
$out .= 'readonly="readonly" ';
|
||||
|
||||
if ( $this -> params['autocomplete'] == 'off' )
|
||||
$out .= 'autocomplete="off" ';
|
||||
|
||||
$out .= ' />';
|
||||
|
||||
$out .= '<span class="input-group-addon btn btn-info ' . $this -> params['icon_class'] . '"';
|
||||
|
||||
if ( $this -> params['icon_js'] )
|
||||
$out .= 'onclick="' . htmlspecialchars( $this -> params['icon_js'] ) . '" ';
|
||||
|
||||
$out .= '>';
|
||||
$out .= $this -> params['icon_content'];
|
||||
$out .= '</span>';
|
||||
$out .= '</div>';
|
||||
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '</div>';
|
||||
$out .= '</div>';
|
||||
}
|
||||
|
||||
echo $out;
|
||||
36
admin/templates/html/input-switch.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '<div class="form-group">';
|
||||
$out .= '<label class="col-lg-3 control-label">' . $this -> params['label'] . ':</label>';
|
||||
$out .= '<div class="col-lg-9 pt5">';
|
||||
}
|
||||
|
||||
$out .= '<div class="switch switch-primary round switch-inline">';
|
||||
$out .= '<input ';
|
||||
|
||||
if ( $this -> params['id'] )
|
||||
$out .= 'id="' . $this -> params['id'] . '" ';
|
||||
else
|
||||
$out .= 'id="' . $this -> params['name'] . '" ';
|
||||
$out .= 'name="' . $this -> params['name'] . '" type="checkbox"';
|
||||
|
||||
if ( $this -> params['checked'] )
|
||||
$out .= 'checked="checked" ';
|
||||
|
||||
$out .= '>';
|
||||
$out .= '<label for="';
|
||||
if ( $this -> params['id'] )
|
||||
$out .= $this -> params['id'];
|
||||
else
|
||||
$out .= $this -> params['name'];
|
||||
$out .= '"></label>';
|
||||
$out .= '</div>';
|
||||
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '</div>';
|
||||
$out .= '</div>';
|
||||
}
|
||||
|
||||
echo $out;
|
||||
63
admin/templates/html/input.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '<div class="form-group ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'pl10 pr10';
|
||||
$out .= '">';
|
||||
$out .= '<label class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-3 ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'mb5 ';
|
||||
$out .= 'control-label">' . $this -> params['label'] . ':</label>';
|
||||
$out .= '<div class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-9';
|
||||
$out .= '">';
|
||||
}
|
||||
|
||||
$out .= '<input ';
|
||||
$out .= 'type="' . $this -> params['type'] . '" ';
|
||||
|
||||
if ( $this -> params['id'] )
|
||||
$out .= 'id="' . $this -> params['id'] . '" ';
|
||||
|
||||
if ( $this -> params['class'] or $this -> params['label'] )
|
||||
{
|
||||
if ( $this -> params['label'] )
|
||||
$out .= 'class="' . $this -> params['class'] . ' form-control" ';
|
||||
else if ( $this -> params['class'] )
|
||||
$out .= 'class="' . $this -> params['class'] . '" ';
|
||||
}
|
||||
|
||||
$out .= 'name="' . $this -> params['name'] . '" ';
|
||||
$out .= 'value="' . $this -> secureHTML( $this -> params['value'] ) . '" ';
|
||||
|
||||
if ( $this -> params['style'] )
|
||||
$out .= 'style="' . $this -> params['style'] . '" ';
|
||||
|
||||
if ( $this -> params['js'] )
|
||||
$out .= 'onchange="' . htmlspecialchars( $this -> params['js'] ) . '" ';
|
||||
|
||||
if ( $this -> params['js_key'] )
|
||||
$out .= 'onkeyup="' . htmlspecialchars( $this -> params['js_key'] ) . '" ';
|
||||
|
||||
if ( $this -> params['readonly'] )
|
||||
$out .= 'readonly="readonly" ';
|
||||
|
||||
if ( $this -> params['autocomplete'] == 'off' )
|
||||
$out .= 'autocomplete="off" ';
|
||||
|
||||
if ( is_array( $this -> params['params'] ) and count( $this -> params['params'] ) ) foreach ( $this -> params['params'] as $key => $val )
|
||||
$out .= $key . '="' . $val . '" ';
|
||||
|
||||
$out .= ' />';
|
||||
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '</div>';
|
||||
$out .= '</div>';
|
||||
}
|
||||
|
||||
echo $out;
|
||||
8
admin/templates/html/panel.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<div class="panel <?= $this -> params['class'];?>">
|
||||
<div class="panel-heading">
|
||||
<span class="panel-title"><?= $this -> params['title'];?></span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<?= $this -> params['content'];?>
|
||||
</div>
|
||||
</div>
|
||||
62
admin/templates/html/select.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '<div class="form-group ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'pl10 pr10';
|
||||
$out .= '">';
|
||||
$out .= '<label class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-3 ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'mb5 ';
|
||||
$out .= 'control-label">' . $this -> params['label'] . ':</label>';
|
||||
$out .= '<div class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-9';
|
||||
$out .= '">';
|
||||
}
|
||||
|
||||
$out .= '<select ';
|
||||
|
||||
if ( $this -> params['id'] )
|
||||
$out .= 'id="' . $this -> params['id'] . '" ';
|
||||
|
||||
if ( $this -> params['class'] or $this -> params['label'] )
|
||||
{
|
||||
if ( $this -> params['label'] )
|
||||
$out .= 'class="' . $this -> params['class'] . ' form-control" ';
|
||||
else if ( $this -> params['class'] )
|
||||
$out .= 'class="' . $this -> params['class'] . '" ';
|
||||
}
|
||||
|
||||
$out .= 'name="' . $this -> params['name'] . '" ';
|
||||
|
||||
if ( $this -> params['style'] )
|
||||
$out .= 'style="' . $this -> params['style'] . '" ';
|
||||
|
||||
if ( $this -> params['readonly'] )
|
||||
$out .= 'readonly="readonly" ';
|
||||
|
||||
if ( is_array( $this -> params['params'] ) and count( $this -> params['params'] ) ) foreach ( $this -> params['params'] as $key => $val )
|
||||
$out .= $key . '="' . $val . '" ';
|
||||
|
||||
$out .= '>';
|
||||
|
||||
if ( $this -> params['empty'] )
|
||||
$out .= '<option value="">--- ' . mb_strtolower( $this -> params['label'], 'UTF-8' ) . ' ---</option>';
|
||||
|
||||
if ( is_array( $this -> params['values'] ) ) foreach ( $this -> params['values'] as $key => $val )
|
||||
{
|
||||
$out .= '<option value="' . $key . '"'; if ( $key == $this -> params['value'] and $this -> params['value'] !== null ) $out .= 'selected="selected"'; $out .='>' . $val . '</option>';
|
||||
}
|
||||
|
||||
$out .= '</select>';
|
||||
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '</div>';
|
||||
$out .= '</div>';
|
||||
}
|
||||
|
||||
echo $out;
|
||||
52
admin/templates/html/textarea.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '<div class="form-group ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'pl10 pr10';
|
||||
$out .= '">';
|
||||
$out .= '<label class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-3 ';
|
||||
if ( $this -> params['inline'] )
|
||||
$out .= 'mb5 ';
|
||||
$out .= 'control-label">' . $this -> params['label'] . ':</label>';
|
||||
$out .= '<div class="';
|
||||
if ( !$this -> params['inline'] )
|
||||
$out .= 'col-lg-9';
|
||||
$out .= '">';
|
||||
}
|
||||
|
||||
$out .= '<textarea ';
|
||||
|
||||
if ( $this -> params['id'] )
|
||||
$out .= 'id="' . $this -> params['id'] . '" ';
|
||||
|
||||
if ( $this -> params['class'] or $this -> params['label'] )
|
||||
{
|
||||
if ( $this -> params['label'] )
|
||||
$out .= 'class="' . $this -> params['class'] . ' form-control" ';
|
||||
else if ( $this -> params['class'] )
|
||||
$out .= 'class="' . $this -> params['class'] . '" ';
|
||||
}
|
||||
|
||||
if ( $this -> params['js'] )
|
||||
$out .= 'onchange="' . htmlspecialchars( $this -> params['js'] ) . '" ';
|
||||
|
||||
if ( $this -> params['js_key'] )
|
||||
$out .= 'onkeyup="' . htmlspecialchars( $this -> params['js_key'] ) . '" ';
|
||||
|
||||
$out .= 'name="' . $this -> params['name'] . '" ';
|
||||
|
||||
if ( $this -> params['style'] )
|
||||
$out .= 'style="' . $this -> params['style'] . '" ';
|
||||
|
||||
$out .= ' rows="' . $this -> params['rows'] . '">' . $this -> secureHTML( $this -> params['value'] ) . '</textarea>';
|
||||
|
||||
if ( $this -> params['label'] )
|
||||
{
|
||||
$out .= '</div>';
|
||||
$out .= '</div>';
|
||||
}
|
||||
|
||||
echo $out;
|
||||
98
admin/templates/languages/language-edit.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?
|
||||
global $db;
|
||||
|
||||
ob_start();
|
||||
echo \Html::input(
|
||||
array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'o',
|
||||
'value' => $this -> language['o']
|
||||
)
|
||||
);
|
||||
echo \Html::input(
|
||||
array(
|
||||
'label' => 'Język',
|
||||
'type' => 'text',
|
||||
'class' => 'require',
|
||||
'name' => 'name',
|
||||
'value' => $this -> language['name']
|
||||
)
|
||||
);
|
||||
if ( $this -> language['id'] )
|
||||
{
|
||||
echo \Html::input(
|
||||
array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'id',
|
||||
'value' => $this -> language['id']
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo \Html::input(
|
||||
array(
|
||||
'label' => 'ID (2 znaki)',
|
||||
'class' => 'require',
|
||||
'type' => 'text',
|
||||
'name' => 'id'
|
||||
)
|
||||
);
|
||||
}
|
||||
echo \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Aktywny',
|
||||
'name' => 'status',
|
||||
'checked' => $this -> language['status'] == 1 ? true : false
|
||||
)
|
||||
);
|
||||
echo \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Domyślny',
|
||||
'name' => 'start',
|
||||
'checked' => $this -> language['start'] == 1 ? true : false
|
||||
)
|
||||
);
|
||||
echo '<hr />';
|
||||
echo \Html::input(
|
||||
array(
|
||||
'label' => 'Domena',
|
||||
'type' => 'text',
|
||||
'name' => 'domain',
|
||||
'value' => $this -> language['domain']
|
||||
)
|
||||
);
|
||||
echo \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Domena domyślna',
|
||||
'name' => 'main_domain',
|
||||
'checked' => $this -> language['main_domain'] == 1 ? true : false
|
||||
)
|
||||
);
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'language-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja języka';
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/languages/language_save/', 'back_url' => '/admin/languages/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/languages/view_list/' ]
|
||||
];
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$( function()
|
||||
{
|
||||
disable_menu();
|
||||
|
||||
$( 'input[type="text"].date' ).datetimepicker({
|
||||
format: "YYYY-MM-DD",
|
||||
pickTime: false
|
||||
});
|
||||
});
|
||||
</script>
|
||||
72
admin/templates/languages/languages-list.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_langs' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'name', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Język', 'db' => 'name', 'type' => 'text' ],
|
||||
[ 'name' => 'Aktywny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ],
|
||||
[ 'name' => 'Domyślny', 'db' => 'start', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Domyślny',
|
||||
'db' => 'start',
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'php' => 'if ( [start] ) echo "<span class=\'text-system\'>tak</span>"; else echo "nie";'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Język',
|
||||
'db' => 'name',
|
||||
'php' => 'echo "<a href=\'/admin/languages/language_edit/id=[id]\'>[name]</a>";',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Domena',
|
||||
'db' => 'domain',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Domena domyślna',
|
||||
'db' => 'main_domain',
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'php' => 'if ( [main_domain] ) echo "<span class=\'text-system\'>tak</span>"; else echo "nie";'
|
||||
],
|
||||
[
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/languages/language_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/languages/language_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj język',
|
||||
'url' => '/admin/languages/language_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
60
admin/templates/languages/translation-edit.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?
|
||||
global $db;
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<?
|
||||
echo \Html::input(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'label' => 'Tekst',
|
||||
'name' => 'text',
|
||||
'class' => 'require',
|
||||
'value' => $this -> translation['text']
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $language ):
|
||||
echo \Html::input(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'label' => $language['name'],
|
||||
'name' => $language['id'],
|
||||
'value' => $this -> translation[$language['id']]
|
||||
) );
|
||||
endforeach;
|
||||
endif;
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'translation-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja tłumaczenia';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> translation['id']
|
||||
]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/languages/translation_save/', 'back_url' => '/admin/languages/translation_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/languages/translation_list/' ]
|
||||
];
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(function ()
|
||||
{
|
||||
disable_menu();
|
||||
|
||||
$('input[type="text"].date').datetimepicker({
|
||||
format: "YYYY-MM-DD",
|
||||
pickTime: false
|
||||
});
|
||||
});
|
||||
</script>
|
||||
44
admin/templates/languages/translations-list.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_langs_translations' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'text', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Tekst', 'db' => 'text', 'type' => 'text' ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Tekst',
|
||||
'db' => 'text',
|
||||
'php' => 'echo "<a href=\'/admin/languages/translation_edit/id=[id]\'>[text]</a>";',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/languages/translation_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/languages/translation_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj tłumaczenie',
|
||||
'url' => '/admin/languages/translation_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
262
admin/templates/layouts/layout-edit.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<link rel="stylesheet" href="/libraries/codemirror/lib/codemirror.css" />
|
||||
<link rel="stylesheet" href="/libraries/codemirror/theme/material.css" />
|
||||
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/lib/codemirror.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/css/css.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/xml/xml.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/javascript/javascript.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/htmlmixed/htmlmixed.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/addon/mode/multiplex.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( function()
|
||||
{
|
||||
var code_html = CodeMirror.fromTextArea( document.getElementById( "html" ),{
|
||||
lineWrapping: true,
|
||||
mode: "text/html"
|
||||
});
|
||||
code_html.on( 'change', function(cm) {
|
||||
$( '#html' ).val( cm.getValue() );
|
||||
});
|
||||
code_html.setOption( "theme", 'material' );
|
||||
|
||||
var code_css = CodeMirror.fromTextArea( document.getElementById( "css" ),{
|
||||
lineWrapping: true,
|
||||
mode: "css"
|
||||
});
|
||||
code_css.on( 'change', function(cm) {
|
||||
$( '#css' ).val( cm.getValue() );
|
||||
});
|
||||
code_css.setOption( "theme", 'material' );
|
||||
|
||||
var code_js = CodeMirror.fromTextArea( document.getElementById( "js" ),{
|
||||
lineWrapping: true,
|
||||
mode: "javascript"
|
||||
});
|
||||
code_js.on( 'change', function(cm) {
|
||||
$( '#js' ).val( cm.getValue() );
|
||||
});
|
||||
code_js.setOption( "theme", 'material' );
|
||||
|
||||
var code_m_html = CodeMirror.fromTextArea( document.getElementById( "m_html" ),{
|
||||
lineWrapping: true,
|
||||
mode: "text/html"
|
||||
});
|
||||
code_m_html.on( 'change', function(cm) {
|
||||
$( '#m_html' ).val( cm.getValue() );
|
||||
});
|
||||
code_m_html.setOption( "theme", 'material' );
|
||||
|
||||
var code_m_css = CodeMirror.fromTextArea( document.getElementById( "m_css" ),{
|
||||
lineWrapping: true,
|
||||
mode: "css"
|
||||
});
|
||||
code_m_css.on( 'change', function(cm) {
|
||||
$( '#m_css' ).val( cm.getValue() );
|
||||
});
|
||||
code_m_css.setOption( "theme", 'material' );
|
||||
|
||||
var code_m_js = CodeMirror.fromTextArea( document.getElementById( "m_js" ),{
|
||||
lineWrapping: true,
|
||||
mode: "javascript"
|
||||
});
|
||||
code_m_js.on( 'change', function(cm) {
|
||||
$( '#m_js' ).val( cm.getValue() );
|
||||
});
|
||||
code_m_js.setOption( "theme", 'material' );
|
||||
|
||||
disable_menu();
|
||||
|
||||
$( '#layout-tabs' ).easyResponsiveTabs(
|
||||
{
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'layout-tabs',
|
||||
type: 'vertical'
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'click', '.select-page', function()
|
||||
{
|
||||
$( this ).parent( 'div' ).children( 'div.icheckbox_minimal-blue' ).children( 'input' ).iCheck( 'toggle' );
|
||||
});
|
||||
|
||||
$('ol.sortable').nestedSortable(
|
||||
{
|
||||
forcePlaceholderSize: true,
|
||||
handle: 'div',
|
||||
helper: 'clone',
|
||||
items: 'li',
|
||||
opacity: .6,
|
||||
placeholder: 'placeholder',
|
||||
revert: 250,
|
||||
tabSize: 25,
|
||||
tolerance: 'pointer',
|
||||
toleranceElement: '> div',
|
||||
maxLevels: 3,
|
||||
isTree: true,
|
||||
expandOnHover: 700,
|
||||
isAllowed: function()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$( '.disclose' ).on( 'click', function()
|
||||
{
|
||||
$( this ).closest( 'li' ).toggleClass( 'sort-collapsed' ).toggleClass( 'sort-expanded' );
|
||||
});
|
||||
|
||||
$( '.disclose' ).mousedown( function(e)
|
||||
{
|
||||
if ( e.which === 1 ) {
|
||||
if ( $( this ).parent( 'div' ).hasClass( 'content_menu' ) )
|
||||
{
|
||||
var menu_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'menu' );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'cookie_menus',
|
||||
menu_id: menu_id
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var page_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'id' );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'cookie_pages',
|
||||
page_id: page_id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
<?php
|
||||
$array = unserialize( $_COOKIE[ 'cookie_pages' ] );
|
||||
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
|
||||
if ( $val ):
|
||||
?>$( '.<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
|
||||
endif;
|
||||
endforeach; endif;
|
||||
|
||||
$array = unserialize( $_COOKIE[ 'cookie_menus' ] );
|
||||
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
|
||||
if ( $val ):
|
||||
?>$( '.menu_<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
|
||||
endif;
|
||||
endforeach; endif;
|
||||
?>
|
||||
|
||||
});
|
||||
</script>
|
||||
<?
|
||||
global $db;
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div id="layout-tabs">
|
||||
<ul class="resp-tabs-list layout-tabs">
|
||||
<li><i class="fa fa-wrench"></i>Ustawienia</li>
|
||||
<li><i class="fa fa-html5"></i>HTML</li>
|
||||
<li><i class="fa fa-html5"></i>CSS</li>
|
||||
<li><i class="fa fa-html5"></i>JS</li>
|
||||
<li><i class="fa fa-mobile"></i>HTML - mobile</li>
|
||||
<li><i class="fa fa-mobile"></i>CSS - mobile</li>
|
||||
<li><i class="fa fa-mobile"></i>JS - mobile</li>
|
||||
</ul>
|
||||
<div class="resp-tabs-container layout-tabs">
|
||||
<div>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Nazwa',
|
||||
'name' => 'name',
|
||||
'id' => 'name',
|
||||
'value' => $this -> layout['name']
|
||||
)
|
||||
);?>
|
||||
<?= \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Szablon domyślny',
|
||||
'name' => 'status',
|
||||
'checked' => $this -> layout['status'] == 1 ? true : false
|
||||
)
|
||||
);?>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">Strony:</label>
|
||||
<div class="col-lg-9">
|
||||
<?
|
||||
if ( is_array( $this -> menus ) ) foreach ( $this -> menus as $menu )
|
||||
{
|
||||
?>
|
||||
<div class="menu_sortable">
|
||||
<ol class="sortable" id="sortable_<?= $menu['id'];?>">
|
||||
<li id="list_<?= $menu['id'];?>" class="menu_<?= $menu['id'];?>" menu="<?= $menu['id'];?>">
|
||||
<div class="context_0 content content_menu" <? if ( !$menu['status'] ) echo 'style="color: #cc0000;"';?>>
|
||||
<span class="disclose"><span></span></span>
|
||||
Menu: <b><?= $menu['name'];?></b>
|
||||
</div>
|
||||
<?= \admin\view\Layouts::subpages_list( \admin\factory\Pages::menu_pages( $menu['id'] ), $this -> layout['pages'] );?>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="html" id="html" style="width: 100%; height: 500px; border: 0; padding: 10px; margin: -10px 0 -15px; font-size: 12px; box-sizing: border-box;"><?= htmlspecialchars( $this -> layout['html'] );?></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="css" id="css" style="width: 100%; height: 500px; border: 0; padding: 10px; margin: -10px 0 -15px; font-size: 12px; box-sizing: border-box;"><?= htmlspecialchars( $this -> layout['css'] );?></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="js" id="js" style="width: 100%; height: 500px; border: 0; padding: 10px; margin: -10px 0 -15px; font-size: 12px; box-sizing: border-box;"><?= htmlspecialchars( $this -> layout['js'] );?></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="m_html" id="m_html" style="width: 100%; height: 500px; border: 0; padding: 10px; margin: -10px 0 -15px; font-size: 12px; box-sizing: border-box;"><?= htmlspecialchars( $this -> layout['m_html'] );?></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="m_css" id="m_css" style="width: 100%; height: 500px; border: 0; padding: 10px; margin: -10px 0 -15px; font-size: 12px; box-sizing: border-box;"><?= htmlspecialchars( $this -> layout['m_css'] );?></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="m_js" id="m_js" style="width: 100%; height: 500px; border: 0; padding: 10px; margin: -10px 0 -15px; font-size: 12px; box-sizing: border-box;"><?= htmlspecialchars( $this -> layout['m_js'] );?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'layout-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja szablonu';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> layout['id']
|
||||
]
|
||||
];
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/layouts/layout_save/', 'back_url' => '/admin/layouts/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/layouts/view_list/' ]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
47
admin/templates/layouts/layouts-list.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_layouts' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'name', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Nazwa', 'db' => 'name', 'type' => 'text' ],
|
||||
[ 'name' => 'Szablon domyślny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Nazwa',
|
||||
'db' => 'name',
|
||||
'php' => 'echo "<a href=\'/admin/layouts/layout_edit/id=[id]\'>[name]</a>";',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Szablon domyślny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => 'nie', 1 => '<span class="text-system">tak</span>' ] ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Akcja',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/layouts/layout_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center' ],
|
||||
'td' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Akcja',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/layouts/layout_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center' ],
|
||||
'td' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[ 'label' => 'Dodaj szablon', 'url' => '/admin/layouts/layout_edit/', 'icon' => 'fa-plus-circle', 'class' => 'btn-success' ]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
16
admin/templates/layouts/subpages-list.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<? if ( is_array( $this -> pages ) ):?>
|
||||
<ol>
|
||||
<? foreach ( $this -> pages as $page ):?>
|
||||
<li id="list_<?= $page['id'];?>" idk="<?= $page['id'];?>" class="list_<?= $page['id'];?>" menu="<?= $page['menu_id'];?>">
|
||||
<div class="content <?= $this -> step < 2 ? $tmp = 'content_page' : $tmp = 'content_page_last_level';?>" <? if ( !$page['status'] ) echo 'style="color: #cc0000;"';?>>
|
||||
<span class="disclose"><span></span></span>
|
||||
<input type="checkbox" class="g-checkbox" name="pages" value="<?= $page['id'];?>" <? if ( is_array( $this -> layout_pages ) and in_array( $page['id'], $this -> layout_pages ) ):?>checked="checked"<? endif;?> /><?= $page['title'];?>
|
||||
</div>
|
||||
<?
|
||||
if ( is_array( $page['subpages'] ) )
|
||||
echo \admin\view\Layouts::subpages_list( $page['subpages'], $this -> layout_pages, $page['id'], $this -> step + 1 );
|
||||
?>
|
||||
</li>
|
||||
<? endforeach;?>
|
||||
</ol>
|
||||
<? endif;?>
|
||||
63
admin/templates/newsletter/email-template-edit.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
|
||||
<?
|
||||
global $db;
|
||||
ob_start();
|
||||
?>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Nazwa',
|
||||
'name' => 'name',
|
||||
'id' => 'name',
|
||||
'value' => $this -> email_template['name'],
|
||||
'inline' => true,
|
||||
'readonly' => $this -> email_template['is_admin'] ? true : false
|
||||
)
|
||||
);?>
|
||||
<?= \Html::textarea(
|
||||
array(
|
||||
'label' => 'Treść',
|
||||
'name' => 'text',
|
||||
'id' => 'text',
|
||||
'value' => $this ->email_template['text'],
|
||||
'inline' => true
|
||||
)
|
||||
);?>
|
||||
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'email-templates-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja szablonu newslettera';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> email_template['id']
|
||||
]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [
|
||||
'url' => '/admin/newsletter/template_save/',
|
||||
'back_url' => $this -> email_template['is_admin'] ? '/admin/newsletter/email_templates_admin/' : '/admin/newsletter/email_templates_user/'
|
||||
],
|
||||
'cancel' => [
|
||||
'url' => $this -> email_template['is_admin'] ? '/admin/newsletter/email_templates_admin/' : '/admin/newsletter/email_templates_user/'
|
||||
]
|
||||
];
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$( function() {
|
||||
$( '#text' ).ckeditor( {
|
||||
toolbar : 'MyTool',
|
||||
height:'350'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
28
admin/templates/newsletter/email-templates-admin.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_newsletter_templates' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'name', 'type' => 'ASC' ];
|
||||
$grid -> where = [ 'is_admin' => 1 ];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Nazwa',
|
||||
'db' => 'name',
|
||||
'php' => 'echo "<a href=\'/admin/newsletter/email_template_edit/id=[id]\'>[name]</a>";',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/newsletter/email_template_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
42
admin/templates/newsletter/email-templates-user.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_newsletter_templates' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'name', 'type' => 'ASC' ];
|
||||
$grid -> where = [ 'is_admin' => 0 ];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Nazwa',
|
||||
'db' => 'name',
|
||||
'php' => 'echo "<a href=\'/admin/newsletter/email_template_edit/id=[id]\'>[name]</a>";',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/newsletter/email_template_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/newsletter/email_template_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj szablon',
|
||||
'url' => '/admin/newsletter/email_template_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
38
admin/templates/newsletter/emails-list.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_newsletter' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> order = [ 'column' => 'email', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Email', 'db' => 'email', 'type' => 'text' ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Email',
|
||||
'db' => 'email',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Potwierdzony',
|
||||
'db' => 'status',
|
||||
'sort' => true,
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Importuj emaile',
|
||||
'url' => '/admin/newsletter/import/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
$grid -> actions = [ 'delete' => true ];
|
||||
echo $grid -> draw();
|
||||
41
admin/templates/newsletter/import.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?
|
||||
global $db;
|
||||
ob_start();
|
||||
?>
|
||||
<?= \Html::textarea(
|
||||
array(
|
||||
'label' => 'Maile (oddzielone nowym wierszem)',
|
||||
'name' => 'emails',
|
||||
'id' => 'emails'
|
||||
)
|
||||
);?>
|
||||
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'emails';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Import adresów mailowych';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> element['id']
|
||||
]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [
|
||||
'url' => '/admin/newsletter/emails_import/',
|
||||
'back_url' => '/admin/newsletter/emails_list/'
|
||||
],
|
||||
'cancel' => [
|
||||
'url' => '/admin/newsletter/emails_list/'
|
||||
]
|
||||
];
|
||||
$grid -> persist_edit = false;
|
||||
$grid -> id_param = 'id';
|
||||
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
140
admin/templates/newsletter/prepare.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?
|
||||
global $db;
|
||||
ob_start();
|
||||
?>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">Wysyłaj tylko raz:</label>
|
||||
<div class="col-lg-9 pt5">
|
||||
<div class="switch switch-primary round switch-inline">
|
||||
<input id="only_once" name="only_once" type="checkbox">
|
||||
<label for="only_once"></label>
|
||||
<small><i>Dotyczy wysyłki maili z szablonu.</i></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">Zakres dat:</label>
|
||||
<div class="col-lg-9">
|
||||
<div class="input-group">
|
||||
<input type="text" id="dates" name="dates" data="search-column:date_add;search-type:date_range" class="form-control date-range require" value="">
|
||||
<span class="input-group-addon cursor date-range-icon">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">lub / i</label>
|
||||
</div>
|
||||
<?
|
||||
$templates[''] = '---- szablon ----';
|
||||
if ( is_array( $this -> templates ) ): foreach ( $this -> templates as $template ):
|
||||
$templates[ $template['id'] ] = $template['name'];
|
||||
endforeach; endif;
|
||||
?>
|
||||
<?= \Html::select(
|
||||
array(
|
||||
'label' => 'Szablon',
|
||||
'name' => 'template',
|
||||
'id' => 'template',
|
||||
'values' => $templates,
|
||||
'value' => $this -> templates['id']
|
||||
|
||||
));?>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">Podgląd:</label>
|
||||
<div class="col-lg-9">
|
||||
<div id="newsletter-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'newsletter-prepare';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Wysyłka newslettera - przygotowanie';
|
||||
$grid -> default_buttons = false;
|
||||
$grid -> external_code = $out;
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Wyślij newsletter',
|
||||
'class' => 'btn-success',
|
||||
'icon' => 'fa-send',
|
||||
'js' => 'send_newsletter();'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
function send_newsletter()
|
||||
{
|
||||
var dates = $( '#dates' ).val();
|
||||
var template = $('#template').val();
|
||||
|
||||
if ( !dates && !template )
|
||||
$.prompt( 'Proszę wybrać zakres dat lub szablon.', { title: 'Błąd' } );
|
||||
|
||||
$( '#fg-newsletter-prepare' ).submit();
|
||||
return false;
|
||||
}
|
||||
|
||||
$( function()
|
||||
{
|
||||
$( '#fg-newsletter-prepare' ).attr( 'action', '/admin/newsletter/send/' );
|
||||
|
||||
$( 'body' ).on( 'change', '#dates', function()
|
||||
{
|
||||
var dates = $( this ).val();
|
||||
var template = $('#template').val();
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'newsletter-preview',
|
||||
dates: dates,
|
||||
template: template
|
||||
},
|
||||
beforeSend: function()
|
||||
{
|
||||
$( '#overlay' ).show();
|
||||
},
|
||||
success: function( response )
|
||||
{
|
||||
$( '#overlay' ).hide();
|
||||
$( '#newsletter-preview' ).html( response );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'change', '#template', function()
|
||||
{
|
||||
var dates = $( '#dates' ).val();
|
||||
var template = $( this ).val();
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'newsletter-preview',
|
||||
template: template,
|
||||
dates: dates
|
||||
},
|
||||
beforeSend: function()
|
||||
{
|
||||
$( '#overlay' ).show();
|
||||
},
|
||||
success: function( response )
|
||||
{
|
||||
$( '#overlay' ).hide();
|
||||
$( '#newsletter-preview' ).html( response );
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
33
admin/templates/newsletter/preview.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?= $this -> settings['newsletter_header'] ? $this -> settings['newsletter_header'] : '<p style="text-align: center;">--- brak zdefiniowanego nagłówka ---</p>';?>
|
||||
<? if ( is_array( $this -> template ) ):?>
|
||||
<?= $this -> template['text']?>
|
||||
<? endif;?>
|
||||
<? if ( is_array( $this -> articles ) ):?>
|
||||
<? foreach ( $this -> articles as $article ):?>
|
||||
<? $article['language']['seo_link'] ? $url = $article['language']['seo_link'] : $url = 'a-' . $article['id'] . '-' . \S::seo( $article['language']['title'] );?>
|
||||
<div style="padding: 10px; background: #F1F1F1; margin-bottom: 10px">
|
||||
<?
|
||||
$article['language']['seo_link'] ? $url = $article['language']['seo_link'] : $url = 'a-' . $article['id'] . '-' . \S::seo( $article['language']['title'] );
|
||||
?>
|
||||
<a href="http://<?= $_SERVER['SERVER_NAME'];?>/<?= $url;?>" title="<?= $article['language']['title'];?>" style="margin-bottom: 10px; display: block; font-size: 14px; color: #5b7fb1; font-weight: 600;">
|
||||
<?= $article['language']['title'];?>
|
||||
</a>
|
||||
<div>
|
||||
<?
|
||||
if ( $article['language']['entry'] )
|
||||
echo $article['language']['entry'];
|
||||
else
|
||||
echo $article['language']['text'];
|
||||
?>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<? endforeach;?>
|
||||
<? else:?>
|
||||
<? if ( $this -> dates ):?>
|
||||
<div style="padding: 10px; background: #F1F1F1; margin-bottom: 10px; text-align: center;">
|
||||
--- brak artykułów w danym okresie ---
|
||||
</div>
|
||||
<? endif;?>
|
||||
<? endif;?>
|
||||
<?= $this -> settings['newsletter_footer_2'] ? $this -> settings['newsletter_footer_2'] : '<p style="text-align: center;">--- brak zdefiniowanej stopki cz. 2 ---</p>';?>
|
||||
60
admin/templates/newsletter/settings.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( function()
|
||||
{
|
||||
$( 'textarea' ).ckeditor(
|
||||
{
|
||||
toolbar : 'MyTool',
|
||||
height: '150'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?
|
||||
global $db;
|
||||
|
||||
ob_start();
|
||||
|
||||
echo \Html::textarea(
|
||||
array(
|
||||
'label' => 'Nagłówek',
|
||||
'name' => 'newsletter_header',
|
||||
'id' => 'newsletter_header',
|
||||
'value' => $this -> settings['newsletter_header'],
|
||||
'inline' => true
|
||||
)
|
||||
);
|
||||
echo \Html::textarea(
|
||||
array(
|
||||
'label' => 'Stopka cz 1. (dołączana zawsze)',
|
||||
'name' => 'newsletter_footer_1',
|
||||
'id' => 'newsletter_footer_1',
|
||||
'value' => $this -> settings['newsletter_footer_1'],
|
||||
'inline' => true
|
||||
)
|
||||
);
|
||||
echo \Html::textarea(
|
||||
array(
|
||||
'label' => 'Stopka cz 2. (dołączana tylko w przypadku newslettera)',
|
||||
'name' => 'newsletter_footer_2',
|
||||
'id' => 'newsletter_footer_2',
|
||||
'value' => $this -> settings['newsletter_footer_2'],
|
||||
'inline' => true
|
||||
)
|
||||
);
|
||||
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'settings-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja ustawień';
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/newsletter/settings_save/', 'back_url' => '/admin/newsletter/settings/' ],
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>
|
||||
<style type="text/css">#g-edit-cancel { display: none; }</style>
|
||||
42
admin/templates/pages/menu-edit.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Zapisz menu';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> menu['id']
|
||||
],
|
||||
[
|
||||
'name' => 'Nazwa',
|
||||
'db' => 'name',
|
||||
'type' => 'text',
|
||||
'value' => $this -> menu['name'],
|
||||
'params' => [ 'class' => 'require' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywne',
|
||||
'db' => 'status',
|
||||
'type' => 'input_switch',
|
||||
'checked' => $this -> menu['status'] ? true : false,
|
||||
'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ]
|
||||
]
|
||||
];
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/pages/menu_save/', 'back_url' => '/admin/pages/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/pages/view_list/' ]
|
||||
];
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready( function()
|
||||
{
|
||||
disable_menu();
|
||||
});
|
||||
</script>
|
||||
89
admin/templates/pages/page-articles.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?
|
||||
global $gdb;
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<ol class="sortable" id="article-list">
|
||||
<?
|
||||
if ( is_array( $this -> articles ) ) foreach ( $this -> articles as $article )
|
||||
{
|
||||
?>
|
||||
<li id="list_<?= $article['article_id'];?>">
|
||||
<div class="content <? if ( !$article['status'] ) echo 'text-danger';?>"><span class="disclose"><span></span></span> <?= $article['title'];?></div>
|
||||
</li>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
</ol>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> default_buttons = false;
|
||||
$grid -> external_code = $out;
|
||||
$grid -> title = 'Lista artykułów';
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Wstecz',
|
||||
'url' => '/admin/pages/view_list/',
|
||||
'icon' => 'fa-reply',
|
||||
'class' => 'btn-dark'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready( function()
|
||||
{
|
||||
$( 'ol.sortable' ).nestedSortable(
|
||||
{
|
||||
forcePlaceholderSize: true,
|
||||
handle: 'div',
|
||||
helper: 'clone',
|
||||
items: 'li',
|
||||
opacity: .6,
|
||||
placeholder: 'placeholder',
|
||||
revert: 250,
|
||||
tabSize: 25,
|
||||
tolerance: 'pointer',
|
||||
toleranceElement: '> div',
|
||||
maxLevels: 1,
|
||||
isTree: true,
|
||||
expandOnHover: 700,
|
||||
save_articles_order: true
|
||||
});
|
||||
});
|
||||
|
||||
function save_articles_order()
|
||||
{
|
||||
articles = $( 'ol.sortable' ).nestedSortable( 'toArray', { startDepthCount: 0 } );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data:
|
||||
{
|
||||
a: 'save_articles_order',
|
||||
page_id: <?= $this -> page_id;?>,
|
||||
articles: articles
|
||||
},
|
||||
beforeSend: function()
|
||||
{
|
||||
$.prompt( 'Trwa zapisywanie...', { title: 'Proszę czekać' } );
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$( '.jqibox' ).remove();
|
||||
response = jQuery.parseJSON( data );
|
||||
|
||||
if ( response.status === 'error' )
|
||||
create_error( response.msg );
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
514
admin/templates/pages/page-edit.php
Normal file
@@ -0,0 +1,514 @@
|
||||
<script type="text/javascript">
|
||||
var link_lang = '';
|
||||
$(function ()
|
||||
{
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
google_preview('<?= $lg['id']; ?>', 0);
|
||||
<? endforeach; endif;?>
|
||||
|
||||
disable_menu();
|
||||
|
||||
$('body').on('change', '#page_type', function ()
|
||||
{
|
||||
var page_type = $(this).val();
|
||||
|
||||
if (page_type == 0 || page_type == 1 || page_type == 2)
|
||||
{
|
||||
$('#articles_limit').parents('.form-group').show();
|
||||
$('#link-content').addClass('hide');
|
||||
}
|
||||
else if (page_type == 3)
|
||||
{
|
||||
$('#link-content').removeClass('hide');
|
||||
$('#articles_limit').parents('.form-group').hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#articles_limit').parents('.form-group').hide();
|
||||
$('#link-content').addClass('hide');
|
||||
}
|
||||
});
|
||||
|
||||
$('#settings-tabs').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'settings-tabs',
|
||||
type: 'vertical'
|
||||
});
|
||||
|
||||
$('#languages-main').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-main'
|
||||
});
|
||||
|
||||
$('#languages-seo').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-seo'
|
||||
});
|
||||
|
||||
$('#languages-links').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-links'
|
||||
});
|
||||
|
||||
$('#page_type').trigger('change');
|
||||
|
||||
$('body').on('click', '.mfp-close', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
$.magnificPopup.close();
|
||||
});
|
||||
|
||||
$('body').on('click', '.url-select', function ()
|
||||
{
|
||||
$('#link_' + link_lang).val($(this).attr('url'));
|
||||
$.magnificPopup.close();
|
||||
});
|
||||
});
|
||||
|
||||
function generate_seo_links( lang, title, page_id, pid )
|
||||
{
|
||||
var default_language = '<?= \front\factory\Languages::default_language(); ?>';
|
||||
|
||||
if ( title === '' )
|
||||
return false;
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data:
|
||||
{
|
||||
a: 'generate_seo_link',
|
||||
title: title,
|
||||
page_id: page_id,
|
||||
lang: lang,
|
||||
pid: pid
|
||||
},
|
||||
beforeSend: function ()
|
||||
{
|
||||
$('#overlay').show();
|
||||
},
|
||||
success: function (data)
|
||||
{
|
||||
$('#overlay').hide();
|
||||
|
||||
response = jQuery.parseJSON(data);
|
||||
|
||||
if ( response.status === 'ok' )
|
||||
{
|
||||
$('#seo_link_' + lang).val( response.seo_link );
|
||||
google_preview( lang, pid );
|
||||
}
|
||||
else
|
||||
create_error( response.msg );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function google_preview( lang_id, pid )
|
||||
{
|
||||
var default_language = '<?= \front\factory\Languages::default_language(); ?>';
|
||||
var title = $( '#title_' + lang_id ).val();
|
||||
var meta_title = $( '#meta_title_' + lang_id ).val();
|
||||
var seo_link = $( '#seo_link_' + lang_id ).val();
|
||||
var description = $( '#meta_description_' + lang_id ).val();
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data:
|
||||
{
|
||||
a: 'google_url_preview',
|
||||
title: title,
|
||||
lang_id: lang_id,
|
||||
page_id: $('#id').val(),
|
||||
pid: pid,
|
||||
seo_link: seo_link,
|
||||
default_language: default_language
|
||||
},
|
||||
success: function (data)
|
||||
{
|
||||
$( '#google-preview-' + lang_id + ' .google-url' ).html( '<?= $_SERVER['SERVER_NAME']; ?>/' + data );
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof meta_title !== "undefined" && meta_title != '')
|
||||
{
|
||||
if (meta_title.length < 65)
|
||||
$('#google-preview-' + lang_id + ' .google-title').html(meta_title);
|
||||
else if (typeof description !== "undefined")
|
||||
{
|
||||
var space = meta_title.lastIndexOf(" ", 65);
|
||||
$('#google-preview-' + lang_id + ' .google-title').html(meta_title.substring(0, space).concat('...'));
|
||||
}
|
||||
} else if (typeof title !== "undefined" && title != '')
|
||||
{
|
||||
title = title + ' ● <?= $this->settings['firm_name']; ?>';
|
||||
|
||||
if (title.length < 65)
|
||||
$('#google-preview-' + lang_id + ' .google-title').html(title);
|
||||
else if (typeof description !== "undefined")
|
||||
{
|
||||
var space = title.lastIndexOf(" ", 65);
|
||||
$('#google-preview-' + lang_id + ' .google-title').html(title.substring(0, space).concat('...'));
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof description !== "undefined" && description.length < 153)
|
||||
$('#google-preview-' + lang_id + ' .google-description').html(description);
|
||||
else if (typeof description !== "undefined")
|
||||
{
|
||||
var space = description.lastIndexOf(" ", 153);
|
||||
$('#google-preview-' + lang_id + ' .google-description').html(description.substring(0, space).concat('...'));
|
||||
}
|
||||
}
|
||||
|
||||
function pages_url_browser(lang_id)
|
||||
{
|
||||
link_lang = lang_id;
|
||||
|
||||
$.magnificPopup.open({
|
||||
removalDelay: 500,
|
||||
items: {
|
||||
src: '/admin/pages/pages_url_browser/modal=true'
|
||||
},
|
||||
type: 'ajax',
|
||||
overflowY: 'scroll'
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<?
|
||||
global $db;
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div id="settings-tabs">
|
||||
<ul class="resp-tabs-list settings-tabs">
|
||||
<li><i class="fa fa-file"></i>Treść</li>
|
||||
<li><i class="fa fa-wrench"></i>Ustawienia</li>
|
||||
<li><i class="fa fa-globe"></i>SEO</li>
|
||||
</ul>
|
||||
<div class="resp-tabs-container settings-tabs">
|
||||
<div>
|
||||
<div id="languages-main">
|
||||
<ul class="resp-tabs-list languages-main">
|
||||
<? if (is_array($this->languages)): foreach ($this->languages as $lg): ?>
|
||||
<? if ($lg['status']): ?>
|
||||
<li><? if ($lg['id'] == \front\factory\Languages::default_language()) echo '<i class="fa fa-star fa-lg text-system" title="Język domyślny"></i> '; ?><?= $lg['name']; ?></a></li>
|
||||
<? endif; ?>
|
||||
<? endforeach;
|
||||
endif; ?>
|
||||
</ul>
|
||||
<div class="resp-tabs-container languages-main">
|
||||
<? if (is_array($this->languages)): foreach ($this->languages as $lg): ?>
|
||||
<? if ($lg['status']): ?>
|
||||
<div>
|
||||
<?=
|
||||
\Html::input(
|
||||
array(
|
||||
'label' => 'Nazwa strony',
|
||||
'name' => 'title',
|
||||
'id' => 'title_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['title'],
|
||||
'js_key' => 'google_preview( "' . $lg['id'] . '", "' . \S::get('pid') . '" ); return false;'
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<? endif; ?>
|
||||
<? endforeach;
|
||||
endif; ?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 15px;">
|
||||
<?
|
||||
if (is_array($this->menus)): foreach ($this->menus as $menu):
|
||||
$menus[$menu['id']] = $menu['name'];
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
<?=
|
||||
\Html::select(
|
||||
array(
|
||||
'label' => 'Menu',
|
||||
'name' => 'menu_id',
|
||||
'values' => $menus,
|
||||
'value' => $this->page['id'] ? $this->page['menu_id'] : $this->menu_id
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::select(
|
||||
array(
|
||||
'label' => 'Typ strony',
|
||||
'name' => 'page_type',
|
||||
'id' => 'page_type',
|
||||
'values' => \admin\factory\Pages::$_page_types,
|
||||
'value' => $this->page['page_type']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<div id="link-content" class="hide">
|
||||
<div id="languages-links">
|
||||
<ul class="resp-tabs-list languages-links">
|
||||
<? if (is_array($this->languages)): foreach ($this->languages as $lg): ?>
|
||||
<? if ($lg['status']): ?>
|
||||
<li><? if ($lg['id'] == \front\factory\Languages::default_language()) echo '<i class="fa fa-star fa-lg text-system" title="Język domyślny"></i> '; ?><?= $lg['name']; ?></a></li>
|
||||
<? endif; ?>
|
||||
<? endforeach;
|
||||
endif; ?>
|
||||
</ul>
|
||||
<div class="resp-tabs-container languages-links">
|
||||
<? if (is_array($this->languages)): foreach ($this->languages as $lg): ?>
|
||||
<? if ($lg['status']): ?>
|
||||
<div>
|
||||
<?=
|
||||
\Html::input_icon(
|
||||
array(
|
||||
'label' => 'Link',
|
||||
'name' => 'link',
|
||||
'id' => 'link_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['link'],
|
||||
'icon_class' => 'fa fa-link',
|
||||
'icon_js' => 'pages_url_browser( "' . $lg['id'] . '");'
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<? endif; ?>
|
||||
<? endforeach;
|
||||
endif; ?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?=
|
||||
\Html::select(
|
||||
array(
|
||||
'label' => 'Sortowanie artykułów',
|
||||
'name' => 'sort_type',
|
||||
'id' => 'sort_type',
|
||||
'values' => \admin\factory\Pages::$_sort_types,
|
||||
'value' => $this->page['sort_type']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?
|
||||
$layouts[''] = '---- szablon ----';
|
||||
if (is_array($this->layouts)): foreach ($this->layouts as $layout):
|
||||
$layouts[$layout['id']] = $layout['name'];
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
<?=
|
||||
\Html::select(
|
||||
array(
|
||||
'label' => 'Szablon',
|
||||
'name' => 'layout_id',
|
||||
'id' => 'layout_id',
|
||||
'values' => $layouts,
|
||||
'value' => $this->page['layout_id']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::input(
|
||||
array(
|
||||
'label' => 'Liczba artykułów na stronę',
|
||||
'name' => 'articles_limit',
|
||||
'id' => 'articles_limit',
|
||||
'value' => $this->page['articles_limit'] ? $this->page['articles_limit'] : 2
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::input_switch(
|
||||
array(
|
||||
'label' => 'Pokaż tytuł',
|
||||
'name' => 'show_title',
|
||||
'checked' => $this->page['show_title'] == 1 or ! $this->page['id'] ? true : false
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Aktywna',
|
||||
'name' => 'status',
|
||||
'checked' => $this->page['status'] == 1 or ! $this->page['id'] ? true : false
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= Html::input_switch( [
|
||||
'label' => 'Strona startowa',
|
||||
'name' => 'start',
|
||||
'checked' => $this->page['start'] == 1 ? true : false
|
||||
]
|
||||
);
|
||||
?>
|
||||
<?= Html::input_switch( [
|
||||
'label' => 'Cache (24h)',
|
||||
'name' => 'cache',
|
||||
'checked' => $this -> page['cache'] == 1 ? true : false
|
||||
]
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<div>
|
||||
<div id="languages-seo">
|
||||
<ul class="resp-tabs-list languages-seo">
|
||||
<? if (is_array($this->languages)): foreach ($this->languages as $lg): ?>
|
||||
<? if ($lg['status']): ?>
|
||||
<li><? if ($lg['id'] == \front\factory\Languages::default_language()) echo '<i class="fa fa-star fa-lg text-system" title="Język domyślny"></i> '; ?><?= $lg['name']; ?></a></li>
|
||||
<? endif; ?>
|
||||
<? endforeach;
|
||||
endif; ?>
|
||||
</ul>
|
||||
<div class="resp-tabs-container languages-seo">
|
||||
<? if (is_array($this->languages)): foreach ($this->languages as $lg): ?>
|
||||
<? if ($lg['status']): ?>
|
||||
<div>
|
||||
<?=
|
||||
\Html::input_icon(
|
||||
array(
|
||||
'label' => 'Link SEO',
|
||||
'name' => 'seo_link',
|
||||
'id' => 'seo_link_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['seo_link'],
|
||||
'icon_content' => 'generuj',
|
||||
'icon_js' => 'generate_seo_links( "' . $lg['id'] . '", $( "#title_' . $lg['id'] . '" ).val(), ' . (int) $this->page['id'] . ', ' . \S::get('pid') . ' );',
|
||||
'js_key' => 'google_preview( "' . $lg['id'] . '", "' . \S::get('pid') . '" ); return false;'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::input(
|
||||
array(
|
||||
'label' => 'Tytuł strony (h1)',
|
||||
'name' => 'site_title',
|
||||
'id' => 'site_title_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['site_title']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::input(
|
||||
array(
|
||||
'label' => 'Meta title',
|
||||
'name' => 'meta_title',
|
||||
'id' => 'meta_title_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['meta_title'],
|
||||
'js_key' => 'google_preview( "' . $lg['id'] . '" ); return false;'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::textarea(
|
||||
array(
|
||||
'label' => 'Meta description',
|
||||
'name' => 'meta_description',
|
||||
'id' => 'meta_description_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['meta_description'],
|
||||
'js_key' => 'google_preview( "' . $lg['id'] . '" ); return false;'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
\Html::textarea(
|
||||
array(
|
||||
'label' => 'Meta keywords',
|
||||
'name' => 'meta_keywords',
|
||||
'id' => 'meta_keywords_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['meta_keywords']
|
||||
)
|
||||
);
|
||||
?>
|
||||
<div class="form-group ">
|
||||
<label class="col-lg-3 control-label">Podgląd google:</label>
|
||||
<div class="col-lg-9">
|
||||
<div id="google-preview-<?= $lg['id']; ?>">
|
||||
<div class="google-title"></div>
|
||||
<div class="google-url"></div>
|
||||
<div class="google-description"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?=
|
||||
\Html::select(
|
||||
array(
|
||||
'label' => 'Blokuj indeksację',
|
||||
'name' => "noindex",
|
||||
'id' => 'noindex_' . $lg['id'],
|
||||
'values' => array(
|
||||
0 => 'nie', 1 => 'tak'
|
||||
),
|
||||
'value' => $this->page['languages'][$lg['id']]['noindex'] == 1 ? 1 : 0
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::select(
|
||||
array(
|
||||
'label' => 'Blokuj bezpośredni dostęp',
|
||||
'name' => "block_direct_access",
|
||||
'id' => 'block_direct_access_' . $lg['id'],
|
||||
'values' => array(
|
||||
0 => 'nie', 1 => 'tak'
|
||||
),
|
||||
'value' => $this -> page['languages'][ $lg['id'] ]['block_direct_access'] == 1 ? 1 : 0
|
||||
)
|
||||
);?>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Rel canonical',
|
||||
'name' => 'canonical',
|
||||
'id' => 'canonical_' . $lg['id'],
|
||||
'value' => $this->page['languages'][$lg['id']]['canonical']
|
||||
) );?>
|
||||
</div>
|
||||
<? endif; ?>
|
||||
<? endforeach;
|
||||
endif; ?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid->id = 'page-edit';
|
||||
$grid->gdb_opt = $gdb;
|
||||
$grid->include_plugins = true;
|
||||
$grid->title = 'Edycja strony';
|
||||
$grid->fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this->page['id']
|
||||
],
|
||||
[
|
||||
'db' => 'parent_id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this->page['id'] ? $this->page['parent_id'] : $this->parent_id
|
||||
]
|
||||
];
|
||||
$grid->actions = [
|
||||
'save' => ['url' => '/admin/pages/page_save/', 'back_url' => '/admin/pages/view_list/'],
|
||||
'cancel' => ['url' => '/admin/pages/view_list/']
|
||||
];
|
||||
$grid->external_code = $out;
|
||||
$grid->persist_edit = true;
|
||||
$grid->id_param = 'id';
|
||||
|
||||
echo $grid->draw();
|
||||
?>
|
||||
156
admin/templates/pages/pages-browse-list.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?
|
||||
global $gdb;
|
||||
ob_start();
|
||||
if ( is_array( $this -> menus ) ) foreach ( $this -> menus as $menu )
|
||||
{
|
||||
?>
|
||||
<div class="menu_sortable">
|
||||
<ol class="sortable" id="sortable_<?= $menu['id'];?>" menu-id="<?= $menu['id'];?>">
|
||||
<li id="list_<?= $menu['id'];?>" class="menu_<?= $menu['id'];?>" menu="<?= $menu['id'];?>">
|
||||
<div class="context_0 content content_menu">
|
||||
<span class="disclose"><span></span></span>
|
||||
<? if ( !$menu['status'] ) echo '<i class="fa fa-ban fa-lg text-danger" title="Menu nieaktywne"></i>';?>
|
||||
Menu: <b><?= $menu['name'];?></b>
|
||||
</div>
|
||||
<?= \admin\view\Pages::subpages_browse_list( \admin\factory\Pages::menu_pages( $menu['id'] ) );?>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<?
|
||||
}
|
||||
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'pages-list';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Lista stron';
|
||||
$grid -> default_buttons = false;
|
||||
$grid -> external_code = $out;
|
||||
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<style type="text/css">
|
||||
<? if ( $this -> modal ):?>
|
||||
.menu-left, .navbar {
|
||||
display: none;
|
||||
}
|
||||
.site-content {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
<? endif;?>
|
||||
</style>
|
||||
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
|
||||
<script type="text/javascript">
|
||||
var menu_id = 0;
|
||||
|
||||
function getUrlParam(paramName)
|
||||
{
|
||||
var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i');
|
||||
var match = window.location.search.match(reParam);
|
||||
|
||||
return (match && match.length > 1) ? match[1] : '';
|
||||
}
|
||||
|
||||
$( document ).ready( function()
|
||||
{
|
||||
<? if ( !$this -> modal ):?>
|
||||
$( '#sidebar_left, .navbar-fixed-top' ).hide();
|
||||
<? endif;?>
|
||||
|
||||
var funcNum = getUrlParam('CKEditorFuncNum');
|
||||
|
||||
$( 'body' ).on( 'click', '.button', function()
|
||||
{
|
||||
if ( funcNum )
|
||||
{
|
||||
window.opener.CKEDITOR.tools.callFunction(funcNum, $( this ).attr( 'url' ) );
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
$( 'ol.sortable' ).nestedSortable(
|
||||
{
|
||||
forcePlaceholderSize: true,
|
||||
handle: 'div',
|
||||
helper: 'clone',
|
||||
items: 'li',
|
||||
opacity: .9,
|
||||
placeholder: 'placeholder',
|
||||
revert: 250,
|
||||
tabSize: 45,
|
||||
tolerance: 'pointer',
|
||||
toleranceElement: '> div',
|
||||
maxLevels: 3,
|
||||
isTree: true,
|
||||
expandOnHover: 700,
|
||||
stop: function() {
|
||||
save_pages_order();
|
||||
}
|
||||
});
|
||||
|
||||
$( '.disclose' ).on( 'click', function()
|
||||
{
|
||||
$( this ).closest( 'li' ).toggleClass( 'sort-collapsed' ).toggleClass( 'sort-expanded' );
|
||||
});
|
||||
|
||||
$( ".sortable *" ).mousedown( function(e)
|
||||
{
|
||||
menu_id = $( this ).parents( 'ol.sortable' ).attr( 'menu-id' );
|
||||
});
|
||||
|
||||
$( '.disclose' ).mousedown( function(e)
|
||||
{
|
||||
if ( e.which === 1 ) {
|
||||
if ( $( this ).parent( 'div' ).hasClass( 'content_menu' ) )
|
||||
{
|
||||
var menu_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'menu' );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'cookie_menus',
|
||||
menu_id: menu_id
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var page_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'id' );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'cookie_pages',
|
||||
page_id: page_id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
<?php
|
||||
$array = unserialize( $_COOKIE[ 'cookie_pages' ] );
|
||||
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
|
||||
if ( $val ):
|
||||
?>$( '.<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
|
||||
endif;
|
||||
endforeach; endif;
|
||||
|
||||
$array = unserialize( $_COOKIE[ 'cookie_menus' ] );
|
||||
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
|
||||
if ( $val ):
|
||||
?>$( '.menu_<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
|
||||
endif;
|
||||
endforeach; endif;
|
||||
?>
|
||||
});
|
||||
</script>
|
||||
204
admin/templates/pages/pages-list.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?
|
||||
global $gdb;
|
||||
|
||||
ob_start();
|
||||
if ( is_array( $this -> menus ) ) foreach ( $this -> menus as $menu )
|
||||
{
|
||||
?>
|
||||
<div class="menu_sortable">
|
||||
<ol class="sortable" id="sortable_<?= $menu['id'];?>" menu-id="<?= $menu['id'];?>">
|
||||
<li id="list_<?= $menu['id'];?>" class="menu_<?= $menu['id'];?>" menu="<?= $menu['id'];?>">
|
||||
<div class="context_0 content content_menu">
|
||||
<span class="disclose"><span></span></span>
|
||||
<? if ( !$menu['status'] ) echo '<i class="fa fa-ban fa-lg text-danger" title="Menu nieaktywne"></i>';?>
|
||||
Menu: <b><?= $menu['name'];?></b>
|
||||
<div class="btn-group ml20 pull-right">
|
||||
<a href="/admin/pages/menu_edit/id=<?= $menu['id'];?>" title="Edytuj menu" class="btn btn-sm btn-system">
|
||||
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj menu</span>
|
||||
</a>
|
||||
<a href="#" title="Usuń menu" class="btn btn-sm btn-danger menu-delete" menu-id="<?= $menu['id'];?>">
|
||||
<i class="fa fa-trash"></i> <span class="hidden-xs">Usuń menu</span>
|
||||
</a>
|
||||
<a href="/admin/pages/page_edit/pid=0&menu_id=<?= $menu['id'];?>" title="Dodaj stronę" class="btn btn-sm btn-success">
|
||||
<i class="fa fa-plus-circle"></i> <span class="hidden-xs">Dodaj stronę</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?= \admin\view\Pages::subpages_list( \admin\factory\Pages::menu_pages( $menu['id'] ) );?>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<?
|
||||
}
|
||||
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'pages-list';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Lista stron';
|
||||
$grid -> default_buttons = false;
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj menu',
|
||||
'url' => '/admin/pages/menu_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
|
||||
<script type="text/javascript">
|
||||
var menu_id = 0;
|
||||
|
||||
$( document ).ready( function()
|
||||
{
|
||||
$( 'body' ).on( 'click', '.menu-delete', function()
|
||||
{
|
||||
var menu_id = $( this ).attr( 'menu-id' );
|
||||
|
||||
$.prompt( "Na pewno chcesz usunąć wybrane menu?",
|
||||
{
|
||||
title: "Potwierdź?",
|
||||
buttons: { "Tak": true, "Nie": false },
|
||||
submit: function( e, v, m, f )
|
||||
{
|
||||
if ( v === true )
|
||||
document.location.href = '/admin/pages/menu_delete/id=' + menu_id;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'click', '.page-delete', function()
|
||||
{
|
||||
var page_id = $( this ).attr( 'page-id' );
|
||||
|
||||
$.prompt( "Na pewno chcesz usunąć wybraną stronę?",
|
||||
{
|
||||
title: "Potwierdź?",
|
||||
buttons: { "Tak": true, "Nie": false },
|
||||
submit: function( e, v, m, f )
|
||||
{
|
||||
if ( v === true )
|
||||
document.location.href = '/admin/pages/page_delete/id=' + page_id;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$( 'ol.sortable' ).nestedSortable(
|
||||
{
|
||||
forcePlaceholderSize: true,
|
||||
handle: 'div',
|
||||
helper: 'clone',
|
||||
items: 'li',
|
||||
opacity: .9,
|
||||
placeholder: 'placeholder',
|
||||
revert: 250,
|
||||
tabSize: 45,
|
||||
tolerance: 'pointer',
|
||||
toleranceElement: '> div',
|
||||
maxLevels: 4,
|
||||
isTree: true,
|
||||
expandOnHover: 700,
|
||||
stop: function() {
|
||||
save_pages_order();
|
||||
}
|
||||
});
|
||||
|
||||
$( '.disclose' ).on( 'click', function()
|
||||
{
|
||||
$( this ).closest( 'li' ).toggleClass( 'sort-collapsed' ).toggleClass( 'sort-expanded' );
|
||||
});
|
||||
|
||||
$( ".sortable *" ).mousedown( function(e)
|
||||
{
|
||||
menu_id = $( this ).parents( 'ol.sortable' ).attr( 'menu-id' );
|
||||
});
|
||||
|
||||
$( '.disclose' ).mousedown( function(e)
|
||||
{
|
||||
if ( e.which === 1 ) {
|
||||
if ( $( this ).parent( 'div' ).hasClass( 'content_menu' ) )
|
||||
{
|
||||
var menu_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'menu' );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'cookie_menus',
|
||||
menu_id: menu_id
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var page_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'id' );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data: {
|
||||
a: 'cookie_pages',
|
||||
page_id: page_id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
<?php
|
||||
$array = unserialize( $_COOKIE[ 'cookie_pages' ] );
|
||||
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
|
||||
if ( $val ):
|
||||
?>$( '.<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
|
||||
endif;
|
||||
endforeach; endif;
|
||||
|
||||
$array = unserialize( $_COOKIE[ 'cookie_menus' ] );
|
||||
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
|
||||
if ( $val ):
|
||||
?>$( '.menu_<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
|
||||
endif;
|
||||
endforeach; endif;
|
||||
?>
|
||||
});
|
||||
|
||||
function save_pages_order( )
|
||||
{
|
||||
pages = $( '#sortable_' + menu_id ).nestedSortable( 'toArray', { startDepthCount: 0 } );
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: '/admin/ajax.php',
|
||||
data:
|
||||
{
|
||||
a: 'save_pages_order',
|
||||
menu_id: menu_id,
|
||||
pages: pages
|
||||
},
|
||||
beforeSend: function()
|
||||
{
|
||||
$.prompt( 'Trwa zapisywanie...', { title: 'Proszę czekać' } );
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$( '.jqibox' ).remove();
|
||||
response = jQuery.parseJSON( data );
|
||||
|
||||
if ( response.status === 'error' )
|
||||
create_error( response.msg );
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
72
admin/templates/pages/subpages-browse-list.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<? if (is_array($this->pages)): ?>
|
||||
<?
|
||||
$settings = \front\factory\Settings::settings_details();
|
||||
?>
|
||||
<ol>
|
||||
<? foreach ($this->pages as $page): ?>
|
||||
<li id="list_<?= $page['id']; ?>" idk="<?= $page['id']; ?>" class="list_<?= $page['id']; ?>" menu="<?= $page['menu_id']; ?>">
|
||||
<div class="content">
|
||||
<span class="disclose"><span></span></span>
|
||||
<?
|
||||
if (!$page['status'])
|
||||
echo '<i class="fa fa-ban fa-lg text-danger" title="Strona nieaktywna"></i>';
|
||||
|
||||
if ($page['start'])
|
||||
echo '<i class="fa fa-star fa-lg text-system" title="Strona startowa"></i>';
|
||||
|
||||
echo mb_substr( $page['title'], 0, 50, 'UTF-8' );
|
||||
if ( strlen( $page['title'] ) > 50 )
|
||||
echo '...';
|
||||
|
||||
if (is_array($page['languages'])):
|
||||
echo '<div class="btn-group flags" style="display: inline-block;">';
|
||||
foreach ($page['languages'] as $lg)
|
||||
echo '<img src="/admin/css/lang-' . $lg['lang_id'] . '.jpg" />';
|
||||
echo '</div>';
|
||||
endif;
|
||||
|
||||
$default_language = \front\factory\Languages::default_language();
|
||||
if (is_array($page['languages'])):
|
||||
foreach ($page['languages'] as $lg):
|
||||
echo '<div class="btn-group ml20 pull-right">';
|
||||
echo '<a href="#" title="Wybierz stronę" class="btn btn-sm btn-system button url-select" url="';
|
||||
|
||||
if ($settings['links_structure']) {
|
||||
if ($lg['seo_link']) {
|
||||
$seo = '/'.\admin\factory\Pages::google_url_preview($page['id'], $lg['title'], $lg['lang_id'], 0, 0, $lg['seo_link']);
|
||||
echo $seo;
|
||||
}
|
||||
else{
|
||||
$seo = '/'. \admin\factory\Pages::google_url_preview($page['id'], $lg['title'], $lg['lang_id'], 0, 0, 0);
|
||||
echo $seo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($lg['seo_link']) {
|
||||
if ($default_language != $lg['lang_id'])
|
||||
echo '/' . $lg['lang_id'];
|
||||
echo '/' . $lg['seo_link'];
|
||||
}
|
||||
else {
|
||||
if ($default_language != $lg['lang_id'])
|
||||
echo '/' . $lg['lang_id'];
|
||||
echo '/s-' . $page['id'] . '-' . \S::seo($lg['title']);
|
||||
}
|
||||
}
|
||||
echo '">';
|
||||
echo '<i class="fa fa-check"></i> <span class="hidden-xs">' . strtoupper($lg['lang_id']) . '</span>';
|
||||
echo '</a>';
|
||||
echo '</div>';
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<?
|
||||
if (is_array($page['subpages']))
|
||||
echo \admin\view\Pages::subpages_browse_list($page['subpages'], $page['id'], $this->step + 1);
|
||||
?>
|
||||
</li>
|
||||
<? endforeach; ?>
|
||||
</ol>
|
||||
<? endif; ?>
|
||||
54
admin/templates/pages/subpages-list.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<? if ( is_array( $this -> pages ) ):?>
|
||||
<ol>
|
||||
<? foreach ( $this -> pages as $page ):?>
|
||||
<li id="list_<?= $page['id'];?>" idk="<?= $page['id'];?>" class="list_<?= $page['id'];?>" menu="<?= $page['menu_id'];?>">
|
||||
<div class="content">
|
||||
<span class="disclose"><span></span></span>
|
||||
<? if ( !$page['status'] ) echo '<i class="fa fa-ban fa-lg text-danger" title="Strona nieaktywna"></i>';?>
|
||||
<? if ( $page['start'] ) echo '<i class="fa fa-star fa-lg text-system" title="Strona startowa"></i>';?>
|
||||
<?= mb_substr( $page['title'], 0, 75, 'UTF-8' );?><? if ( mb_strlen( $page['title'], 'utf-8' ) > 75 ) echo '...';?>
|
||||
<?
|
||||
if ( is_array( $page['languages'] ) ):
|
||||
echo '<div class="btn-group flags" style="display: inline-block;">';
|
||||
foreach ( $page['languages'] as $lg )
|
||||
echo '<img src="/admin/css/lang-' . $lg['lang_id'] . '.jpg" />';
|
||||
echo '</div>';
|
||||
endif;
|
||||
?>
|
||||
<? if ( $this -> step < 3 ):?>
|
||||
<div class="btn-group ml20 pull-right">
|
||||
<a href="/admin/pages/page_edit/id=<?= $page['id'];?>&menu_id=<?= $page['menu_id'];?>" title="Edytuj stronę" class="btn btn-sm btn-system">
|
||||
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj stronę</span>
|
||||
</a>
|
||||
<a href="#" title="Usuń stronę" class="btn btn-sm btn-danger page-delete" page-id="<?= $page['id'];?>">
|
||||
<i class="fa fa-trash"></i> <span class="hidden-xs">Usuń stronę</span>
|
||||
</a>
|
||||
<a href="/admin/pages/page_articles/id=<?= $page['id'];?>" title="Lista artykułów" class="btn btn-sm btn-info" page-id="<?= $page['id'];?>">
|
||||
<i class="fa fa-bars"></i> <span class="hidden-xs">Lista artykułów</span>
|
||||
</a>
|
||||
<a href="/admin/pages/page_edit/pid=<?= $page['id'];?>&menu_id=<?= $page['menu_id'];?>" title="Dodaj podstronę" class="btn btn-sm btn-success">
|
||||
<i class="fa fa-plus-circle"></i> <span class="hidden-xs">Dodaj podstronę</span>
|
||||
</a>
|
||||
</div>
|
||||
<? else:?>
|
||||
<div class="btn-group ml20 pull-right">
|
||||
<a href="/admin/pages/page_edit/id=<?= $page['id'];?>&menu_id=<?= $page['menu_id'];?>" title="Edytuj stronę" class="btn btn-sm btn-system">
|
||||
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj stronę</span>
|
||||
</a>
|
||||
<a href="#" title="Usuń stronę" class="btn btn-sm btn-danger page-delete" page-id="<?= $page['id'];?>">
|
||||
<i class="fa fa-trash"></i> <span class="hidden-xs">Usuń stronę</span>
|
||||
</a>
|
||||
<a href="/admin/pages/page_articles/id=<?= $page['id'];?>" title="Lista artykułów" class="btn btn-sm btn-info" page-id="<?= $page['id'];?>">
|
||||
<i class="fa fa-bars"></i> <span class="hidden-xs">Lista artykułów</span>
|
||||
</a>
|
||||
</div>
|
||||
<? endif;?>
|
||||
</div>
|
||||
<?
|
||||
if ( is_array( $page['subpages'] ) )
|
||||
echo \admin\view\Pages::subpages_list( $page['subpages'], $page['id'], $this -> step + 1 );
|
||||
?>
|
||||
</li>
|
||||
<? endforeach;?>
|
||||
</ol>
|
||||
<? endif;?>
|
||||
101
admin/templates/scontainers/ckeditor-list.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_scontainers' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> sql = 'SELECT *'
|
||||
. 'FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, status, '
|
||||
. '( SELECT title FROM pp_scontainers_langs AS psl, pp_langs AS pl WHERE lang_id = pl.id AND container_id = ps.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_scontainers AS ps '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] '
|
||||
. 'ORDER BY '
|
||||
. '[order_p1] [order_p2]';
|
||||
$grid -> sql_count = 'SELECT '
|
||||
. 'COUNT(0) FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, status, '
|
||||
. '( SELECT title FROM pp_scontainers_langs AS psl, pp_langs AS pl WHERE lang_id = pl.id AND container_id = ps.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_scontainers AS ps '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] ';
|
||||
$grid -> debug = true;
|
||||
$grid -> order = [ 'column' => 'title', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Tytuł', 'db' => 'title', 'type' => 'text' ],
|
||||
[ 'name' => 'Aktywny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Tytuł',
|
||||
'db' => 'title',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Kod',
|
||||
'php' => 'echo "[KONTENER:[id]]";'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Akcja',
|
||||
'db' => 'id',
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 120px;' ],
|
||||
'php' => 'echo "<a href=\'#\' class=\'button\' text=\'[KONTENER:[id]]\'>wybierz</a>";'
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj kontener',
|
||||
'url' => '/admin/scontainers/container_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<style type="text/css">
|
||||
body.sb-top.sb-top-sm .navbar.navbar-fixed-top + #sidebar_left + #content_wrapper {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function getUrlParam(paramName)
|
||||
{
|
||||
var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i');
|
||||
var match = window.location.search.match(reParam);
|
||||
|
||||
return (match && match.length > 1) ? match[1] : '';
|
||||
}
|
||||
|
||||
$( function()
|
||||
{
|
||||
$( '#sidebar_left, .navbar-fixed-top' ).hide();
|
||||
|
||||
var funcNum = getUrlParam('CKEditorFuncNum');
|
||||
|
||||
$( 'body' ).on( 'click', '.button', function()
|
||||
{
|
||||
window.opener.CKEDITOR.tools.callFunction(funcNum, $( this ).attr( 'text' ) );
|
||||
window.close();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
171
admin/templates/scontainers/container-edit.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<link rel="stylesheet" href="/libraries/codemirror/lib/codemirror.css" />
|
||||
<link rel="stylesheet" href="/libraries/codemirror/theme/material.css" />
|
||||
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/lib/codemirror.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/css/css.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/xml/xml.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/javascript/javascript.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/mode/htmlmixed/htmlmixed.js"></script>
|
||||
<script type="text/javascript" src="/libraries/codemirror/addon/mode/multiplex.js"></script>
|
||||
<?
|
||||
global $db;
|
||||
|
||||
$_SESSION['rfm_akey'] = bin2hex(random_bytes(16));
|
||||
$_SESSION['rfm_akey_expires'] = time() + 20*60;
|
||||
$_SESSION['can_use_rfm'] = true;
|
||||
$rfmAkeyJS = $_SESSION['rfm_akey'];
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div id="settings-tabs">
|
||||
<ul class="resp-tabs-list settings-tabs">
|
||||
<li><i class="fa fa-file"></i>Treść</li>
|
||||
<li><i class="fa fa-wrench"></i>Ustawienia</li>
|
||||
</ul>
|
||||
<div class="resp-tabs-container settings-tabs">
|
||||
<div>
|
||||
<div id="languages-main">
|
||||
<ul class="resp-tabs-list languages-main">
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
<? if ( $lg['status'] ):?>
|
||||
<li><?= $lg['name'];?></a></li>
|
||||
<? endif;?>
|
||||
<? endforeach; endif;?>
|
||||
</ul>
|
||||
<div class="resp-tabs-container languages-main">
|
||||
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
|
||||
<? if ( $lg['status'] ):?>
|
||||
<div>
|
||||
<?= \Html::input(
|
||||
array(
|
||||
'label' => 'Tytuł',
|
||||
'name' => 'title',
|
||||
'id' => 'title_' . $lg['id'],
|
||||
'value' => $this -> container['languages'][ $lg['id'] ]['title'],
|
||||
'inline' => true
|
||||
)
|
||||
);?>
|
||||
<?= \Html::textarea(
|
||||
array(
|
||||
'label' => 'Treść',
|
||||
'name' => 'text',
|
||||
'id' => 'text_' . $lg['id'],
|
||||
'value' => $this -> container['languages'][ $lg['id'] ]['text'],
|
||||
'inline' => true
|
||||
)
|
||||
);?>
|
||||
<?= \Html::textarea(
|
||||
array(
|
||||
'label' => 'Kod HTML',
|
||||
'name' => 'html',
|
||||
'id' => 'html_' . $lg['id'],
|
||||
'value' => $this -> container['languages'][ $lg['id'] ]['html'],
|
||||
'inline' => true
|
||||
)
|
||||
);?>
|
||||
<script type="text/javascript">
|
||||
$( function()
|
||||
{
|
||||
$( '#text_<?= $lg['id'];?>' ).ckeditor(
|
||||
{
|
||||
toolbar : 'MyToolbar',
|
||||
height:'300'
|
||||
});
|
||||
var code_html = CodeMirror.fromTextArea( document.getElementById( "html_<?= $lg['id'];?>" ),{
|
||||
lineWrapping: true,
|
||||
mode: "text/html"
|
||||
});
|
||||
code_html.on( 'change', function(cm) {
|
||||
$( '#html_<?= $lg['id'];?>' ).val( cm.getValue() );
|
||||
});
|
||||
code_html.setOption( "theme", 'material' );
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<? endif;?>
|
||||
<? endforeach; endif;?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<?= \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Aktywny',
|
||||
'name' => 'status',
|
||||
'checked' => $this -> container['status'] == 1 or !$this -> container['id'] ? true : false
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::input_switch(
|
||||
array(
|
||||
'label' => 'Pokaż tytuł',
|
||||
'name' => 'show_title',
|
||||
'checked' => $this -> container['show_title'] == 1 ? true : false
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?= \Html::input_icon(
|
||||
array(
|
||||
'label' => 'Tło kontenera',
|
||||
'name' => 'src',
|
||||
'id' => 'src',
|
||||
'value' => $this->container['src'],
|
||||
'icon_content' => 'przeglądaj',
|
||||
'icon_js' => "window.open ( 'http://" . $_SERVER['SERVER_NAME'] . "/libraries/filemanager-9.14.1/dialog.php?type=1&popup=1&field_id=src&akey=" . $rfmAkeyJS . "', 'mywindow', 'location=1,status=1,scrollbars=1, width=1100,height=700');"
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'container-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja kontenera statycznego';
|
||||
$grid -> fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this -> container['id']
|
||||
]
|
||||
];
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/scontainers/container_save/', 'back_url' => '/admin/scontainers/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/scontainers/view_list/' ]
|
||||
];
|
||||
$grid -> external_code = $out;
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$( function()
|
||||
{
|
||||
disable_menu();
|
||||
|
||||
$( '#settings-tabs' ).easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'settings-tabs',
|
||||
type: 'vertical'
|
||||
});
|
||||
|
||||
$( '#languages-main' ).easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-main'
|
||||
});
|
||||
|
||||
$( '#g-menu' ).attr( 'data-spy', 'affix' );
|
||||
$( '#g-menu' ).attr( 'data-offset-top', '135' );
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>
|
||||
79
admin/templates/scontainers/containers-list.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid( 'pp_scontainers' );
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> sql = 'SELECT *'
|
||||
. 'FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, status, '
|
||||
. '( SELECT title FROM pp_scontainers_langs AS psl, pp_langs AS pl WHERE lang_id = pl.id AND container_id = ps.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_scontainers AS ps '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] '
|
||||
. 'ORDER BY '
|
||||
. '[order_p1] [order_p2]';
|
||||
$grid -> sql_count = 'SELECT '
|
||||
. 'COUNT(0) FROM ( '
|
||||
. 'SELECT '
|
||||
. 'id, status, '
|
||||
. '( SELECT title FROM pp_scontainers_langs AS psl, pp_langs AS pl WHERE lang_id = pl.id AND container_id = ps.id AND title != \'\' ORDER BY o ASC LIMIT 1 ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_scontainers AS ps '
|
||||
. ') AS q1 '
|
||||
. 'WHERE '
|
||||
. '1=1 [where] ';
|
||||
$grid -> debug = true;
|
||||
$grid -> order = [ 'column' => 'title', 'type' => 'ASC' ];
|
||||
$grid -> search = [
|
||||
[ 'name' => 'Tytuł', 'db' => 'title', 'type' => 'text' ],
|
||||
[ 'name' => 'Aktywny', 'db' => 'status', 'type' => 'select', 'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ] ]
|
||||
];
|
||||
$grid -> columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'th' => [ 'class' => 'g-lp' ],
|
||||
'td' => [ 'class' => 'g-center' ],
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Tytuł',
|
||||
'db' => 'title',
|
||||
'php' => 'echo "<a href=\'/admin/scontainers/container_edit/id=[id]\'>[title]</a>";',
|
||||
'sort' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Kod',
|
||||
'php' => 'echo "[KONTENER:[id]]";'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'status',
|
||||
'replace' => [ 'array' => [ 0 => '<span style="color: #FF0000;">nie</span>', 1 => 'tak' ] ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 150px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Edytuj',
|
||||
'action' => [ 'type' => 'edit', 'url' => '/admin/scontainers/container_edit/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/scontainers/container_delete/id=[id]' ],
|
||||
'th' => [ 'class' => 'g-center', 'style' => 'width: 70px;' ],
|
||||
'td' => [ 'class' => 'g-center' ]
|
||||
]
|
||||
];
|
||||
$grid -> buttons = [
|
||||
[
|
||||
'label' => 'Dodaj kontener',
|
||||
'url' => '/admin/scontainers/container_edit/',
|
||||
'icon' => 'fa-plus-circle',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
echo $grid -> draw();
|
||||