├── .csslintrc ├── .editorconfig ├── .env ├── .env.dev ├── .env.test ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug-report.yaml │ ├── config.yml │ ├── feature-request.yaml │ └── release-plan.md ├── PULL_REQUEST_TEMPLATE.md ├── SUPPORT.md ├── scripts │ ├── buildReleaseArtifacts.sh │ └── testInstall.sh └── workflows │ └── build.yml ├── .gitignore ├── .htaccess ├── .scrutinizer.yml ├── .styleci.yml ├── CHANGELOG-4.0.md ├── LICENSE ├── README.md ├── SECURITY.md ├── assets └── translator.js ├── bin ├── console └── translations.sh ├── build.php ├── build ├── BuildPackageCommand.php ├── GenerateVendorDocCommand.php └── PurgeVendorsCommand.php ├── composer.json ├── composer.lock ├── config ├── bundles.php ├── packages │ ├── cache.yaml │ ├── csrf.yaml │ ├── debug.yaml │ ├── doctrine.yaml │ ├── doctrine_migrations.yaml │ ├── framework.yaml │ ├── liip_imagine.yaml │ ├── lock.yaml │ ├── mailer.yaml │ ├── monolog.yaml │ ├── nucleos_profile.yaml │ ├── nucleos_user.yaml │ ├── rate_limiter.yaml │ ├── routing.yaml │ ├── security.yaml │ ├── stof_doctrine_extensions.yaml │ ├── translation.yaml │ ├── twig.yaml │ ├── twig_component.yaml │ ├── ux_translator.yaml │ ├── validator.yaml │ ├── web_profiler.yaml │ └── workflow.yaml ├── preload.php ├── routes.yaml ├── routes │ ├── easyadmin.yaml │ ├── fos_js_routing.yaml │ ├── framework.yaml │ ├── liip_imagine.yaml │ ├── nucleos_profile.yaml │ ├── nucleos_user.yaml │ ├── security.yaml │ ├── web_profiler.yaml │ ├── zikula_legal.yaml │ ├── zikula_theme.yaml │ └── zikula_users.yaml ├── services.yaml └── workflows │ └── README ├── docs ├── Development │ ├── Doctrine │ │ ├── README.md │ │ ├── UtcDateTimeType.md │ │ └── WhereFromFilterTrait.md │ └── Misc │ │ ├── CacheClearer.md │ │ ├── LocaleApi.md │ │ ├── Performance.md │ │ ├── README.md │ │ └── Workflows.md ├── LayoutDesign │ ├── Forms │ │ ├── FormHelpers.md │ │ └── README.md │ ├── Templating │ │ ├── DebuggingTwig.md │ │ ├── Filters.md │ │ ├── Functions.md │ │ ├── Imagine.md │ │ ├── README.md │ │ ├── SiteDefinition.md │ │ ├── Tags.md │ │ └── TemplateAndAssetLocations.md │ └── Themes │ │ ├── Branding.md │ │ └── README.md ├── README.md ├── Setup │ ├── Installation.md │ ├── InstallingZikulaOnUbuntu.md │ ├── Production.md │ └── Requirements.md └── Translation │ ├── Contributing.md │ ├── Debugging.md │ ├── Dev │ └── TranslatorTrait.md │ ├── Intl.md │ ├── Javascript.md │ ├── Overriding.md │ ├── README.md │ ├── Terminology.md │ ├── Translation.md │ └── Usage.md ├── migrations └── .gitignore ├── php_cs_fixer.dist.php ├── phpstan.neon ├── phpunit.dist.xml ├── public ├── .htaccess ├── android-chrome-192x192.png ├── android-chrome-256x256.png ├── apple-touch-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.php ├── mstile-150x150.png ├── robots.txt ├── safari-pinned-tab.svg ├── site.webmanifest └── uploads │ └── .htaccess ├── renovate.json5 ├── src ├── Kernel.php └── system │ ├── CoreBundle │ ├── .gitattributes │ ├── README.md │ ├── bin │ │ └── console │ ├── composer.json │ ├── config │ │ ├── definition.php │ │ └── services.yaml │ ├── phpunit.dist.xml │ ├── public │ │ ├── css │ │ │ └── core.css │ │ ├── images │ │ │ ├── admin.png │ │ │ ├── ajax │ │ │ │ ├── zktimer_48px_black.gif │ │ │ │ ├── zktimer_48px_black_rounded.gif │ │ │ │ ├── zktimer_48px_white.gif │ │ │ │ └── zktimer_48px_white_rounded.gif │ │ │ ├── icon.png │ │ │ ├── logo.gif │ │ │ ├── logo_small.png │ │ │ ├── logo_with_title.gif │ │ │ ├── logo_with_title.png │ │ │ └── zk-power.png │ │ └── js │ │ │ ├── bootstrap-zikula.js │ │ │ ├── paginator.js │ │ │ └── simplePagination.js │ │ │ ├── LICENSE.txt │ │ │ ├── README.md │ │ │ ├── bower.json │ │ │ ├── jquery.simplePagination.js │ │ │ └── simplePagination.css │ ├── src │ │ ├── Api │ │ │ ├── ApiInterface │ │ │ │ └── LocaleApiInterface.php │ │ │ └── LocaleApi.php │ │ ├── Bundle │ │ │ ├── Initializer │ │ │ │ ├── BundleInitializerInterface.php │ │ │ │ └── InitializableBundleInterface.php │ │ │ └── MetaData │ │ │ │ ├── BundleMetaDataInterface.php │ │ │ │ └── MetaDataAwareBundleInterface.php │ │ ├── Command │ │ │ ├── InitBundleCommand.php │ │ │ └── TranslationKeyToValueCommand.php │ │ ├── Doctrine │ │ │ └── DBAL │ │ │ │ ├── CustomTypes.php │ │ │ │ └── Type │ │ │ │ └── UTCDateTimeType.php │ │ ├── EventSubscriber │ │ │ ├── ClickjackProtectionSubscriber.php │ │ │ ├── LocaleSubscriber.php │ │ │ └── SiteOffSubscriber.php │ │ ├── Response │ │ │ └── PlainResponse.php │ │ ├── Site │ │ │ ├── SiteDefinition.php │ │ │ └── SiteDefinitionInterface.php │ │ ├── Translation │ │ │ ├── Extractor │ │ │ │ └── Visitor │ │ │ │ │ └── Php │ │ │ │ │ └── Zikula │ │ │ │ │ ├── FormTypeAlert.php │ │ │ │ │ └── FormTypeInputGroup.php │ │ │ └── TranslatorTrait.php │ │ ├── Twig │ │ │ ├── Extension │ │ │ │ └── CoreExtension.php │ │ │ └── Runtime │ │ │ │ └── CoreRuntime.php │ │ └── ZikulaCoreBundle.php │ ├── templates │ │ └── System │ │ │ └── siteoff.html.twig │ ├── tests │ │ └── Api │ │ │ ├── Fixtures │ │ │ └── translations │ │ │ │ ├── bar.de.po │ │ │ │ ├── foo.de.po │ │ │ │ ├── messages.de.po │ │ │ │ ├── messages.de_DE.po │ │ │ │ ├── messages.en.po │ │ │ │ ├── messages.ru.po │ │ │ │ ├── messages.template.po │ │ │ │ └── sub │ │ │ │ └── messages.it.po │ │ │ └── LocaleApiTest.php │ └── workflows │ │ └── README │ ├── LegalBundle │ ├── .gitattributes │ ├── README.md │ ├── composer.json │ ├── config │ │ ├── definition.php │ │ ├── routing.yaml │ │ └── services.yaml │ ├── phpunit.dist.xml │ ├── public │ │ └── js │ │ │ └── ZikulaLegalBundle.User.AcceptPolicies.js │ ├── src │ │ ├── Bundle │ │ │ └── MetaData │ │ │ │ └── LegalBundleMetaData.php │ │ ├── Controller │ │ │ └── UserController.php │ │ ├── Entity │ │ │ ├── LegalAwareUserInterface.php │ │ │ └── LegalAwareUserTrait.php │ │ ├── Form │ │ │ ├── Extension │ │ │ │ └── PoliciesExtension.php │ │ │ └── Type │ │ │ │ └── AcceptPoliciesType.php │ │ ├── Helper │ │ │ └── AcceptPoliciesHelper.php │ │ ├── Menu │ │ │ └── ExtensionMenu.php │ │ ├── Twig │ │ │ └── TwigExtension.php │ │ └── ZikulaLegalBundle.php │ └── templates │ │ ├── Form │ │ └── acceptPolicies.html.twig │ │ ├── PolicyContent │ │ └── en │ │ │ ├── accessibilityStatement.html.twig │ │ │ ├── cancellationRightPolicy.html.twig │ │ │ ├── legalNotice.html.twig │ │ │ ├── privacyPolicy.html.twig │ │ │ ├── termsOfUse.html.twig │ │ │ └── tradeConditions.html.twig │ │ └── User │ │ ├── Policy │ │ ├── Display │ │ │ ├── accessibilityStatement.html.twig │ │ │ ├── cancellationRightPolicy.html.twig │ │ │ ├── legalNotice.html.twig │ │ │ ├── policyNotActive.html.twig │ │ │ ├── privacyPolicy.html.twig │ │ │ ├── template.html.twig │ │ │ ├── termsOfUse.html.twig │ │ │ └── tradeConditions.html.twig │ │ └── InlineLink │ │ │ ├── accessibilityStatement.html.twig │ │ │ ├── cancellationRightPolicy.html.twig │ │ │ ├── legalNotice.html.twig │ │ │ ├── notFound.html.twig │ │ │ ├── privacyPolicy.html.twig │ │ │ ├── termsOfUse.html.twig │ │ │ └── tradeConditions.html.twig │ │ └── acceptPolicies.html.twig │ ├── ThemeBundle │ ├── .gitattributes │ ├── LICENSE │ ├── README.md │ ├── composer.json │ ├── config │ │ ├── definition.php │ │ ├── routing.yaml │ │ └── services.yaml │ ├── phpunit.dist.xml │ ├── public │ │ ├── css │ │ │ ├── ZikulaThemeBundle.IconPicker.css │ │ │ ├── jstree.Common.css │ │ │ └── phpinfo.css │ │ ├── dashboard │ │ │ ├── admin.css │ │ │ ├── admin.js │ │ │ ├── user.css │ │ │ └── user.js │ │ ├── images │ │ │ ├── preview_large.png │ │ │ ├── preview_medium.png │ │ │ └── preview_small.png │ │ └── js │ │ │ ├── ZikulaThemeBundle.FilePicker.js │ │ │ ├── ZikulaThemeBundle.IconPicker.js │ │ │ ├── ZikulaThemeBundle.Phpinfo.js │ │ │ ├── ZikulaThemeBundle.TestMail.js │ │ │ ├── bs-custom-file-input │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── bs-custom-file-input.js │ │ │ ├── bs-custom-file-input.js.map │ │ │ ├── bs-custom-file-input.min.js │ │ │ └── bs-custom-file-input.min.js.map │ │ │ ├── fontawesome-iconpicker │ │ │ ├── LICENSE │ │ │ ├── css │ │ │ │ ├── fontawesome-iconpicker.css │ │ │ │ └── fontawesome-iconpicker.min.css │ │ │ ├── js │ │ │ │ ├── fontawesome-iconpicker.js │ │ │ │ └── fontawesome-iconpicker.min.js │ │ │ └── version.txt │ │ │ └── jquery │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ ├── jquery.min.map │ │ │ ├── jquery.slim.js │ │ │ ├── jquery.slim.min.js │ │ │ ├── jquery.slim.min.map │ │ │ └── version.txt │ ├── src │ │ ├── Bundle │ │ │ └── MetaData │ │ │ │ └── ThemeBundleMetaData.php │ │ ├── Controller │ │ │ ├── BrandingController.php │ │ │ ├── Dashboard │ │ │ │ ├── AbstractThemedDashboardController.php │ │ │ │ ├── AdminDashboardController.php │ │ │ │ └── UserDashboardController.php │ │ │ ├── TestController.php │ │ │ └── ToolController.php │ │ ├── Entity │ │ │ └── AdminCategory.php │ │ ├── EventSubscriber │ │ │ ├── CreateThemedResponseSubscriber.php │ │ │ └── OutputCompressionSubscriber.php │ │ ├── ExtensionMenu │ │ │ ├── AbstractExtensionMenu.php │ │ │ ├── ExtensionMenuCollector.php │ │ │ ├── ExtensionMenuEvent.php │ │ │ └── ExtensionMenuInterface.php │ │ ├── Form │ │ │ ├── DataTransformer │ │ │ │ └── NullToEmptyTransformer.php │ │ │ ├── Extension │ │ │ │ ├── ButtonTypeIconExtension.php │ │ │ │ └── FormTypeHelpExtension.php │ │ │ └── Type │ │ │ │ ├── DeletionType.php │ │ │ │ ├── IconType.php │ │ │ │ └── MailTestType.php │ │ ├── Helper │ │ │ ├── AdminCategoryHelper.php │ │ │ ├── FallbackDashboardDetector.php │ │ │ ├── ResourceMenuProvider.php │ │ │ └── UserMenuExtensionHelper.php │ │ ├── Menu │ │ │ └── ExtensionMenu.php │ │ ├── Twig │ │ │ ├── Extension │ │ │ │ └── BrandingExtension.php │ │ │ └── Runtime │ │ │ │ └── BrandingRuntime.php │ │ └── ZikulaThemeBundle.php │ ├── templates │ │ ├── Branding │ │ │ ├── manifest.html.twig │ │ │ └── overview.html.twig │ │ ├── Dashboard │ │ │ ├── layout_admin.html.twig │ │ │ ├── layout_user.html.twig │ │ │ └── manifest.html.twig │ │ ├── Form │ │ │ ├── bootstrap_4_zikula_admin_layout.html.twig │ │ │ ├── form_div_layout.html.twig │ │ │ └── icon_picker.html.twig │ │ ├── Test │ │ │ └── page.html.twig │ │ ├── Tool │ │ │ ├── phpinfo.html.twig │ │ │ └── testmail.html.twig │ │ └── welcome.html.twig │ └── tests │ │ └── ExtensionMenu │ │ ├── ExtensionMenuCollectorTest.php │ │ └── Fixtures │ │ ├── BarExtensionMenu.php │ │ └── FooExtensionMenu.php │ └── UsersBundle │ ├── .gitattributes │ ├── LICENSE │ ├── README.md │ ├── composer.json │ ├── config │ ├── definition.php │ ├── routing.yaml │ └── services.yaml │ ├── phpunit.dist.xml │ ├── public │ └── js │ │ └── ZikulaUsersBundle.Avatar.Edit.js │ ├── src │ ├── Bundle │ │ ├── Initializer │ │ │ └── UsersInitializer.php │ │ └── MetaData │ │ │ └── UsersBundleMetaData.php │ ├── Controller │ │ ├── GroupCrudController.php │ │ └── UserCrudController.php │ ├── Entity │ │ ├── Group.php │ │ ├── User.php │ │ ├── UserAttribute.php │ │ └── UserAttributesTrait.php │ ├── Form │ │ └── Type │ │ │ ├── AvatarType.php │ │ │ └── MailType.php │ ├── Helper │ │ ├── ChoiceHelper.php │ │ ├── GravatarHelper.php │ │ ├── MailHelper.php │ │ ├── ProfileHelper.php │ │ └── UploadHelper.php │ ├── Menu │ │ └── ExtensionMenu.php │ ├── ProfileConstant.php │ ├── Repository │ │ ├── UserRepository.php │ │ └── UserRepositoryInterface.php │ ├── Twig │ │ ├── Extension │ │ │ └── ProfileExtension.php │ │ └── Runtime │ │ │ └── ProfileRuntime.php │ ├── UsersConstant.php │ └── ZikulaUsersBundle.php │ └── templates │ └── Email │ ├── footer.txt.twig │ ├── header.txt.twig │ ├── regadminnotify.html.twig │ ├── regadminnotify.txt.twig │ ├── regdeny.html.twig │ ├── regdeny.txt.twig │ ├── welcome.html.twig │ └── welcome.txt.twig ├── symfony.lock ├── templates └── bundles │ ├── NucleosProfileBundle │ ├── Profile │ │ ├── edit_content.html.twig │ │ ├── show_content.html.twig │ │ └── show_profile_fields.html.twig │ └── Registration │ │ └── register_content.html.twig │ └── NucleosUserBundle │ └── layout.html.twig ├── tests └── bootstrap.php ├── translations └── .gitkeep └── var └── cache └── .htaccess /.csslintrc: -------------------------------------------------------------------------------- 1 | --exclude-exts=.min.css 2 | --ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; top-most EditorConfig file 2 | root = true 3 | 4 | ; Unix-style newlines 5 | [*] 6 | end_of_line = LF 7 | 8 | [*.php] 9 | indent_style = space 10 | indent_size = 4 11 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # In all environments, the following files are loaded if they exist, 2 | # the latter taking precedence over the former: 3 | # 4 | # * .env contains default values for the environment variables needed by the app 5 | # * .env.local uncommitted file with local overrides 6 | # * .env.$APP_ENV committed environment-specific defaults 7 | # * .env.$APP_ENV.local uncommitted environment-specific overrides 8 | # 9 | # Real environment variables win over .env files. 10 | # 11 | # DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. 12 | # https://symfony.com/doc/current/configuration/secrets.html 13 | # 14 | # Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). 15 | # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration 16 | 17 | ###> symfony/framework-bundle ### 18 | APP_ENV=prod 19 | APP_DEBUG=0 20 | APP_SECRET= 21 | DEFAULT_URI=https://localhost 22 | ###< symfony/framework-bundle ### 23 | 24 | ###> doctrine/doctrine-bundle ### 25 | # Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url 26 | # IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml 27 | # 28 | # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db" 29 | # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" 30 | # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" 31 | DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" 32 | ###< doctrine/doctrine-bundle ### 33 | 34 | ###> symfony/mailer ### 35 | MAILER_DSN=null://null 36 | ###< symfony/mailer ### 37 | 38 | ###> nucleos/user-bundle ### 39 | MAIL_SENDER=no-reply@localhost 40 | ###< nucleos/user-bundle ### 41 | 42 | ###> symfony/lock ### 43 | # Choose one of the stores below 44 | # postgresql+advisory://db_user:db_password@localhost/db_name 45 | LOCK_DSN=flock 46 | ###< symfony/lock ### 47 | -------------------------------------------------------------------------------- /.env.dev: -------------------------------------------------------------------------------- 1 | 2 | ###> symfony/framework-bundle ### 3 | APP_SECRET=%generate(secret)% 4 | ###< symfony/framework-bundle ### 5 | -------------------------------------------------------------------------------- /.env.test: -------------------------------------------------------------------------------- 1 | KERNEL_CLASS=Kernel 2 | APP_SECRET='$ecretf0rt3st' 3 | DEFAULT_URI=https://localhost 4 | DATABASE_URL='mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7' 5 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*{.,-}min.js 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # .gitattributes snippet to force users to use same line endings for project. 2 | # 3 | # Handle line endings automatically for files detected as text 4 | # and leave all files detected as binary untouched. 5 | * text=auto 6 | 7 | # 8 | # The above will handle all files NOT found below 9 | # https://help.github.com/articles/dealing-with-line-endings/ 10 | # https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes 11 | 12 | 13 | 14 | # These files are text and should be normalized (Convert crlf => lf) 15 | *.php text 16 | *.css text 17 | *.js text 18 | *.json text 19 | *.htm text 20 | *.html text 21 | *.xml text 22 | *.txt text 23 | *.ini text 24 | *.inc text 25 | *.pl text 26 | *.rb text 27 | *.py text 28 | *.scm text 29 | *.sql text 30 | .htaccess text 31 | *.sh text 32 | 33 | # These files are binary and should be left untouched 34 | # (binary is a macro for -text -diff) 35 | *.png binary 36 | *.jpg binary 37 | *.jpeg binary 38 | *.gif binary 39 | *.ico binary 40 | *.mov binary 41 | *.mp4 binary 42 | *.mp3 binary 43 | *.flv binary 44 | *.fla binary 45 | *.swf binary 46 | *.gz binary 47 | *.zip binary 48 | *.7z binary 49 | *.ttf binary 50 | *.pyc binary 51 | 52 | /composer.lock -merge 53 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | To contribute to the project, you must agree to our CLA. To get started, [sign the Contributor License Agreement](https://www.clahub.com/agreements/zikula/core). Be sure to use your GitHub email address. 4 | 5 | Pull requests are welcome, please see [this page](https://docs.ziku.la/General/Contributing/index.html). 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discussions 4 | url: https://github.com/zikula/core/discussions 5 | about: Feel free to talk with us. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yaml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Tell us about a new addition you want to see 3 | labels: [Feature] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this feature request! 9 | - type: textarea 10 | id: summary 11 | attributes: 12 | label: Summary 13 | description: Pleaseprovide a brief overview of what the new feature is all about. 14 | render: bash 15 | validations: 16 | required: true 17 | - type: textarea 18 | id: desired-behavior 19 | attributes: 20 | label: Desired behaviour 21 | description: Please tell us, how the new feature should work, be specific. 22 | placeholder: Describe what you imagine! 23 | render: bash 24 | validations: 25 | required: true 26 | - type: textarea 27 | id: possible-solution 28 | attributes: 29 | label: Possible solution 30 | description: Not required, but suggest ideas on how to implement the addition or change. 31 | render: bash 32 | - type: textarea 33 | id: context 34 | attributes: 35 | label: Context 36 | description: Why does this feature matter to you? What unique circumstances do you have? 37 | render: bash 38 | - type: dropdown 39 | id: zikula-version 40 | attributes: 41 | label: Zikula version 42 | description: Which Zikula version are you running? 43 | options: 44 | - 4.x-git 45 | - 3.1.0 46 | - 3.0.x 47 | validations: 48 | required: true 49 | - type: dropdown 50 | id: php-version 51 | attributes: 52 | label: PHP version 53 | description: Which PHP version are you running? 54 | options: 55 | - 8.4.x 56 | - 8.3.x 57 | - 8.2.x 58 | - older 59 | validations: 60 | required: true 61 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | | Q | A 2 | | ----------------- | --- 3 | | Bug fix? | [yes/no] 4 | | New feature? | [yes/no] 5 | | BC breaks? | no 6 | | Deprecations? | no 7 | | Fixed tickets | - 8 | | Refs tickets | - 9 | | License | MIT 10 | | Changelog updated | [yes/no] 11 | 12 | ## Description 13 | 14 | A few sentences describing the overall goals of the pull request's commits. 15 | 16 | ## Todos 17 | 18 | - [ ] Tests 19 | - [ ] Documentation 20 | - [ ] Changelog 21 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support options for Zikula 2 | 3 | - [Documentation](https://docs.ziku.la/) 4 | - [Slack](https://zikula.slack.com/) - [join here](https://joinslack.ziku.la/) 5 | -------------------------------------------------------------------------------- /.github/scripts/testInstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # setup 5 | mysqlCmd="mysql -h 127.0.0.1 --port 3306 -u root -p12345678" 6 | ${mysqlCmd} -e "CREATE DATABASE zk_test;" 7 | 8 | # action 9 | php bin/console zikula:install:start -n --database_host=127.0.0.1 --database_user=root --database_name=zk_test --database_password=12345678 --password=12345678 --email=admin@example.com --router:request_context:host=localhost --router:request_context:base_url='/' -vvv 10 | php bin/console zikula:install:finish -n -vvv 11 | 12 | # cleanup 13 | ${mysqlCmd} -e "DROP DATABASE zk_test" 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /composer 2 | /composer.phar 3 | /bin/ 4 | /bin/* 5 | !/bin/console 6 | /config/packages/core.yaml 7 | /config/packages/zikula*.yaml 8 | *.phpunit.result.cache 9 | /public/* 10 | !/public/index.php 11 | !/public/uploads/ 12 | !/public/*.ico 13 | !/public/*.png 14 | !/public/*.svg 15 | !/public/browserconfig.xml 16 | !/public/robots 17 | !/public/site.webmanifest 18 | /src/extensions/* 19 | !src/extensions/.gitignore 20 | src/.preload.php 21 | /templates/ 22 | !/templates/bundles/TranslationBundle/WebUI/base.html.twig 23 | /translations/* 24 | /webpack.config.js 25 | !/var/cache/.htaccess 26 | /.vagrant 27 | 28 | ###> symfony/framework-bundle ### 29 | /.env.local 30 | /.env.local.php 31 | /.env.*.local 32 | /config/secrets/prod/prod.decrypt.private.php 33 | /public/bundles/ 34 | /var/ 35 | /vendor/ 36 | ###< symfony/framework-bundle ### 37 | 38 | ###> liip/imagine-bundle ### 39 | /public/media/cache/ 40 | ###< liip/imagine-bundle ### 41 | 42 | ###> phpunit/phpunit ### 43 | /phpunit.xml 44 | /.phpunit.cache/ 45 | ###< phpunit/phpunit ### 46 | 47 | ###> symfony/webpack-encore-bundle ### 48 | /node_modules/ 49 | /public/build/ 50 | npm-debug.log 51 | yarn-error.log 52 | ###< symfony/webpack-encore-bundle ### 53 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | # Block any web access to any folders (undone in /public/.htaccess) 2 | 3 | # Apache 2.2 4 | Deny from all 5 | 6 | 7 | # Apache 2.4 8 | Require all denied 9 | 10 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: symfony 2 | risky: true 3 | 4 | enabled: 5 | - alpha_ordered_imports 6 | - combine_consecutive_issets 7 | - combine_consecutive_unsets 8 | - concat_with_spaces 9 | - declare_strict_types 10 | - explicit_indirect_variable 11 | - explicit_string_variable 12 | - mb_str_functions 13 | - multiline_comment_opening_closing 14 | - no_null_property_initialization 15 | - no_php4_constructor 16 | - no_useless_else 17 | - php_unit_mock 18 | - php_unit_namespaced 19 | - php_unit_set_up_tear_down_visibility 20 | - random_api_migration 21 | - strict_comparison 22 | - ternary_to_null_coalescing 23 | 24 | disabled: 25 | - concat_without_spaces 26 | - function_declaration 27 | - native_constant_invocation_symfony 28 | - native_function_invocation_symfony 29 | - no_blank_lines_after_phpdoc 30 | - no_blank_lines_after_throw 31 | - php_unit_fqcn_annotation 32 | - phpdoc_align 33 | - phpdoc_scalar 34 | - phpdoc_separation 35 | - phpdoc_summary 36 | - phpdoc_to_comment 37 | - pre_increment 38 | - single_quote 39 | - trailing_comma_in_multiline_array 40 | - unalign_double_arrow 41 | - unalign_equals 42 | 43 | finder: 44 | not-name: 45 | - "bundles.php" 46 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report a vulnerability please send it to the email address . 6 | 7 | Thank you very much. 8 | -------------------------------------------------------------------------------- /assets/translator.js: -------------------------------------------------------------------------------- 1 | import { trans, getLocale, setLocale, setLocaleFallbacks } from '@symfony/ux-translator'; 2 | /* 3 | * This file is part of the Symfony UX Translator package. 4 | * 5 | * If folder "../var/translations" does not exist, or some translations are missing, 6 | * you must warmup your Symfony cache to refresh JavaScript translations. 7 | * 8 | * If you use TypeScript, you can rename this file to "translator.ts" to take advantage of types checking. 9 | */ 10 | 11 | setLocaleFallbacks(localeFallbacks); 12 | 13 | export { trans }; 14 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | ../src/system/CoreBundle/bin/console -------------------------------------------------------------------------------- /bin/translations.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SCRIPT_PATH=$(dirname "$(realpath $0)") 5 | cd ${SCRIPT_PATH}/.. 6 | 7 | php -dxdebug.max_nesting_level=500 bin/console translation:extract --force --format=yaml --sort=asc en 8 | php -dxdebug.max_nesting_level=500 bin/console translation:extract --force --format=yaml --sort=asc de 9 | php bin/console zikula:translation:keytovalue 10 | -------------------------------------------------------------------------------- /build.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | add(new BuildPackageCommand()); 24 | $application->add(new PurgeVendorsCommand()); 25 | $application->add(new GenerateVendorDocCommand()); 26 | $application->run(); 27 | -------------------------------------------------------------------------------- /config/bundles.php: -------------------------------------------------------------------------------- 1 | ['all' => true], 7 | Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], 8 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], 9 | Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], 10 | Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], 11 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], 12 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], 13 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], 14 | Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], 15 | Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], 16 | FOS\JsRoutingBundle\FOSJsRoutingBundle::class => ['all' => true], 17 | Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], 18 | EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true], 19 | Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], 20 | Zikula\CoreBundle\ZikulaCoreBundle::class => ['all' => true], 21 | Zikula\LegalBundle\ZikulaLegalBundle::class => ['all' => true], 22 | Zikula\ThemeBundle\ZikulaThemeBundle::class => ['all' => true], 23 | Zikula\UsersBundle\ZikulaUsersBundle::class => ['all' => true], 24 | Nucleos\UserBundle\NucleosUserBundle::class => ['all' => true], 25 | Nucleos\ProfileBundle\NucleosProfileBundle::class => ['all' => true], 26 | Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true], 27 | ]; 28 | -------------------------------------------------------------------------------- /config/packages/cache.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | cache: 3 | # Unique name of your app: used to compute stable namespaces for cache keys. 4 | #prefix_seed: your_vendor_name/app_name 5 | 6 | # The "app" cache stores to the filesystem by default. 7 | # The data in this cache should persist between deploys. 8 | # Other options include: 9 | 10 | # Redis 11 | #app: cache.adapter.redis 12 | #default_redis_provider: redis://localhost 13 | 14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) 15 | #app: cache.adapter.apcu 16 | 17 | # Namespaced pools use the above "app" backend by default 18 | #pools: 19 | #my.dedicated.cache: null 20 | -------------------------------------------------------------------------------- /config/packages/csrf.yaml: -------------------------------------------------------------------------------- 1 | # Enable stateless CSRF protection for forms and logins/logouts 2 | framework: 3 | form: 4 | csrf_protection: 5 | token_id: submit 6 | 7 | csrf_protection: 8 | stateless_token_ids: 9 | - submit 10 | - authenticate 11 | - logout 12 | -------------------------------------------------------------------------------- /config/packages/debug.yaml: -------------------------------------------------------------------------------- 1 | when@dev: 2 | debug: 3 | # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser. 4 | # See the "server:dump" command to start a new server. 5 | dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%" 6 | -------------------------------------------------------------------------------- /config/packages/doctrine_migrations.yaml: -------------------------------------------------------------------------------- 1 | doctrine_migrations: 2 | migrations_paths: 3 | # namespace is arbitrary but should be different from App\Migrations 4 | # as migrations classes should NOT be autoloaded 5 | 'DoctrineMigrations': '%kernel.project_dir%/migrations' 6 | enable_profiler: false 7 | -------------------------------------------------------------------------------- /config/packages/framework.yaml: -------------------------------------------------------------------------------- 1 | # see https://symfony.com/doc/current/reference/configuration/framework.html 2 | framework: 3 | secret: '%env(APP_SECRET)%' 4 | 5 | # Note that the session will ONLY be started if you read or write from it. 6 | session: 7 | enabled: true 8 | handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler 9 | use_cookies: true 10 | cookie_lifetime: 21600 # 6 hours 11 | cookie_secure: true 12 | cookie_samesite: none 13 | cookie_httponly: true 14 | gc_divisor: 100 15 | gc_probability: 5 #/ 5% chance to gc 16 | gc_maxlifetime: 43200 # 12 hours 17 | 18 | #esi: true 19 | #fragments: true 20 | 21 | when@dev: 22 | framework: 23 | profiler: { only_exceptions: false } 24 | # see https://symfony.com/doc/current/reference/configuration/framework.html#ide 25 | #ide: phpstorm 26 | 27 | when@test: 28 | framework: 29 | test: true 30 | session: 31 | handler_id: session.handler.native_file 32 | storage_factory_id: session.storage.factory.mock_file 33 | -------------------------------------------------------------------------------- /config/packages/liip_imagine.yaml: -------------------------------------------------------------------------------- 1 | # Documentation on how to configure the bundle can be found at: https://symfony.com/doc/current/bundles/LiipImagineBundle/basic-usage.html 2 | liip_imagine: 3 | # valid drivers options include "gd" or "gmagick" or "imagick" 4 | driver: 'gd' 5 | resolvers: 6 | default: 7 | web_path: 8 | web_root: "%kernel.project_dir%/public" 9 | cache_prefix: "media/cache" 10 | loaders: 11 | zikula_root: 12 | filesystem: 13 | data_root: "%kernel.project_dir%/public" 14 | default: 15 | filesystem: 16 | data_root: "%kernel.project_dir%/public" 17 | filter_sets: 18 | cache: ~ 19 | my_thumb: # sample 20 | jpeg_quality: 90 21 | png_compression_level: 7 22 | filters: 23 | thumbnail: { size: [120, 90], mode: outbound } 24 | background: { size: [124, 94], position: center, color: '#000000' } 25 | zkroot: # sample using zikula root 26 | data_loader: zikula_root 27 | jpeg_quality: 90 28 | png_compression_level: 7 29 | filters: 30 | thumbnail: { size: [100, 100], mode: inset } 31 | # add more filters as required for your personal application 32 | -------------------------------------------------------------------------------- /config/packages/lock.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | lock: '%env(LOCK_DSN)%' 3 | -------------------------------------------------------------------------------- /config/packages/mailer.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | mailer: 3 | dsn: '%env(MAILER_DSN)%' 4 | -------------------------------------------------------------------------------- /config/packages/nucleos_profile.yaml: -------------------------------------------------------------------------------- 1 | # see https://docs.nucleos.rocks/projects/profile-bundle/en/1.5.x/configuration.html 2 | nucleos_profile: 3 | registration: 4 | confirmation: 5 | enabled: true 6 | from_email: '%env(MAIL_SENDER)%' 7 | -------------------------------------------------------------------------------- /config/packages/nucleos_user.yaml: -------------------------------------------------------------------------------- 1 | # see https://docs.nucleos.rocks/projects/user-bundle/en/2.0.x/configuration_reference.html 2 | nucleos_user: 3 | db_driver: orm 4 | user_class: 'Zikula\UsersBundle\Entity\User' 5 | firewall_name: main 6 | from_email: '%env(MAIL_SENDER)%' 7 | deletion: 8 | enabled: true 9 | group: 10 | group_class: 'Zikula\UsersBundle\Entity\Group' 11 | loggedin: 12 | route: 'user_dashboard' # Redirect route after login 13 | -------------------------------------------------------------------------------- /config/packages/rate_limiter.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | rate_limiter: 3 | test_mails: 4 | policy: 'fixed_window' 5 | limit: 5 6 | interval: '30 minutes' 7 | -------------------------------------------------------------------------------- /config/packages/routing.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | router: 3 | # Configure how to generate URLs in non-HTTP contexts, such as CLI commands. 4 | # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands 5 | default_uri: '%env(DEFAULT_URI)%' 6 | #default_uri: http://localhost 7 | 8 | when@prod: 9 | # In production environment you should know that the parameters for URL generation 10 | # always pass the requirements. Otherwise it would break your link (or even site with 11 | # strict_requirements = true). So we can disable the requirements check completely for 12 | # enhanced performance with strict_requirements = null. 13 | framework: 14 | router: 15 | strict_requirements: null 16 | -------------------------------------------------------------------------------- /config/packages/stof_doctrine_extensions.yaml: -------------------------------------------------------------------------------- 1 | # Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html 2 | # See the official DoctrineExtensions documentation for more details: https://github.com/doctrine-extensions/DoctrineExtensions/tree/main/doc 3 | stof_doctrine_extensions: 4 | default_locale: en_US 5 | #default_locale: '%locale%' 6 | persist_default_translation: false 7 | translation_fallback: true 8 | orm: 9 | default: 10 | # if removed these values default to false 11 | translatable: true 12 | timestampable: true 13 | blameable: true 14 | sluggable: true 15 | tree: true 16 | loggable: true 17 | ip_traceable: true 18 | sortable: true 19 | softdeleteable: true 20 | uploadable: true 21 | reference_integrity: true 22 | -------------------------------------------------------------------------------- /config/packages/translation.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | default_locale: en 3 | #enabled_locales: [en, de] 4 | translator: 5 | default_path: '%kernel.project_dir%/translations' 6 | fallbacks: 7 | - en 8 | # providers: 9 | # enable language negotiation 10 | set_locale_from_accept_language: true 11 | set_content_language_from_locale: true 12 | -------------------------------------------------------------------------------- /config/packages/twig.yaml: -------------------------------------------------------------------------------- 1 | twig: 2 | default_path: '%kernel.project_dir%/templates' 3 | form_themes: [ 4 | '@ZikulaTheme/Form/bootstrap_4_zikula_admin_layout.html.twig', 5 | '@ZikulaTheme/Form/form_div_layout.html.twig' 6 | ] 7 | file_name_pattern: '*.twig' 8 | 9 | when@test: 10 | twig: 11 | strict_variables: true 12 | -------------------------------------------------------------------------------- /config/packages/twig_component.yaml: -------------------------------------------------------------------------------- 1 | twig_component: 2 | anonymous_template_directory: 'components/' 3 | defaults: 4 | # Namespace & directory for components 5 | App\Twig\Components\: 'components/' 6 | -------------------------------------------------------------------------------- /config/packages/ux_translator.yaml: -------------------------------------------------------------------------------- 1 | ux_translator: 2 | # The directory where the JavaScript translations are dumped 3 | dump_directory: '%kernel.project_dir%/var/translations' 4 | -------------------------------------------------------------------------------- /config/packages/validator.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | validation: 3 | enable_attributes: true 4 | 5 | # Enables validator auto-mapping support. 6 | # For instance, basic validation constraints will be inferred from Doctrine's metadata. 7 | #auto_mapping: 8 | # App\Entity\: [] 9 | 10 | when@test: 11 | framework: 12 | validation: 13 | not_compromised_password: false 14 | -------------------------------------------------------------------------------- /config/packages/web_profiler.yaml: -------------------------------------------------------------------------------- 1 | when@dev: 2 | web_profiler: 3 | toolbar: true 4 | 5 | framework: 6 | profiler: 7 | collect_serializer_data: true 8 | 9 | when@test: 10 | framework: 11 | profiler: { collect: false } 12 | -------------------------------------------------------------------------------- /config/packages/workflow.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | workflows: null 3 | -------------------------------------------------------------------------------- /config/preload.php: -------------------------------------------------------------------------------- 1 | where(Expr)`. 11 | `filter = [field => value, field => value, field => ['operator' => '!=', 'operand' => value], …]` 12 | when value is not an array, operator is assumed to be '=' 13 | 14 | This is used in `\Zikula\UsersBundle\Repository\UserRepository` as one example. 15 | -------------------------------------------------------------------------------- /docs/Development/Misc/CacheClearer.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: dev-misc 3 | --- 4 | # Cache clearer 5 | 6 | The cache clearer is implemented by the `\Zikula\Bundle\CoreBundle\CacheClearer` class and intended to be used 7 | for clearing (parts of) the Symfony cache. The cache clearer provides one method: `clear($type)`. The `$type` 8 | argument determines what part of the cache shall be deleted. The following types are supported: 9 | 10 | 1. `symfony` 11 | - `symfony.routing.generator`: Deletes the url generator files. 12 | - `symfony.routing.matcher`: Deletes the url matcher files. 13 | - `symfony.routing.fosjs`: Deletes the cache files for route generation in javascript (using the FOSJsRoutingBundle) 14 | - `symfony.config`: Deletes the container configuration cache files. 15 | - `symfony.annotations` 16 | - `symfony.translations` 17 | 2. `twig` 18 | 3. `purifier` 19 | 4. `assets` 20 | 21 | **Note:** The service keys are "namespaced", meaning you can also specify `symfony.routing` to delete the url `generator` 22 | AND `matcher` files. Or, specifying simply `symfony` clears *all* symfony caches. 23 | 24 | Usage example: 25 | 26 | ```php 27 | $cacheClearer->clear('symfony.config'); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/Development/Misc/LocaleApi.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: localisation 3 | --- 4 | # LocaleApi 5 | 6 | Interface: `\Zikula\Bundle\CoreBundle\Api\ApiInterface\LocaleApiInterface`. 7 | Class: `\Zikula\Bundle\CoreBundle\Api\LocaleApi`. 8 | 9 | This class defines the locales that are supported based on the translations available in `/translations`. 10 | 11 | The class makes the following methods available: 12 | 13 | ```php 14 | /** 15 | * Whether the site is multilingual or not. 16 | */ 17 | public function multilingual(): bool; 18 | 19 | /** 20 | * Get array of supported locales. 21 | */ 22 | public function getSupportedLocales($includeRegions = true): array; 23 | 24 | /** 25 | * Get array of supported locales with their translated name. 26 | */ 27 | public function getSupportedLocaleNames(string $region = null, string $displayLocale = null, $includeRegions = true): array; 28 | ``` 29 | 30 | The class is fully tested. 31 | -------------------------------------------------------------------------------- /docs/Development/Misc/Performance.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: dev-general 3 | --- 4 | # Performance optimisation 5 | 6 | 1. [Introduction](#introduction) 7 | 2. [Use DQL Joins](#use-dql-joins) 8 | 3. [Use the Twig service](#use-the-twig-service) 9 | 4. [Use namespace notation for templates](#use-namespace-notation-for-templates) 10 | 11 | ## Introduction 12 | 13 | This document collects some developer hints for improving performance of your code. 14 | 15 | ## Use DQL Joins 16 | 17 | Doctrine fetches related items lazily by default. While this saves performance in cases you do not need them, 18 | this behaviour becomes worse if you access a few relationships though. The reason is that several single queries 19 | are slower than one combined query. 20 | 21 | So if you know that you need access to some relationships add corresponding DQL joins to your query builder. 22 | Read more about this [here](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/dql-doctrine-query-language.html#joins). 23 | 24 | ## Use the Twig service 25 | 26 | Since Zikula always uses Twig templates you should use the `twig` service instead of the `templating` abstraction. 27 | The latter is just overhead we do not need. 28 | Read more about this [here](https://symfony.com/blog/new-in-symfony-2-7-twig-as-a-first-class-citizen). 29 | 30 | ## Use namespace notation for templates 31 | 32 | You must always use namespaced pathes for your templates which is faster than the normal notation because Twig 33 | does not need to convert it when resolving/reading the template file. 34 | 35 | So for example use `@AcmeFooModule/Person/index.html.twig` instead of `AcmeFooModule:Person:index.html.twig`. 36 | -------------------------------------------------------------------------------- /docs/Development/Misc/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: dev-misc 3 | --- 4 | # Misc 5 | 6 | ## Specific services 7 | 8 | - [LocaleApi](LocaleApi.md) 9 | - [Cache clearer](CacheClearer.md) 10 | - [Workflows](Workflows.md) 11 | 12 | ## Specific topics 13 | 14 | - [Performance optimisation](Performance.md) 15 | -------------------------------------------------------------------------------- /docs/Development/Misc/Workflows.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: workflows 3 | --- 4 | # Workflows 5 | 6 | Zikula utilises the Symfony Workflow component to provide workflow functionality. 7 | 8 | You can read more about it in [the manual](https://symfony.com/doc/current/components/workflow.html). 9 | 10 | ## Workflow events 11 | 12 | Please see the [Symfony docs](https://symfony.com/doc/current/workflow/usage.html#using-events) for a list of existing workflow events. 13 | 14 | ## Custom functionality 15 | 16 | There are some slight differences regarding workflow behaviour in Zikula. 17 | 18 | ### Workflow locations 19 | 20 | It seems that usually workflow definitions can only be stored at a central location. We wanted to make this more flexible so we allowed three different levels: 21 | 22 | 1. Central workflows in the core system are placed in: `/src/Zikula/Bundle/CoreBundle/Resources/workflows/` 23 | 2. Modules can define their own workflows in: `/src/extensions/Acme/MyBundle/Resources/workflows/` 24 | 3. Also it is possible to define custom workflows (or override existing ones) in: `/config/workflows/` 25 | 26 | Each of these directories may contain several YML (`*.yaml`) or XML (`*.xml`) files. 27 | 28 | **Caution:** when overriding existing workflows in `/config/workflows/someFile.yaml` (or `someFile.xml`) ensure that these workflows get new, unique names. Otherwise transitions will be added to the original workflow instead of redefining a custom workflow. 29 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Forms/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: forms 3 | --- 4 | # Forms 5 | 6 | ## Zikula additions 7 | 8 | - [Form helpers](FormHelpers.md) 9 | 10 | ## External resources 11 | 12 | - [Symfony Forms docs](https://symfony.com/doc/current/forms.html) 13 | 14 | ## For developers 15 | 16 | - [Dynamic Form Bundle](https://github.com/zikula/DynamicFormBundle) 17 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/DebuggingTwig.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Debugging Twig templates 5 | 6 | If you need help working with Twig you can install [twig-inspector](https://github.com/oroinc/twig-inspector) which is a nice and powerful tool for inspecting and debugging Twig templates. 7 | 8 | Note that by default template files are opened inside your browser. If you want to be able to open them in your IDE or editor instead you need to configure this in `/config/packages/dev/framework.yaml`. 9 | For more information about the `framework.ide` setting please refer to [Symfony docs](https://symfony.com/doc/current/reference/configuration/framework.html#ide). 10 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/Filters.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Twig filters provided by Zikula Core 5 | 6 | The following twig filters are available in templates. These are in addition to the standard functions provided 7 | by the Twig package itself. See [Twig documentation](https://twig.symfony.com) for more information. 8 | Also see [standard Symfony functions](https://symfony.com/doc/current/reference/twig_reference.html) for additional 9 | functions, filters, tags, tests and global variables. 10 | 11 | ## Filters 12 | 13 | - profileLinkByUserId 14 | - profileLinkByUserName 15 | - protectMail 16 | - urldecode 17 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/Functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Twig functions provided by Zikula Core 5 | 6 | The following twig functions are available in templates. These are in addition to the standard functions provided 7 | by the Twig package itself. See [Twig documentation](https://twig.symfony.com) for more information. 8 | Also see [standard Symfony functions](https://symfony.com/doc/current/reference/twig_reference.html) for additional 9 | functions, filters, tags, tests and global variables. 10 | 11 | ## Functions 12 | 13 | ### Themes and Site data 14 | 15 | - localeSwitcher() 16 | - siteDefinition() 17 | - siteName() 18 | - siteSlogan() 19 | - siteBranding() 20 | - siteImagePath() 21 | 22 | ### Users 23 | 24 | #### Profiles 25 | 26 | - userAvatar($uid = 0, array $parameters = []) 27 | - profileLinkByUserId($userId, $class = '', $image = '', $maxLength = 0, $title = '') (filter) 28 | - profileLinkByUserName($userName, $class = '', $image = '', $maxLength = 0, $title = '') (filter) 29 | 30 | ### Permissions 31 | 32 | - hasPermission(component, instance, level) 33 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/Imagine.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Image manipulation with Imagine 5 | 6 | Imagine is implemented in Zikula Core by the installation and pre-configuration of the [LiipImagineBundle](https://github.com/liip/LiipImagineBundle). 7 | 8 | Configuration is located at `/config/packages/imagine.yaml` 9 | 10 | In order for the developer to create their own filter(s), one must edit this config file directly. 11 | 12 | Once this is done, use the provided Twig filter to create the images you require. 13 | 14 | ```twig 15 | 16 | 17 | ``` 18 | 19 | Zikula Core provides a default cache resolver. By default images are cached to `/public/imagine/cache/`. 20 | 21 | Zikula Core provides a `zikula_root` loader if it is required to load images from locations other than `/public/`. 22 | 23 | Use this loader to locate images from the `/public/uploads` directory: 24 | 25 | ```yaml 26 | # /config/packages/imagine.yaml 27 | filter_sets: 28 | my_uploads_filter: 29 | data_loader: zikula_root 30 | jpeg_quality: 75 31 | filters: 32 | thumbnail: { size: [100, 100], mode: inset } 33 | ``` 34 | 35 | ```twig 36 | # my template 37 | 38 | ``` 39 | 40 | ## External resources 41 | 42 | - [Imagine docs](https://imagine.readthedocs.io/en/stable/) 43 | - [LiipImagineBundle docs](https://symfony.com/doc/current/bundles/LiipImagineBundle/index.html) 44 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Templating 5 | 6 | Zikula uses the Twig template engine, like Symfony does. 7 | 8 | ## Basic topics 9 | 10 | ### General information about template and asset handling 11 | 12 | - [Locations of Templates and Assets](TemplateAndAssetLocations.md) 13 | - [Site definition](SiteDefinition.md) 14 | 15 | ### Twig extensions 16 | 17 | - [Twig functions provided by Zikula Core](Functions.md) 18 | - [Twig filters provided by Zikula Core](Filters.md) 19 | - [Twig tags provided by Zikula Core](Tags.md) 20 | 21 | ### Additional topics 22 | 23 | - [Debugging Twig templates](DebuggingTwig.md) 24 | - [Image manipulation with Imagine](Imagine.md) 25 | 26 | ## External resources 27 | 28 | - [Twig docs](https://twig.symfony.com/doc/3.x/) 29 | - [Twig extensions provided by Twig](https://twig.symfony.com/doc/3.x/#reference) 30 | - [Twig extensions provided by Symfony](https://symfony.com/doc/current/reference/twig_reference.html) 31 | - [Bootstrap 5](https://getbootstrap.com/) 32 | - [Font Awesome 6](https://fontawesome.com/) 33 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/SiteDefinition.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: main-settings 3 | --- 4 | # Site definition 5 | 6 | The Core bundle provides a site definition which can be used for adding additional logic for computing site titles, site meta descriptions as well as logos and icon files. 7 | 8 | The basic interface for this is defined in `\Zikula\Bundle\CoreBundle\Site\SiteDefinitionInterface` as follows: 9 | 10 | ```php 11 | interface SiteDefinitionInterface 12 | { 13 | public function getName(): string; 14 | 15 | public function getSlogan(): string; 16 | 17 | public function getPageTitle(): string; 18 | 19 | public function getMetaDescription(): string; 20 | 21 | public function getLogoPath(): ?string; 22 | 23 | public function getMobileLogoPath(): ?string; 24 | 25 | public function getIconPath(): ?string; 26 | 27 | public function getStartController(): ?array; 28 | 29 | public function getAdminMail(): ?string; 30 | } 31 | ``` 32 | 33 | ## How to add custom logic 34 | 35 | A default implementation is provided by `\Zikula\Bundle\CoreBundle\Site\SiteDefinition`. 36 | 37 | You can subclass this and tell the dependency injection system that it should use your custom subclass whenever the interface is expected. 38 | 39 | For this add something like the following to `/config/services.yaml`: 40 | 41 | ```yaml 42 | services: 43 | Zikula\Bundle\CoreBundle\Site\SiteDefinitionInterface: '@Acme\FooThemeBundle\Site\AcmeCustomSiteDefinition' 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/Tags.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Twig tags provided by Zikula Core 5 | 6 | The following Twig tags are available in templates. These are in addition to the standard tags provided 7 | by the Twig package itself. See [Twig documentation](https://twig.symfony.com) for more information. 8 | Also see [standard Symfony functions](https://symfony.com/doc/current/reference/twig_reference.html) for additional 9 | functions, filters, tags, tests and global variables. 10 | 11 | ## Switch 12 | 13 | ```twig 14 | {% switch variable %} 15 | {% case val_1 %} 16 | code for val_1 17 | (notice - here's not break) 18 | {% case val_2 %} 19 | code for val_2 20 | {% break %} 21 | {% default %} 22 | code for default case 23 | {% endswitch %} 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Templating/TemplateAndAssetLocations.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: templating 3 | --- 4 | # Templates and assets 5 | 6 | ## Template locations 7 | 8 | Templates are resolved in the following order: 9 | 10 | 1. Override on system level: `/templates/bundles/AcmeFooBundle/News/display.html.twig`. 11 | 2. Original location: `/src/extensions/Acme/FooBundle/Resources/views/News/display.html.twig`. 12 | 13 | ## Asset locations 14 | 15 | Assets like CSS, images and JavaScript files are resolved in the following order: 16 | 17 | 1. Override on system level: `/public/overrides/acmefoobundle/js/SomeScript.js`. 18 | 2. Original location: `/public/bundles/acmefoo/js/SomeScript.js`. 19 | 20 | If the asset file can not be found, it is copied from it's source location to the original public folder. 21 | For example `/src/extensions/Acme/FooBundle/Resources/public/js/SomeScript.js` will be copied to `/public/bundles/acmefoo/js/SomeScript.js`. 22 | -------------------------------------------------------------------------------- /docs/LayoutDesign/Themes/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: themes 3 | --- 4 | # Theme system 5 | 6 | The `ThemeBundle` allows for creating several themed dashboards. It brings out of the box support for an admin dashboard as well as an user dashboard, but you can define additional ones if you need to. 7 | 8 | For each dashboard you can override the base layout template which is named `@ZikulaTheme/Dashboard/layout_.html.twig`, for example `layout_admin.html.twig`, by copying it to `/templates/bundles/ZikulaThemeBundle/`. Furthermore, there are assets you can customise by copying `ZikulaThemeBundle/Resources/public/dashboard/.(css|js)` to `/public/overrides/zikulathemebundle/dashboard/.(css|js)`. 9 | 10 | ## Additional topics and further references 11 | 12 | - [Branding](Branding.md) 13 | - [Site definition](../Templating/SiteDefinition.md) 14 | - [EasyAdminBundle: Dashboards](https://symfony.com/bundles/EasyAdminBundle/current/dashboards.html) 15 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: home 3 | --- 4 | # Zikula Core - Application Framework 5 | 6 | Zikula Core is an Application Framework which extends Symfony 7.x and includes technologies 7 | fostering a dynamic modular development paradigm which allows for rapid application development. 8 | See the features section below for more information. 9 | 10 | Zikula also features an [MDSD](https://en.wikipedia.org/wiki/Model-driven_engineering) tool for rapid prototyping 11 | and bundle development called [ModuleStudio](https://modulestudio.de/en/) or MOST. 12 | 13 | ## Some features of Zikula Core system 14 | 15 | ### Foundation 16 | 17 | - Based on Symfony 7.x which provides stability, continuity and extensibility 18 | - Uses Doctrine for persisting data 19 | - Uses Twig as template engine 20 | - Uses Mailer component for mail handling 21 | 22 | ### Themes and templating 23 | 24 | - Uses EasyAdminBundle for lightweight layout and rapid development 25 | - Twig-based theme engine for decorating dashboards 26 | 27 | ### Users and security 28 | 29 | - Users management with roles and groups 30 | - Included add-ons 31 | - Profile module (user profile information) 32 | - Legal module (TOS, Age Check, etc) 33 | 34 | ### Administration 35 | 36 | - Multi-language & translation support 37 | - Centralized category management 38 | 39 | ### Developer gems 40 | 41 | - Centralized category assignments by entity 42 | - Several distinct APIs for feature utilization 43 | - Imagine image manipulation library integration 44 | 45 | #### ModuleStudio (MOST) 46 | 47 | - Model-Driven Software Development tool 48 | - rapid prototyping 49 | - easy customization 50 | - quick updating 51 | - Creates models describing your extensions 52 | - Generates the Symfony bundle implementation 53 | - Read more at the [project's website](https://modulestudio.de/en) 54 | -------------------------------------------------------------------------------- /docs/Setup/Production.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: install 3 | --- 4 | # Production 5 | 6 | In an ideal situation, you would test your installation of Zikula in a local (development) environment before 7 | moving the entire site into "production". This process is called _deployment_. 8 | 9 | Symfony provides documentation for this process [here](https://symfony.com/doc/current/deployment.html). 10 | 11 | Before deploying your site, you should **remove all unused Zikula extensions**. 12 | 13 | Another recommended step is to run `composer dump-autoload -a` (authoritative mode). This will allow all supported 14 | Zikula core classes to load faster. (see composer's [autoloader optimization](https://getcomposer.org/doc/articles/autoloader-optimization.md)). 15 | It will also pre-cache all annotation classes in supported classes which will also speed up loading. 16 | 17 | Beware however, as classes that are generated at runtime will not autoload and this [could cause issues](https://getcomposer.org/doc/articles/autoloader-optimization.md#trade-offs-2). 18 | -------------------------------------------------------------------------------- /docs/Setup/Requirements.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: requirements 3 | --- 4 | # Requirements 5 | 6 | - Zikula Core requires PHP >= 8.1.0. 7 | - Additional server considerations can be found on [the Symfony site](https://symfony.com/doc/current/setup.html#technical-requirements). 8 | - Zikula requires more memory than typical to install. You should set your memory limit in `php.ini` 9 | to 128 MB for the installation process. 10 | - Zikula requires that `date.timezone` be set in the `php.ini` configuration file (or `.htaccess`). 11 | - Zikula requires `AllowOverride All` and the `mod_rewrite` module (be aware the Apache 2.3.9+ has changed 12 | the default setting for `AllowOverride` to `None`). 13 | - Zikula also requires other PHP extensions and configurations. These are checked during the installation 14 | process and if there are problems, you will be notified. If you discover errors, check with your hosting 15 | provider on how to rectify these issues. Typically, they will require changing the `php.ini` file or 16 | possibly reconfiguring the PHP installation by your provider. 17 | -------------------------------------------------------------------------------- /docs/Translation/Contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Contributing translations 5 | 6 | Translations should be managed in the repository of the corresponding component. 7 | 8 | So if you would like to contribute new translations or updates for existing ones please create a pull request at: 9 | 10 | - for the Zikula Core 11 | - the appropriate repository for any extensions 12 | -------------------------------------------------------------------------------- /docs/Translation/Debugging.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Debugging translations 5 | 6 | Symfony comes with `bin/console debug:translation` command line tool to debug translations. 7 | 8 | Example output: 9 | 10 | ``` 11 | %> php bin/console debug:translation pl --domain=mydomain 12 | +----------+-------------+----------------------+ 13 | | State(s) | Id | Message Preview (pl) | 14 | +----------+-------------+----------------------+ 15 | | o | Pages | Strony | 16 | | o | Page | Strona | 17 | | o | pages | strony | 18 | | o | page | strona | 19 | | o | read more | czytaj więcej | 20 | | o | title | tytuł | 21 | | o | description | opis | 22 | +----------+-------------+----------------------+ 23 | 24 | Legend: 25 | x Missing message 26 | o Unused message 27 | = Same as the fallback message 28 | ``` 29 | 30 | For more information please check [Debugging Translations](https://symfony.com/doc/current/translation.html#debugging-translations). 31 | 32 | ## Important notes 33 | 34 | From Symfony translator documentation: 35 | 36 | > Each time you create a new translation resource (or install a bundle that includes a translation resource), be sure to 37 | clear your cache so that Symfony can discover the new translation resources. 38 | -------------------------------------------------------------------------------- /docs/Translation/Dev/TranslatorTrait.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # TranslatorTrait 5 | 6 | The trait implemented by `\Zikula\Bundle\CoreBundle\Translator\TranslatorTrait` adds the following methods to your class: 7 | 8 | - `trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string` 9 | - `getTranslator(): TranslatorInterface` 10 | - `setTranslator(TranslatorInterface $translator)` 11 | 12 | In your constructor, you are required to call the `setTranslator()` method and set the `$translator` property. 13 | Typically this will be set to the `'translator'` service. 14 | -------------------------------------------------------------------------------- /docs/Translation/Intl.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Using the PHP and Symfony's Intl classes 5 | 6 | Zikula expects PHP's [intl extension](http://www.php.net/manual/en/book.intl.php) to be installed to facilitate internationalization functions within the code. 7 | 8 | If it is installed properly in your PHP build, you can search your `phpinfo` output and you should find something like 9 | `—enable-intl` in the Configure Command and `Internationalization support => enabled` in the output. 10 | 11 | If these are NOT found, then the [Intl component](https://symfony.com/doc/current/components/intl.html) from Symfony 12 | will be used instead as a polyfill. These will enable the functions to work without error, but the functions will only work for the `en` locale. 13 | 14 | Support in enabling this PHP extension should be obtained through your web provider. This is not something Zikula can help with. 15 | 16 | Symfony's `Intl` class is used as a wrapper to access 17 | 18 | - Country Names 19 | - Currencies 20 | - Language and Script Names 21 | - Locales 22 | - Timezones 23 | 24 | For further information read [Accessing ICU Data](https://symfony.com/doc/current/components/intl.html#accessing-icu-data). 25 | -------------------------------------------------------------------------------- /docs/Translation/Javascript.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # JavaScript translation 5 | 6 | Zikula includes `symfony/ux-translator` for integrating the Symfony Translator in JavaScript. 7 | 8 | For more information see: . 9 | -------------------------------------------------------------------------------- /docs/Translation/Overriding.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Overriding translations 5 | 6 | From [Symfony docs](https://symfony.com/doc/current/bundles/override.html#translations): 7 | 8 | > Translations are not related to bundles, but to translation domains. For this reason, you can override any bundle translation file from the main `translations/` directory, as long as the new file uses the same domain. 9 | 10 | > For example, to override the translations defined in the `Resources/translations/FOSUserBundle.es.yml` file of the FOSUserBundle, create a `/translations/FOSUserBundle.es.yml` file. 11 | -------------------------------------------------------------------------------- /docs/Translation/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Translation 5 | 6 | ## Basic topics 7 | 8 | - [Translation terminology](Terminology.md) 9 | - [Translator usage](Usage.md) 10 | 11 | ## Translation extraction 12 | 13 | - [Extracting translation messages in Symfony](https://symfony.com/doc/current/translation.html#extracting-translation-contents-and-updating-catalogs-automatically) 14 | - For the core use `bin/translations.sh`. 15 | 16 | ## Specific and advanced topics 17 | 18 | - [Translation in Zikula](Translation.md) 19 | - [Javascript translation](Javascript.md) 20 | - [Debugging translations](Debugging.md) 21 | - [Using the PHP and Symfony's Intl classes](Intl.md) 22 | - [Overriding translations](Overriding.md) 23 | - [Contributing translations](Contributing.md) 24 | 25 | ## Tools and external resources 26 | 27 | Here are some recommended tools. We recommend you try them all to find your favorite tool. 28 | 29 | - [Poedit](https://poedit.net/) - Powerful Gettext translation tool, works with Windows, Mac and Linux 30 | - [Virtaal](https://virtaal.translatehouse.org/) - Another excellent translation tool 31 | - [YAML to PO converter](https://yml2po.com/) 32 | 33 | ## For developers 34 | 35 | - [TranslatorTrait](Dev/TranslatorTrait.md) 36 | -------------------------------------------------------------------------------- /docs/Translation/Terminology.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Translation terminology 5 | 6 | The technology for translations used in this guide is simple - anywhere in project we use English strings and English descriptions. 7 | These are translated to other language stored in files or database and loaded on demand instead of English strings. 8 | 9 | ## Terminology 10 | 11 | - **Symfony Translator** - Symfony gettext technology used for translations 12 | - **message** - in basic it is an translation array element; for example: 'English string' => 'Translated string' 13 | - **domain** - An optional way to organize messages into groups (e.g. `admin`, `navigation`, `validators`; default value is `messages`) 14 | - **catalogue** - Gettext way to organize messages into groups (LC_MESSAGES, LC_TYPE, LC_ALL) 15 | - **locale** - The locale that the translations are for (e.g. `en_GB`, `en`, etc); 16 | - **loader** - How Symfony/Zikula should load and parse the file (e.g. `xlf`, `php`, `yml`, `po`, `mo`, etc.). 17 | 18 | For more information please refer to [Symfony docs](https://symfony.com/doc/current/translation.html). 19 | 20 | ## Translation domains 21 | 22 | Earlier we used the bundle name as translation domain. The new translation system uses different configurations for different bundles though. You are encouraged to use multiple translation domains now. They should cover different semantical topics and act as a context for translators, like for example `mail`, `messages`, `navigation`, `validators` and `admin`). 23 | -------------------------------------------------------------------------------- /docs/Translation/Translation.md: -------------------------------------------------------------------------------- 1 | --- 2 | currentMenu: translation 3 | --- 4 | # Translation in Zikula 5 | 6 | Zikula uses the native Symfony translation system. Please refer to [Symfony docs](https://symfony.com/doc/current/translation.html) for more information about Symfony features. 7 | 8 | ## Important notes 9 | 10 | From Symfony translator documentation: 11 | 12 | > Each time you create a new translation resource (or install a bundle that includes a translation resource), be sure to 13 | clear your cache so that Symfony can discover the new translation resources. 14 | 15 | Translations are cached in `var/cache//translations/catalogue..` 16 | 17 | ### Fallback locale 18 | 19 | Let's look at a website with 3 languages: `en` (strings are in `en`), `de` and `pl`. 20 | All languages are enabled but some translations are missing for some strings. 21 | 22 | Normally it would show English as default because strings are in English. 23 | The fallback locale is a feature that reads translator 'fallback' setting from config.yaml 24 | and sets this as locale to show instead the one that is missing. 25 | So when viewing a German site in Polish language and Polish translations are not complete 26 | while the German is, it will show German translations instead. This will happen only 27 | when translator fallback setting locale is set to `de`. At the end there is always an English string. 28 | 29 | ## Further resources 30 | 31 | - [Gettext documentation](https://www.gnu.org/software/gettext/manual/gettext.html#I18n_002c-L10n_002c-and-Such) 32 | - [Symfony Translator documentation](https://symfony.com/doc/current/translation.html) 33 | - [How to Translate With GetText PO and POT Files](https://www.icanlocalize.com/site/tutorials/how-to-translate-with-gettext-po-and-pot-files/) 34 | -------------------------------------------------------------------------------- /migrations/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/migrations/.gitignore -------------------------------------------------------------------------------- /php_cs_fixer.dist.php: -------------------------------------------------------------------------------- 1 | setParallelConfig(ParallelConfigFactory::detect()) 24 | ->setRules([ 25 | '@PSR12' => true, 26 | '@PHP84Migration' => true, 27 | '@PHPUnit100Migration:risky' => true, 28 | '@Symfony' => true, 29 | '@Symfony:risky' => true, 30 | 'combine_nested_dirname' => true, 31 | 'concat_space' => ['spacing' => 'one'], 32 | 'fopen_flags' => false, 33 | 'mb_str_functions' => true, 34 | 'native_constant_invocation' => false, 35 | 'native_function_invocation' => false, 36 | 'no_short_bool_cast' => true, 37 | 'no_unreachable_default_argument_value' => false, 38 | 'nullable_type_declaration_for_default_null_value' => true, 39 | 'phpdoc_align' => ['align' => 'left'], 40 | 'phpdoc_to_param_type' => true, 41 | 'phpdoc_to_return_type' => true, 42 | 'php_unit_test_annotation' => false, // breaks "@depends App\Something::testFooBar()" 43 | 'protected_to_private' => false, 44 | 'simplified_null_return' => true, 45 | 'single_line_throw' => false, 46 | ]) 47 | ->setRiskyAllowed(true) 48 | ->setFinder( 49 | new PhpCsFixer\Finder() 50 | ->in(['src', 'tests']) 51 | ->notPath('#/Fixtures/#') 52 | ->notPath('#/vendor/#') 53 | ) 54 | ->setCacheFile('.php-cs-fixer.cache') 55 | ; 56 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 1 3 | paths: 4 | - src 5 | - tests 6 | -------------------------------------------------------------------------------- /phpunit.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./src/system/*/Tests/ 27 | 28 | 29 | 30 | 31 | 32 | src 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/public/android-chrome-256x256.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 8 | Deny from all 9 | 10 | 11 | # Apache 2.4 12 | 13 | Require all denied 14 | 15 | 16 | 17 | # Apache 2.2 18 | 19 | Order allow,deny 20 | Allow from all 21 | 22 | 23 | # Apache 2.4 24 | 25 | Require all granted 26 | 27 | 28 | -------------------------------------------------------------------------------- /renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | // all options: see https://docs.renovatebot.com/configuration-options/ 3 | $schema: 'https://docs.renovatebot.com/renovate-schema.json', 4 | // configuration presets to use or extend 5 | extends: ['config:base', 'group:symfony', 'docker:enableMajor'], 6 | // ignore versions with unstable SemVer 7 | ignoreUnstable: true, 8 | // when is Renovate allowed to run 9 | schedule: ['at any time'], 10 | // enforce enablement of semantic commits 11 | semanticCommits: 'enabled', 12 | // separate major or minor branches if both updates exist 13 | separateMajorMinor: true, 14 | // separate minor or patch branches if both updates exist 15 | separateMinorPatch: true, 16 | // separate branches for multiple major updates 17 | separateMultipleMajor: true, 18 | // rules for matching package names 19 | // see https://docs.renovatebot.com/configuration-options/#packagerules 20 | packageRules: [ 21 | { 22 | matchManagers: ['composer'], 23 | rangeStrategy: 'update-lockfile', 24 | }, 25 | // group all docker updates together 26 | { 27 | matchManagers: ['docker-compose', 'dockerfile'], 28 | groupName: 'docker', 29 | }, 30 | // group other updates with patch level 31 | { 32 | matchManagers: ['composer'], 33 | matchUpdateTypes: ['patch'], 34 | groupName: 'composer (patch)', 35 | }, 36 | { 37 | matchManagers: ['npm'], 38 | matchUpdateTypes: ['patch'], 39 | groupName: 'npm (patch)', 40 | }, 41 | { 42 | matchPackagePatterns: ['^doctrine'], 43 | groupName: 'doctrine', 44 | }, 45 | ], 46 | // required for Symfony Flex integration 47 | // see https://github.com/renovatebot/renovate/pull/11990 48 | allowPlugins: true, 49 | ignorePlugins: false, 50 | } 51 | -------------------------------------------------------------------------------- /src/Kernel.php: -------------------------------------------------------------------------------- 1 | =8.2", 17 | 18 | "symfony/config": "^7.2", 19 | "symfony/console": "^7.2", 20 | "symfony/finder": "^7.2", 21 | "symfony/framework-bundle": "^7.2", 22 | "symfony/security-bundle": "^7.2", 23 | "symfony/string": "^7.2", 24 | "symfony/validator": "^7.2", 25 | "symfony/workflow": "^7.2", 26 | "symfony/yaml": "^7.2", 27 | 28 | "symfony/browser-kit": "^7.2", 29 | "symfony/debug-bundle": "^7.2", 30 | "symfony/doctrine-bridge": "^7.2", 31 | "symfony/expression-language": "^7.2", 32 | "symfony/lock": "^7.2", 33 | "symfony/monolog-bundle": "^3", 34 | "symfony/polyfill-uuid": "^1", 35 | "symfony/polyfill-intl-messageformatter": "^1", 36 | "symfony/runtime": "^7.2", 37 | "symfony/stopwatch": "^7.2", 38 | "symfony/uid": "^7.2", 39 | "symfony/web-link": "^7.2", 40 | "symfony/web-profiler-bundle": "^7.2", 41 | 42 | "doctrine/doctrine-bundle": "^2", 43 | "doctrine/doctrine-migrations-bundle": "^3.3", 44 | "doctrine/orm": "^3", 45 | "stof/doctrine-extensions-bundle": "^1", 46 | "liip/imagine-bundle": "^2", 47 | 48 | "symfony/ux-translator": "^2", 49 | "friendsofsymfony/jsrouting-bundle": "^3" 50 | }, 51 | "autoload": { 52 | "psr-4": { "Zikula\\CoreBundle\\": "src" } 53 | }, 54 | "autoload-dev": { 55 | "psr-4": { "Zikula\\CoreBundle\\Tests\\": "tests" } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/system/CoreBundle/config/services.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | _defaults: 3 | autowire: true 4 | autoconfigure: true 5 | public: false 6 | 7 | # alias interface to doctrine service 8 | Doctrine\Persistence\ManagerRegistry: '@doctrine' 9 | 10 | Zikula\CoreBundle\: 11 | resource: '../src/*' 12 | 13 | Zikula\CoreBundle\Api\ApiInterface\LocaleApiInterface: '@Zikula\CoreBundle\Api\LocaleApi' 14 | 15 | Zikula\CoreBundle\EventSubscriber\ClickjackProtectionSubscriber: 16 | arguments: 17 | $xFrameOptions: 'SAMEORIGIN' 18 | 19 | Symfony\Component\HttpKernel\Fragment\FragmentHandler: '@fragment.handler' 20 | -------------------------------------------------------------------------------- /src/system/CoreBundle/phpunit.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./Tests/ 27 | 28 | 29 | 30 | 31 | 32 | . 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/admin.png -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/ajax/zktimer_48px_black.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/ajax/zktimer_48px_black.gif -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/ajax/zktimer_48px_black_rounded.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/ajax/zktimer_48px_black_rounded.gif -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/ajax/zktimer_48px_white.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/ajax/zktimer_48px_white.gif -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/ajax/zktimer_48px_white_rounded.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/ajax/zktimer_48px_white_rounded.gif -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/icon.png -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/logo.gif -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/logo_small.png -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/logo_with_title.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/logo_with_title.gif -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/logo_with_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/logo_with_title.png -------------------------------------------------------------------------------- /src/system/CoreBundle/public/images/zk-power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/CoreBundle/public/images/zk-power.png -------------------------------------------------------------------------------- /src/system/CoreBundle/public/js/paginator.js: -------------------------------------------------------------------------------- 1 | // Copyright Zikula, licensed MIT. 2 | 3 | (function($) { 4 | var paginationLinks = []; 5 | var pagers = null; 6 | function bootstrapifyPager(pager) { 7 | if (null === pager) { 8 | return; 9 | } 10 | pager.find('li').addClass('page-item'); 11 | pager.find('li > span').addClass('page-link'); 12 | pager.find('li > a').each(function (index) { 13 | var pageNumber = $(this).attr('href'); 14 | $(this).attr('href', paginationLinks[pageNumber]); 15 | }); 16 | }; 17 | $(document).ready(function() { 18 | pagers = $('.pagination'); 19 | pagers.each(function (index) { 20 | var pager = $(this); 21 | pager.addClass('d-none'); 22 | pager.find('li > a').each(function (index) { 23 | var pageNumber = $(this).data('page'); 24 | if (pageNumber) { 25 | paginationLinks[pageNumber] = $(this).attr('href'); 26 | } 27 | }); 28 | pager.pagination({ 29 | pages: pager.data('pages'), 30 | currentPage: pager.data('currentpage'), 31 | hrefTextPrefix: '', 32 | prevText: '', 33 | nextText: '', 34 | onPageClick: function (pageNumber, event) { 35 | bootstrapifyPager(pager); 36 | if (paginationLinks[pageNumber]) { 37 | document.location = paginationLinks[pageNumber]; 38 | 39 | return; 40 | } 41 | }, 42 | onInit: function () { 43 | bootstrapifyPager(pager); 44 | pager.removeClass('d-none'); 45 | } 46 | }); 47 | }); 48 | }); 49 | })(jQuery); 50 | -------------------------------------------------------------------------------- /src/system/CoreBundle/public/js/simplePagination.js/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2012, Flavius Matis 2 | http://flaviusmatis.github.com/ 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/system/CoreBundle/public/js/simplePagination.js/README.md: -------------------------------------------------------------------------------- 1 | A simple jQuery pagination plugin and 3 CSS themes. 2 | 3 | [Read Full Documentation](https://flaviusmatis.github.io/simplePagination.js/) 4 | -------------------------------------------------------------------------------- /src/system/CoreBundle/public/js/simplePagination.js/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simplePagination.js", 3 | "version": "0.0.3", 4 | "homepage": "https://github.com/flaviusmatis/simplePagination.js", 5 | "authors": [ 6 | "Flavius Matis " 7 | ], 8 | "description": "A simple jQuery pagination plugin with 3 CSS themes.", 9 | "main": "jquery.simplePagination.js", 10 | "keywords": [ 11 | "jquery", 12 | "pagination" 13 | ], 14 | "license": "MIT", 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/system/CoreBundle/src/Api/ApiInterface/LocaleApiInterface.php: -------------------------------------------------------------------------------- 1 | setTimezone(self::getUtc()); 31 | } 32 | 33 | return parent::convertToDatabaseValue($value, $platform); 34 | } 35 | 36 | public function convertToPHPValue($value, AbstractPlatform $platform): ?\DateTime 37 | { 38 | if (null === $value || $value instanceof \DateTimeInterface) { 39 | return $value; 40 | } 41 | 42 | $converted = \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value, self::getUtc()); 43 | if (!$converted) { 44 | throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString()); 45 | } 46 | 47 | return $converted; 48 | } 49 | 50 | private static function getUtc(): \DateTimeZone 51 | { 52 | return self::$utc ??= new \DateTimeZone('UTC'); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/system/CoreBundle/src/EventSubscriber/ClickjackProtectionSubscriber.php: -------------------------------------------------------------------------------- 1 | ['onKernelResponse', -99], 35 | ]; 36 | } 37 | 38 | /** 39 | * Sets x-origin headers in the response object. 40 | */ 41 | public function onKernelResponse(ResponseEvent $event): void 42 | { 43 | if (!$event->isMainRequest()) { 44 | return; 45 | } 46 | 47 | $response = $event->getResponse(); 48 | 49 | $response->headers->set('X-Frame-Options', $this->xFrameOptions); 50 | $response->headers->set('X-XSS-Protection', '1'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/system/CoreBundle/src/Response/PlainResponse.php: -------------------------------------------------------------------------------- 1 | getTranslator()->trans($id, $parameters, $domain, $locale); 25 | } 26 | 27 | public function getTranslator(): TranslatorInterface 28 | { 29 | if (null === $this->translator) { 30 | throw new \ErrorException('Translator must be set in __TRAIT__ before it can be used.'); 31 | } 32 | 33 | return $this->translator; 34 | } 35 | 36 | public function setTranslator(TranslatorInterface $translator) 37 | { 38 | $this->translator = $translator; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/system/CoreBundle/src/Twig/Extension/CoreExtension.php: -------------------------------------------------------------------------------- 1 | ['html']]), 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/system/CoreBundle/src/Twig/Runtime/CoreRuntime.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% trans %}The site is currently off-line.{% endtrans %} 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

{% trans %}The site is currently off-line.{% endtrans %}

14 | {% if reason %} 15 |

{{ reason }}

16 | {% endif %} 17 |

18 | {% trans %}Administrator log-in{% endtrans %} 19 |

20 |

21 | {% trans %}Proudly powered by Zikula{% endtrans %} 22 |

23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/bar.de.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: de\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/foo.de.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: de\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/messages.de.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: de\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/messages.de_DE.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: de\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/messages.en.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: en\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/messages.ru.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: ru\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/messages.template.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: en\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/tests/Api/Fixtures/translations/sub/messages.it.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Content-Transfer-Encoding: 8bit\n" 5 | "Language: it\n" 6 | 7 | msgid "foo" 8 | msgstr "foo" 9 | -------------------------------------------------------------------------------- /src/system/CoreBundle/workflows/README: -------------------------------------------------------------------------------- 1 | This file is a placeholder 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/.gitattributes: -------------------------------------------------------------------------------- 1 | /Tests export-ignore 2 | /phpunit.xml.dist export-ignore 3 | /.gitignore export-ignore 4 | -------------------------------------------------------------------------------- /src/system/LegalBundle/README.md: -------------------------------------------------------------------------------- 1 | # LegalBundle 2 | 3 | This is a read-only repository. 4 | 5 | This bundle provides a site with the ability to manage and display legal information such as terms of use 6 | and privacy policies. It also allows the site to require that these policies be accepted during registration 7 | and/or log-in. 8 | 9 | This bundle also supports a simplistic age verification during registration. 10 | 11 | ### Supported Policies, statements, and registration requirements 12 | 13 | * Legal Notice 14 | * User acceptance is not required. 15 | * Privacy 16 | * User acceptance is required during registration, if active. 17 | * User acceptance is required during log-in, if active and not accepted during registration. 18 | * Terms of use 19 | * User acceptance is required during registration, if active. 20 | * User acceptance is required during log-in, if active and not accepted during registration. 21 | * Trade Conditions 22 | * User acceptance is required during registration, if active. 23 | * User acceptance is required during log-in, if active and not accepted during registration. 24 | * Cancellation Rights Policy 25 | * User acceptance is required during registration, if active. 26 | * User acceptance is required during log-in, if active and not accepted during registration. 27 | * Accessibility Statement 28 | * User acceptance is not required. 29 | * Age check 30 | * Check performed during registration, if active. 31 | -------------------------------------------------------------------------------- /src/system/LegalBundle/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zikula/legal-bundle", 3 | "version": "dev-4.0", 4 | "description": "Provides an interface for managing the site's legal documents.", 5 | "type": "symfony-bundle", 6 | "license": "LGPL-3.0+", 7 | "authors": [ 8 | { 9 | "name": "Zikula Development Team", 10 | "homepage": "https://ziku.la" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=8.2" 15 | }, 16 | "autoload": { 17 | "psr-4": { "Zikula\\LegalBundle\\": "" } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/system/LegalBundle/config/routing.yaml: -------------------------------------------------------------------------------- 1 | zikulalegalbundle: 2 | resource: '@ZikulaLegalBundle/src/Controller' # TODO src is a workaround for https://github.com/symfony/symfony/issues/46482 3 | type: attribute 4 | -------------------------------------------------------------------------------- /src/system/LegalBundle/config/services.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | _defaults: 3 | autowire: true 4 | autoconfigure: true 5 | public: false 6 | bind: 7 | $twigLoader: '@twig.loader' 8 | 9 | Zikula\LegalBundle\: 10 | resource: '../src/*' 11 | 12 | Zikula\LegalBundle\Bundle\MetaData\LegalBundleMetaData: 13 | public: true 14 | 15 | Zikula\LegalBundle\Helper\: 16 | resource: '../src/Helper/*' 17 | lazy: true 18 | -------------------------------------------------------------------------------- /src/system/LegalBundle/phpunit.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./Tests/ 27 | 28 | 29 | 30 | 31 | 32 | . 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/system/LegalBundle/public/js/ZikulaLegalBundle.User.AcceptPolicies.js: -------------------------------------------------------------------------------- 1 | // Copyright Zikula, licensed MIT. 2 | 3 | document.addEventListener('DOMContentLoaded', function () { 4 | const policyLinks = document.querySelectorAll('.policy-link'); 5 | const modalTitle = document.querySelector('#policyModalTitle'); 6 | const modalBody = document.querySelector('#policyModalBody'); 7 | const modalElem = document.querySelector('#policyModal'); 8 | const modal = new bootstrap.Modal('#policyModal', {}); 9 | 10 | policyLinks.forEach(function (link) { 11 | link.addEventListener('click', function (event) { 12 | event.preventDefault(); 13 | modalTitle.textContent = this.textContent; 14 | const href = this.getAttribute('href') + '?raw=1'; 15 | fetch(href) 16 | .then(function (response) { 17 | return response.text(); 18 | }) 19 | .then(function (data) { 20 | modalBody.innerHTML = data; 21 | modal.show(); 22 | }) 23 | .catch(function (error) { 24 | console.error('Error:', error); 25 | }); 26 | }); 27 | }); 28 | 29 | modalElem.addEventListener('hidden.bs.modal', event => { 30 | modalBody.innerHTML = ''; 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /src/system/LegalBundle/src/Bundle/MetaData/LegalBundleMetaData.php: -------------------------------------------------------------------------------- 1 | add('userId', HiddenType::class, ['mapped' => false]) 30 | ->add('loginRequired', HiddenType::class, ['mapped' => false]) 31 | ->add('submit', SubmitType::class, [ 32 | 'label' => $loginRequired ? 'Save and continue logging in' : 'Save', 33 | 'icon' => 'fa-check', 34 | 'attr' => ['class' => 'btn-success'], 35 | ]) 36 | ; 37 | } 38 | 39 | public function configureOptions(OptionsResolver $resolver): void 40 | { 41 | $resolver->setDefaults(['userId' => '', 'loginRequired' => false]) 42 | ->setAllowedTypes('userId', 'int') 43 | ->setAllowedTypes('loginRequired', 'bool'); 44 | } 45 | 46 | public function getBlockPrefix(): string 47 | { 48 | return 'zikulalegalbundle_policy'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/system/LegalBundle/src/Helper/AcceptPoliciesHelper.php: -------------------------------------------------------------------------------- 1 | legalConfig['policies']; 33 | 34 | return [ 35 | 'privacyPolicy' => $policies['privacy_policy']['enabled'], 36 | 'termsOfUse' => $policies['terms_of_use']['enabled'], 37 | 'tradeConditions' => $policies['trade_conditions']['enabled'], 38 | 'cancellationRightPolicy' => $policies['cancellation_right_policy']['enabled'], 39 | 'agePolicy' => 0 !== $this->legalConfig['minimum_age'], 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/system/LegalBundle/src/ZikulaLegalBundle.php: -------------------------------------------------------------------------------- 1 | container->get(LegalBundleMetaData::class); 33 | } 34 | 35 | public function configure(DefinitionConfigurator $definition): void 36 | { 37 | $definition->import('../config/definition.php'); 38 | } 39 | 40 | public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void 41 | { 42 | $container->import('../config/services.yaml'); 43 | 44 | // configure services 45 | $services = $container->services(); 46 | 47 | $services->get(UserController::class) 48 | ->arg('$legalConfig', $config); 49 | 50 | $services->get(AcceptPoliciesHelper::class) 51 | ->arg('$legalConfig', $config); 52 | 53 | $services->get(ExtensionMenu::class) 54 | ->arg('$legalConfig', $config); 55 | 56 | $services->get(TwigExtension::class) 57 | ->arg('$legalConfig', $config); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/PolicyContent/en/cancellationRightPolicy.html.twig: -------------------------------------------------------------------------------- 1 |

{{ 'Enter your text by overriding the %s% template file.'|trans({ '%s%': 'system/LegalBundle/Resources/views/en/cancellationRightPolicy.html.twig' })|raw }}

2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/PolicyContent/en/legalNotice.html.twig: -------------------------------------------------------------------------------- 1 |

{{ 'Enter your text by overriding the %s% template file.'|trans({ '%s%': 'system/LegalBundle/Resources/views/en/legalNotice.html.twig' })|raw }}

2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/PolicyContent/en/tradeConditions.html.twig: -------------------------------------------------------------------------------- 1 |

{{ 'Enter your text by overriding the %s% template file.'|trans({ '%s%': 'system/LegalBundle/Resources/views/en/tradeConditions.html.twig' })|raw }}

2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/accessibilityStatement.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Accessibility statement for %s%'|trans({ '%s%': siteName() }) %} 4 | {% block policy_content %} 5 | {{ include('@ZikulaLegal/PolicyContent/' ~ app.locale ~ '/accessibilityStatement.html.twig') }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/cancellationRightPolicy.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Cancellation right policy for %s%'|trans({ '%s%': siteName() }) %} 4 | {% block policy_content %} 5 | {{ include('@ZikulaLegal/PolicyContent/' ~ app.locale ~ '/cancellationRightPolicy.html.twig') }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/legalNotice.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Legal notice for %s%'|trans({ '%s%': siteName() }) %} 4 | {% block policy_content %} 5 | {{ include('@ZikulaLegal/PolicyContent/' ~ app.locale ~ '/legalNotice.html.twig') }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/policyNotActive.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Policy not available'|trans %} 4 | {% block policy_content %} 5 |

{% trans %}The selected policy is not available.{% endtrans %}

6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/privacyPolicy.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Privacy policy for %s%'|trans({ '%s%': siteName() }) %} 4 | {% block policy_content %} 5 | {{ include('@ZikulaLegal/PolicyContent/' ~ app.locale ~ '/privacyPolicy.html.twig') }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/template.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block wrapper_wrapper %} 4 | {% if app.request.query.getBoolean('raw') %} 5 | {# for modal display #} 6 | {{ block('policy_content') }} 7 | {% else %} 8 | {{ parent() }} 9 | {% endif %} 10 | {% endblock %} 11 | 12 | {# for normal display #} 13 | {% block main %} 14 | {{ block('policy_content') }} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/termsOfUse.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Terms of use for %s%'|trans({ '%s%': siteName() }) %} 4 | {% block policy_content %} 5 | {{ include('@ZikulaLegal/PolicyContent/' ~ app.locale ~ '/termsOfUse.html.twig') }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/Display/tradeConditions.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@ZikulaLegal/User/Policy/Display/template.html.twig' %} 2 | 3 | {% block page_title 'Trade conditions for %s%'|trans({ '%s%': siteName() }) %} 4 | {% block policy_content %} 5 | {{ include('@ZikulaLegal/PolicyContent/' ~ app.locale ~ '/tradeConditions.html.twig') }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/accessibilityStatement.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}Accessibility statement{% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/cancellationRightPolicy.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}Cancellation right policy{% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/legalNotice.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}Legal notice{% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/notFound.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}(POLICY NOT FOUND!){% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/privacyPolicy.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}Privacy policy{% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/termsOfUse.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}Terms of use{% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/Policy/InlineLink/tradeConditions.html.twig: -------------------------------------------------------------------------------- 1 | {% trans %}General terms and conditions of trade{% endtrans %} 2 | -------------------------------------------------------------------------------- /src/system/LegalBundle/templates/User/acceptPolicies.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block page_title 'Site policies'|trans %} 4 | {% block main %} 5 | {% if loginRequired %} 6 |
7 | {% trans %}In order to log in you must accept this site's policies. If you have accepted the site's policies in the past, then they have been updated and we ask that you review the changes.{% endtrans %} 8 |
9 | {% trans %}If you leave this page without successfully accepting the policies, then you will not be logged in.{% endtrans %} 10 |
11 | {% endif %} 12 | 13 | 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/.gitattributes: -------------------------------------------------------------------------------- 1 | /Tests export-ignore 2 | /phpunit.xml.dist export-ignore 3 | /.gitignore export-ignore 4 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/README.md: -------------------------------------------------------------------------------- 1 | # ThemeBundle 2 | 3 | This is a read-only repository. 4 | 5 | ## Resources 6 | 7 | * [Report issues](https://github.com/zikula/core/issues) and 8 | [send Pull Requests](https://github.com/zikula/core/pulls) 9 | in the [main Zikula repository](https://github.com/zikula/core) 10 | * For more information visit [ziku.la](https://ziku.la/). 11 | * Please see our [documentation](https://docs.ziku.la). 12 | 13 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zikula/theme-bundle", 3 | "version": "dev-4.0", 4 | "description": "Theme system and admin extensions", 5 | "type": "symfony-bundle", 6 | "license": "LGPL-3.0-or-later", 7 | "authors": [ 8 | { 9 | "name": "Zikula", 10 | "homepage": "https://ziku.la/" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=8.2", 15 | "easycorp/easyadmin-bundle": "^4.12", 16 | "symfony/config": "^7.2", 17 | "symfony/dependency-injection": "^7.2", 18 | "symfony/event-dispatcher": "^7.2", 19 | "symfony/filesystem": "^7.2", 20 | "symfony/form": "^7.2", 21 | "symfony/http-foundation": "^7.2", 22 | "symfony/http-kernel": "^7.2", 23 | "symfony/routing": "^7.2", 24 | "symfony/string": "^7.2", 25 | "symfony/twig-bundle": "^7.2", 26 | "symfony/validator": "^7.2", 27 | "symfony/webpack-encore-bundle": "^2", 28 | "symfony/yaml": "^7.2", 29 | "twig/intl-extra": "^3", 30 | "twig/string-extra": "^3", 31 | "twig/extra-bundle": "^3", 32 | 33 | "zikula/core-bundle": "dev-4.0", 34 | 35 | "components/jquery": "^3", 36 | "vakata/jstree": "^3" 37 | }, 38 | "autoload": { 39 | "psr-4": { "Zikula\\ThemeBundle\\": "src" } 40 | }, 41 | "autoload-dev": { 42 | "psr-4": { "Zikula\\ThemeBundle\\Tests\\": "tests" } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/config/routing.yaml: -------------------------------------------------------------------------------- 1 | zikulathemebundle: 2 | resource: '@ZikulaThemeBundle/src/Controller' # TODO src is a workaround for https://github.com/symfony/symfony/issues/46482 3 | type: attribute 4 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/config/services.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | _defaults: 3 | autowire: true 4 | autoconfigure: true 5 | public: false 6 | 7 | Zikula\ThemeBundle\: 8 | resource: '../src/*' 9 | 10 | Zikula\ThemeBundle\Bundle\MetaData\ThemeBundleMetaData: 11 | public: true 12 | 13 | Zikula\ThemeBundle\Helper\: 14 | resource: '../src/Helper/*' 15 | lazy: true 16 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/phpunit.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./Tests/ 27 | 28 | 29 | 30 | 31 | 32 | . 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/css/ZikulaThemeBundle.IconPicker.css: -------------------------------------------------------------------------------- 1 | /* temporary fix for making BS3 component work with BS4 - see https://github.com/itsjavi/fontawesome-iconpicker/issues/65 */ 2 | .fade.in { 3 | opacity: 1; 4 | } 5 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/css/jstree.Common.css: -------------------------------------------------------------------------------- 1 | .jstree-contextmenu { 2 | z-index: 100; 3 | } 4 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/css/phpinfo.css: -------------------------------------------------------------------------------- 1 | 2 | #phpinfo table { 3 | table-layout: fixed; 4 | } 5 | #phpinfo table td { 6 | word-wrap: break-word; 7 | } 8 | #phpinfo td.e { 9 | font-weight: 700; 10 | } 11 | #phpinfo a > img { 12 | float: left; 13 | margin-right: 20px; 14 | } 15 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/dashboard/admin.css: -------------------------------------------------------------------------------- 1 | aside.sidebar > p:first-child { 2 | color: green; 3 | } 4 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/dashboard/admin.js: -------------------------------------------------------------------------------- 1 | // to be used for overrides 2 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/dashboard/user.css: -------------------------------------------------------------------------------- 1 | aside.sidebar > p:first-child { 2 | color: blue; 3 | } 4 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/dashboard/user.js: -------------------------------------------------------------------------------- 1 | // to be used for overrides 2 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/images/preview_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/ThemeBundle/public/images/preview_large.png -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/images/preview_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/ThemeBundle/public/images/preview_medium.png -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/images/preview_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/src/system/ThemeBundle/public/images/preview_small.png -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/ZikulaThemeBundle.FilePicker.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function () { 2 | bsCustomFileInput.init(); 3 | }); 4 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/ZikulaThemeBundle.IconPicker.js: -------------------------------------------------------------------------------- 1 | function initFontAwesomeIconPicker() { 2 | jQuery('.zikula-icon-picker').iconpicker({ 3 | hideOnSelect: true, 4 | inputSearch: true, 5 | component: '.input-group-append .input-group-text,.iconpicker-component' 6 | }); 7 | } 8 | 9 | jQuery(document).ready(initFontAwesomeIconPicker); 10 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/ZikulaThemeBundle.Phpinfo.js: -------------------------------------------------------------------------------- 1 | // Copyright Zikula, licensed MIT. 2 | 3 | window.addEventListener('load', function () { 4 | document.querySelectorAll('#phpinfo table').forEach(el => el.classList.add('table', 'table-striped', 'table-bordered')); 5 | }, false); 6 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/ZikulaThemeBundle.TestMail.js: -------------------------------------------------------------------------------- 1 | // Copyright Zikula, licensed MIT. 2 | 3 | document.addEventListener('DOMContentLoaded', function() { 4 | function toggleBodyFields() { 5 | var messageType = document.getElementById('zikulathemebundle_mailtest_messageType').value; 6 | var bodyHtmlRow = document.getElementById('zikulathemebundle_mailtest_bodyHtml_row'); 7 | var bodyTextRow = document.getElementById('zikulathemebundle_mailtest_bodyText_row'); 8 | 9 | var messageTypes = ['html', 'multipart']; 10 | if (-1 !== messageTypes.indexOf(messageType)) { 11 | bodyHtmlRow.classList.remove('d-none'); 12 | } else { 13 | bodyHtmlRow.classList.add('d-none'); 14 | } 15 | 16 | messageTypes = ['text', 'multipart']; 17 | if (-1 !== messageTypes.indexOf(messageType)) { 18 | bodyTextRow.classList.remove('d-none'); 19 | } else { 20 | bodyTextRow.classList.add('d-none'); 21 | } 22 | } 23 | 24 | var messageTypeInput = document.getElementById('zikulathemebundle_mailtest_messageType'); 25 | messageTypeInput.addEventListener('change', toggleBodyFields); 26 | toggleBodyFields(); 27 | }); 28 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/bs-custom-file-input/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Johann-S 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/fontawesome-iconpicker/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Javi Aguilar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/fontawesome-iconpicker/version.txt: -------------------------------------------------------------------------------- 1 | 3.2.1 2 | from https://github.com/Sentence/fontawesome-iconpicker 3 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/public/js/jquery/version.txt: -------------------------------------------------------------------------------- 1 | jQuery 3.7.1 2 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Bundle/MetaData/ThemeBundleMetaData.php: -------------------------------------------------------------------------------- 1 | render('@ZikulaTheme/Branding/overview.html.twig', []); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Controller/TestController.php: -------------------------------------------------------------------------------- 1 | render('@ZikulaTheme/Test/page.html.twig', 28 | [ 29 | 'isAdminArea' => $request->attributes->get('isAdminArea', false), 30 | ] 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/EventSubscriber/OutputCompressionSubscriber.php: -------------------------------------------------------------------------------- 1 | ['onKernelRequest', 1023], 30 | ]; 31 | } 32 | 33 | public function onKernelRequest(RequestEvent $event): void 34 | { 35 | // check if compression is desired 36 | if (!$this->useCompression) { 37 | return; 38 | } 39 | 40 | if (!$event->isMainRequest()) { 41 | return; 42 | } 43 | 44 | // check if Zlib extension is available 45 | if (!extension_loaded('zlib')) { 46 | return; 47 | } 48 | 49 | // set compression on 50 | ini_set('zlib.output_handler', ''); 51 | ini_set('zlib.output_compression', 'On'); 52 | ini_set('zlib.output_compression_level', 6); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/ExtensionMenu/AbstractExtensionMenu.php: -------------------------------------------------------------------------------- 1 | getAdmin(); 22 | } 23 | if (ExtensionMenuInterface::CONTEXT_USER === $context) { 24 | return $this->getUser(); 25 | } 26 | if (ExtensionMenuInterface::CONTEXT_ACCOUNT === $context) { 27 | return $this->getAccount(); 28 | } 29 | 30 | return []; 31 | } 32 | 33 | protected function getAdmin(): iterable 34 | { 35 | return []; 36 | } 37 | 38 | protected function getUser(): iterable 39 | { 40 | return []; 41 | } 42 | 43 | protected function getAccount(): iterable 44 | { 45 | return []; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/ExtensionMenu/ExtensionMenuEvent.php: -------------------------------------------------------------------------------- 1 | bundleName; 30 | } 31 | 32 | public function getMenuContext(): string 33 | { 34 | return $this->context; 35 | } 36 | 37 | /** 38 | * @return MenuItemInterface[] 39 | */ 40 | public function getMenu(): iterable 41 | { 42 | return $this->menu; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/ExtensionMenu/ExtensionMenuInterface.php: -------------------------------------------------------------------------------- 1 | setAttribute('icon', $options['icon']); 32 | } 33 | 34 | public function buildView(FormView $view, FormInterface $form, array $options): void 35 | { 36 | $view->vars['icon'] = $options['icon']; 37 | } 38 | 39 | public function configureOptions(OptionsResolver $resolver): void 40 | { 41 | $resolver->setDefaults([ 42 | 'icon' => null, 43 | ]); 44 | } 45 | 46 | public static function getExtendedTypes(): iterable 47 | { 48 | return [ButtonType::class]; // Extend the button field type 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Form/Extension/FormTypeHelpExtension.php: -------------------------------------------------------------------------------- 1 | setAttribute('help', $options['help']) 30 | ->setAttribute('input_group', $options['input_group']) 31 | ->setAttribute('alert', $options['alert']) 32 | ; 33 | } 34 | 35 | public function buildView(FormView $view, FormInterface $form, array $options): void 36 | { 37 | $view->vars['help'] = $options['help']; 38 | $view->vars['input_group'] = $options['input_group']; 39 | $view->vars['alert'] = $options['alert']; 40 | } 41 | 42 | public function configureOptions(OptionsResolver $resolver): void 43 | { 44 | $resolver->setDefaults([ 45 | 'input_group' => null, 46 | 'alert' => null, 47 | ]); 48 | 49 | $resolver->setAllowedTypes('help', ['string', 'null', 'array', TranslatableMessage::class]); 50 | } 51 | 52 | public static function getExtendedTypes(): iterable 53 | { 54 | return [FormType::class]; // Extend all field types 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Form/Type/DeletionType.php: -------------------------------------------------------------------------------- 1 | add('delete', SubmitType::class, [ 29 | 'label' => 'Delete', 30 | 'icon' => 'fa-trash-alt', 31 | 'attr' => [ 32 | 'class' => 'btn-danger', 33 | ], 34 | ]) 35 | ->add('cancel', SubmitType::class, [ 36 | 'label' => 'Cancel', 37 | 'validate' => false, 38 | 'icon' => 'fa-times', 39 | 'attr' => [ 40 | 'class' => 'btn-secondary', 41 | ], 42 | ]) 43 | ; 44 | } 45 | 46 | public function getBlockPrefix(): string 47 | { 48 | return 'zikulathemebundle_deletion'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Form/Type/IconType.php: -------------------------------------------------------------------------------- 1 | getRoute($request); 30 | 31 | return str_contains($route, self::ROUTE_PART_ADMIN); 32 | } 33 | 34 | public function getDashboardControllerFqcn(Request $request): string 35 | { 36 | $isAdminArea = $this->isAdminArea($request); 37 | $request->attributes->set('isAdminArea', $isAdminArea); 38 | 39 | return $isAdminArea ? AdminDashboardController::class : UserDashboardController::class; 40 | } 41 | 42 | private function getRoute(Request $request): string 43 | { 44 | return $request->attributes->get('_route') ?? ''; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Helper/ResourceMenuProvider.php: -------------------------------------------------------------------------------- 1 | setLinkTarget('_blank'); 25 | yield MenuItem::linkToUrl(t('ModuleStudio'), 'fas fa-wand-sparkles', 'https://modulestudio.de/en/documentation/')->setLinkTarget('_blank'); 26 | yield MenuItem::subMenu(t('Foundation'), 'fas fa-cubes-stacked')->setSubItems([ 27 | MenuItem::linkToUrl(t('Symfony'), 'fab fa-symfony', 'https://symfony.com/')->setLinkTarget('_blank'), 28 | MenuItem::linkToUrl(t('Twig'), 'fas fa-file-lines', 'https://twig.symfony.com/')->setLinkTarget('_blank'), 29 | MenuItem::linkToUrl(t('Doctrine'), 'fas fa-database', 'https://www.doctrine-project.org/')->setLinkTarget('_blank'), 30 | MenuItem::linkToUrl(t('EasyAdmin'), 'fas fa-screwdriver-wrench', 'https://symfony.com/bundles/EasyAdminBundle/current/index.html')->setLinkTarget('_blank'), 31 | MenuItem::linkToUrl(t('Bootstrap'), 'fab fa-bootstrap', 'https://getbootstrap.com/')->setLinkTarget('_blank'), 32 | ]); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Menu/ExtensionMenu.php: -------------------------------------------------------------------------------- 1 | setPermission('ROLE_ADMIN'); 26 | yield MenuItem::linktoRoute(t('Test mail settings'), 'fas fa-envelope', 'zikula_theme_tool_testmail') 27 | ->setPermission('ROLE_ADMIN'); 28 | yield MenuItem::linktoRoute(t('PHP configuration'), 'fab fa-php', 'zikula_theme_tool_phpinfo') 29 | ->setPermission('ROLE_ADMIN'); 30 | } 31 | 32 | public function getBundleName(): string 33 | { 34 | return 'ZikulaThemeBundle'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Twig/Extension/BrandingExtension.php: -------------------------------------------------------------------------------- 1 | ['html']]), 29 | new TwigFunction('siteImagePath', [BrandingRuntime::class, 'getSiteImagePath']) 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/src/Twig/Runtime/BrandingRuntime.php: -------------------------------------------------------------------------------- 1 | site; 34 | } 35 | 36 | /** 37 | * Returns site name. 38 | */ 39 | public function getSiteName(): string 40 | { 41 | return $this->site->getName(); 42 | } 43 | 44 | /** 45 | * Returns site slogan. 46 | */ 47 | public function getSiteSlogan(): string 48 | { 49 | return $this->site->getSlogan(); 50 | } 51 | 52 | /** 53 | * Returns site branding markup. 54 | */ 55 | public function getSiteBrandingMarkup(): string 56 | { 57 | return $this->twig->render('@ZikulaTheme/Branding/manifest.html.twig'); 58 | } 59 | 60 | /** 61 | * Returns site image path. 62 | */ 63 | public function getSiteImagePath(string $imageType = ''): string 64 | { 65 | if (!in_array($imageType, ['logo', 'mobileLogo', 'icon'], true)) { 66 | $imageType = 'logo'; 67 | } 68 | 69 | $accessor = 'get' . ucfirst($imageType) . 'Path'; 70 | 71 | return $this->site->{$accessor}(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Branding/manifest.html.twig: -------------------------------------------------------------------------------- 1 | {# force fullscreen mode to look like an app #} 2 | 3 | {# adapt status line: default, black or black-translucent #} 4 | 5 | {# viewport initialisation #} 6 | 7 | {# reference icons and manifest #} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Dashboard/layout_admin.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@!EasyAdmin/layout.html.twig' %} 2 | 3 | {% block head_metas %} 4 | {{ parent() }} 5 | {{ include('@ZikulaTheme/Dashboard/manifest.html.twig') }} 6 | {% endblock %} 7 | 8 | {% block page_title %}{{ siteName()|replace({'#pagetitle#': parent()}) }}{% endblock %} 9 | {% block sidebar %} 10 |

Hello admin!

11 | {{ parent() }} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Dashboard/layout_user.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@!EasyAdmin/layout.html.twig' %} 2 | 3 | {% block head_metas %} 4 | {{ parent() }} 5 | {{ include('@ZikulaTheme/Dashboard/manifest.html.twig') }} 6 | {% endblock %} 7 | 8 | {% block page_title %}{{ siteName()|replace({'#pagetitle#': parent()}) }}{% endblock %} 9 | {% block sidebar %} 10 |

Hello user!

11 | {{ parent() }} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Dashboard/manifest.html.twig: -------------------------------------------------------------------------------- 1 | {# force fullscreen mode to look like an app #} 2 | 3 | {# adapt status line: default, black or black-translucent #} 4 | 5 | {# viewport initialisation #} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Form/form_div_layout.html.twig: -------------------------------------------------------------------------------- 1 | {# overrides button_widget to add icon parameter @see \Zikula\ThemeBundle\Form\Extension\ButtonTypeIconExtension #} 2 | {% block button_widget -%} 3 | {% set attr = attr|merge({class: (attr.class|default('') ~ ' btn')|trim}) %} 4 | {% if label is empty -%} 5 | {%- if label_format is not empty -%} 6 | {% set label = label_format|replace({ 7 | '%name%': name, 8 | '%id%': id, 9 | }) %} 10 | {%- else -%} 11 | {% set label = name|humanize %} 12 | {%- endif -%} 13 | {%- endif -%} 14 | {% if icon|default %} 15 | {% set iconHtml = ' ' %} 16 | {% else %} 17 | {% set iconHtml = '' %} 18 | {% endif %} 19 | 20 | {%- endblock button_widget %} 21 | 22 | {# overrides textarea_widget to catch array to string conversion issues when a form returns with errors #} 23 | {%- block textarea_widget -%} 24 | {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %} 25 | 26 | {%- endblock textarea_widget -%} 27 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Form/icon_picker.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Test/page.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block page_title 'Test page'|trans %} 4 | {% block main %} 5 |

Hello {% if isAdminArea %}admin{% else %}user{% endif %}!

6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Tool/phpinfo.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block page_title 'PHP configuration'|trans %} 4 | {% block main %} 5 |
6 | {{ phpinfo|raw }} 7 |
8 | {% endblock %} 9 | {% block head_stylesheets %} 10 | {{ parent() }} 11 | 12 | {% endblock %} 13 | {% block body_javascript %} 14 | {{ parent() }} 15 | 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/Tool/testmail.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block page_title 'Test mailer settings'|trans %} 4 | {% block main %} 5 | {{ form_start(form) }} 6 | {{ form_errors(form) }} 7 | 8 |
9 | {% trans %}Settings test{% endtrans %} 10 | {{ form_row(form.fromName) }} 11 | {{ form_row(form.fromAddress) }} 12 | {{ form_row(form.toName) }} 13 | {{ form_row(form.toAddress) }} 14 | {{ form_row(form.subject) }} 15 | {{ form_row(form.messageType) }} 16 |
17 | {{ form_row(form.bodyHtml) }} 18 |
19 |
20 | {{ form_row(form.bodyText) }} 21 |
22 |
23 | 24 |
25 |
26 | {{ form_widget(form.test) }} 27 | {{ form_widget(form.cancel) }} 28 |
29 |
30 | {{ form_end(form) }} 31 | {% endblock %} 32 | {% block body_javascript %} 33 | {{ parent() }} 34 | 35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/templates/welcome.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block page_title %} 4 | {{ t('Welcome to %siteName%', {'%siteName%': siteName()})|trans }} 5 | {% endblock %} 6 | 7 | {% block main %} 8 |

{{ t('To customize this page check %file%.', {'%file%': '/config/packages/zikula_theme.yaml'})|trans|raw }}

9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/tests/ExtensionMenu/Fixtures/BarExtensionMenu.php: -------------------------------------------------------------------------------- 1 | {$method}(); 31 | } 32 | 33 | return null; 34 | } 35 | 36 | private function getUser(): ?ItemInterface 37 | { 38 | $menu = $this->factory->createItem('admin'); 39 | $menu->addChild('list', [ 40 | 'route' => 'list', 41 | ])->setAttribute('icon', 'fas fa-list'); 42 | $menu->addChild('new', [ 43 | 'route' => 'edit', 44 | ]); 45 | 46 | return $menu; 47 | } 48 | 49 | private function getBar(): ?ItemInterface 50 | { 51 | $menu = $this->factory->createItem('foo'); 52 | $menu->addChild('bar admin', [ 53 | 'route' => 'bar_admin', 54 | ])->setAttribute('icon', 'fas fa-plus'); 55 | 56 | return $menu; 57 | } 58 | 59 | private function getAccount(): ?ItemInterface 60 | { 61 | $menu = $this->factory->createItem('account'); 62 | $menu->addChild('bar acct', [ 63 | 'route' => 'bar_acct', 64 | ]); 65 | 66 | return $menu; 67 | } 68 | 69 | public function getBundleName(): string 70 | { 71 | return 'ZikulaBarExtension'; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/system/ThemeBundle/tests/ExtensionMenu/Fixtures/FooExtensionMenu.php: -------------------------------------------------------------------------------- 1 | getAdmin(); 30 | } 31 | if (ExtensionMenuInterface::TYPE_USER === $type) { 32 | return $this->getUser(); 33 | } 34 | 35 | return null; 36 | } 37 | 38 | private function getAdmin(): ?ItemInterface 39 | { 40 | $menu = $this->factory->createItem('foo'); 41 | $menu->addChild('list', [ 42 | 'route' => 'list', 43 | ]); 44 | $menu->addChild('foo', [ 45 | 'route' => 'foo', 46 | ]); 47 | $menu->addChild('bar', [ 48 | 'route' => 'bar', 49 | ]); 50 | 51 | return $menu; 52 | } 53 | 54 | private function getUser(): ?ItemInterface 55 | { 56 | $menu = $this->factory->createItem('foo'); 57 | $menu->addChild('user list', [ 58 | 'route' => 'user_list', 59 | ]); 60 | 61 | return $menu; 62 | } 63 | 64 | public function getBundleName(): string 65 | { 66 | return 'ZikulaFooExtension'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/system/UsersBundle/.gitattributes: -------------------------------------------------------------------------------- 1 | /Tests export-ignore 2 | /phpunit.xml.dist export-ignore 3 | /.gitignore export-ignore 4 | -------------------------------------------------------------------------------- /src/system/UsersBundle/README.md: -------------------------------------------------------------------------------- 1 | # UsersBundle 2 | 3 | This is a read-only repository. 4 | 5 | ## Resources 6 | 7 | * [Report issues](https://github.com/zikula/core/issues) and 8 | [send Pull Requests](https://github.com/zikula/core/pulls) 9 | in the [main Zikula repository](https://github.com/zikula/core) 10 | * For more information visit [ziku.la](https://ziku.la/). 11 | * Please see our [documentation](https://docs.ziku.la). 12 | 13 | -------------------------------------------------------------------------------- /src/system/UsersBundle/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zikula/users-bundle", 3 | "version": "dev-4.0", 4 | "description": "User account administration", 5 | "type": "symfony-bundle", 6 | "license": "LGPL-3.0-or-later", 7 | "authors": [ 8 | { 9 | "name": "Zikula", 10 | "homepage": "https://ziku.la/" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=8.2", 15 | "doctrine/doctrine-migrations-bundle": "^3.3", 16 | "nucleos/profile-bundle": "^2", 17 | "nucleos/user-bundle": "^3", 18 | "symfony/config": "^7.2", 19 | "symfony/dependency-injection": "^7.2", 20 | "symfony/doctrine-bridge": "^7.2", 21 | "symfony/form": "^7.2", 22 | "symfony/http-foundation": "^7.2", 23 | "symfony/http-kernel": "^7.2", 24 | "symfony/intl": "^7.2", 25 | "symfony/mailer": "^7.2", 26 | "symfony/property-access": "^7.2", 27 | "symfony/routing": "^7.2", 28 | "symfony/security-bundle": "^7.2", 29 | "symfony/string": "^7.2", 30 | "symfony/validator": "^7.2", 31 | 32 | "zikula/core-bundle": "dev-4.0", 33 | "zikula/theme-bundle": "dev-4.0" 34 | }, 35 | "autoload": { 36 | "psr-4": { "Zikula\\UsersBundle\\": "src" } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/system/UsersBundle/config/routing.yaml: -------------------------------------------------------------------------------- 1 | zikulausersbundle: 2 | resource: '@ZikulaUsersBundle/src/Controller' # TODO src is a workaround for https://github.com/symfony/symfony/issues/46482 3 | type: attribute 4 | -------------------------------------------------------------------------------- /src/system/UsersBundle/config/services.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | profile_property_prefix: 'zpmpp' 3 | 4 | services: 5 | _defaults: 6 | autowire: true 7 | autoconfigure: true 8 | public: false 9 | 10 | Zikula\UsersBundle\: 11 | resource: '../src/*' 12 | 13 | Zikula\UsersBundle\Bundle\Initializer\UsersInitializer: 14 | public: true 15 | 16 | Zikula\UsersBundle\Bundle\MetaData\UsersBundleMetaData: 17 | public: true 18 | 19 | Zikula\UsersBundle\Helper\: 20 | resource: '../src/Helper/*' 21 | lazy: true 22 | 23 | Zikula\UsersBundle\Repository\UserRepositoryInterface: '@Zikula\UsersBundle\Repository\UserRepository' 24 | -------------------------------------------------------------------------------- /src/system/UsersBundle/phpunit.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./Tests/ 27 | 28 | 29 | 30 | 31 | 32 | . 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/system/UsersBundle/public/js/ZikulaUsersBundle.Avatar.Edit.js: -------------------------------------------------------------------------------- 1 | // Copyright Zikula, licensed MIT. 2 | 3 | (function($) { 4 | function showAvatar() { 5 | $('.avatar-preview').remove(); 6 | $('.avatar-selector').each(function (index) { 7 | var avatarUrl, avatarPreview; 8 | 9 | avatarUrl = ''; 10 | if ('blank.jpg' !== $(this).val()) { 11 | if ('' === $(this).val() || 'gravatar.jpg' === $(this).val()) { 12 | avatarUrl = $('#gravatarUrl').val(); 13 | } else { 14 | avatarUrl = Zikula.Config.baseURL + Zikula.Config.baseURI + '/' + $('#avatarPath').val() + '/' + $(this).val(); 15 | } 16 | } 17 | 18 | avatarPreview = '' !== avatarUrl ? '' + Translator.trans('Avatar') + '' : ''; 19 | 20 | $(this).parent().append('

' + avatarPreview + '

'); 21 | }); 22 | } 23 | 24 | $(document).ready(function() { 25 | if ($('.avatar-selector').length > 0) { 26 | $('.avatar-selector').change(showAvatar); 27 | showAvatar(); 28 | } 29 | }); 30 | })(jQuery); 31 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/Bundle/Initializer/UsersInitializer.php: -------------------------------------------------------------------------------- 1 | setId(UsersConstant::USER_ID_ANONYMOUS); 35 | $user->setUsername('guest'); 36 | $user->setEmail(''); 37 | $user->setActivated(UsersConstant::ACTIVATED_ACTIVE) 38 | ->setApprovedDate($then) 39 | ->setApprovedBy(UsersConstant::USER_ID_ADMIN) 40 | ->setRegistrationDate($then) 41 | ->setLastLogin($then); 42 | $this->entityManager->persist($user); 43 | 44 | // Admin 45 | $user = (new User())->setId(UsersConstant::USER_ID_ADMIN); 46 | $user->setUsername('admin'); 47 | $user->setEmail(''); 48 | $user->setActivated(UsersConstant::ACTIVATED_ACTIVE) 49 | ->setApprovedDate($now) 50 | ->setApprovedBy(UsersConstant::USER_ID_ADMIN) 51 | ->setRegistrationDate($now) 52 | ->setLastLogin($then); 53 | $this->entityManager->persist($user); 54 | 55 | $this->entityManager->flush(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/Bundle/MetaData/UsersBundleMetaData.php: -------------------------------------------------------------------------------- 1 | id; 31 | } 32 | 33 | public function setId(?int $id): self 34 | { 35 | $this->id = $id; 36 | 37 | return $this; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/Entity/UserAttributesTrait.php: -------------------------------------------------------------------------------- 1 | attributes; 26 | } 27 | 28 | public function getAttributeValue(string $name): string 29 | { 30 | return $this->getAttributes()->offsetExists($name) ? $this->getAttributes()->get($name)->getValue() : ''; 31 | } 32 | 33 | public function setAttributes(ArrayCollection $attributes): self 34 | { 35 | $this->attributes = $attributes; 36 | 37 | return $this; 38 | } 39 | 40 | /** 41 | * @param mixed $value 42 | */ 43 | public function setAttribute(string $name, $value): self 44 | { 45 | if (isset($this->attributes[$name])) { 46 | $this->attributes[$name]->setValue($value); 47 | } else { 48 | $this->attributes[$name] = new UserAttribute($this, $name, $value); 49 | } 50 | 51 | return $this; 52 | } 53 | 54 | public function delAttribute(string $name): self 55 | { 56 | if (isset($this->attributes[$name])) { 57 | $this->attributes->remove($name); 58 | } 59 | 60 | return $this; 61 | } 62 | 63 | public function hasAttribute(string $name): bool 64 | { 65 | return $this->attributes->containsKey($name); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/Helper/ChoiceHelper.php: -------------------------------------------------------------------------------- 1 | roleHierarchy = $roleHierarchy; 28 | } 29 | 30 | public function getRoles(): array 31 | { 32 | $systemRoles = [ 33 | 'User' => 'ROLE_USER', 34 | 'Editor' => 'ROLE_EDITOR', 35 | 'Administrator' => 'ROLE_ADMIN', 36 | 'Super administrator' => 'ROLE_SUPER_ADMIN', 37 | ]; 38 | 39 | $definedRoles = []; 40 | array_walk_recursive($this->roleHierarchy, static function ($role) use (&$roles) { 41 | $definedRoles[$role] = $role; 42 | }); 43 | 44 | $roles = $systemRoles; 45 | foreach ($definedRoles as $role) { 46 | if (!in_array($role, $roles, true)) { 47 | $roles[$role] = $role; 48 | } 49 | } 50 | 51 | return $roles; 52 | } 53 | 54 | public function getActivatedValues(): array 55 | { 56 | return [ 57 | 'Active' => UsersConstant::ACTIVATED_ACTIVE, 58 | 'Inactive' => UsersConstant::ACTIVATED_INACTIVE, 59 | 'Pending' => UsersConstant::ACTIVATED_PENDING_REG, 60 | ]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/Helper/GravatarHelper.php: -------------------------------------------------------------------------------- 1 | createQueryBuilder('u') 31 | ->innerJoin('u.groups', 'g') 32 | ->where('g = :group') 33 | ->setParameter('group', $group) 34 | ->getQuery() 35 | ->getResult(); 36 | } 37 | 38 | public function findUsersByGroupId(int $groupId): array 39 | { 40 | return $this->createQueryBuilder('u') 41 | ->innerJoin('u.groups', 'g') 42 | ->where('g.id = :groupId') 43 | ->setParameter('groupId', $groupId) 44 | ->getQuery() 45 | ->getResult(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/Repository/UserRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | ['html']]) 28 | ]; 29 | } 30 | 31 | public function getFilters() 32 | { 33 | return [ 34 | new TwigFilter('profileLinkByUserId', [ProfileRuntime::class, 'profileLinkByUserId'], ['is_safe' => ['html']]), 35 | new TwigFilter('profileLinkByUserName', [ProfileRuntime::class, 'profileLinkByUserName'], ['is_safe' => ['html']]) 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/system/UsersBundle/src/UsersConstant.php: -------------------------------------------------------------------------------- 1 | {{ heading }} 11 | 12 |

13 | {% set siteLink = '%2$s'|replace({'%1$s': url('user_home'), '%2$s': siteName()}) %} 14 | {% if not user.isApproved %} 15 | {% trans with {'%sub%': siteLink} %}A new user account has been created but not yet activated on %sub%.{% endtrans %} 16 | {% else %} 17 | {% trans with {'%sub%': siteLink} %}A new user account has been activated on %sub%.{% endtrans %} 18 | {% endif %} 19 | {% if createdByAdmin %}{% trans %}It was created by an administrator or sub-administrator.{% endtrans %}{% endif %} 20 | {% trans %}The account details are as follows:{% endtrans %} 21 |

22 | 23 |

{% trans %}User name{% endtrans %}: '{{ user.uname }}'

24 | {{ include('@ZikulaUsers/Email/footer.txt.twig')|nl2br }} 25 | -------------------------------------------------------------------------------- /src/system/UsersBundle/templates/Email/regadminnotify.txt.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'mail' %} 2 | {{ include('@ZikulaUsers/Email/header.txt.twig') }} 3 | {% if not user.isApproved %} 4 | {% set heading = 'New registration pending approval'|trans %} 5 | {% elseif not isVerified %} 6 | {% set heading = 'New registration pending e-mail verification'|trans %} 7 | {% else %} 8 | {% set heading = 'New user activated'|trans %} 9 | {% endif %} 10 | {{ heading }} 11 | 12 | {% if not user.isApproved %} 13 | {% trans with {'%sub%': siteName()} %}A new user account has been created but not yet activated on %sub%.{% endtrans %} 14 | {% else %} 15 | {% trans with {'%sub%': siteName()} %}A new user account has been activated on %sub%.{% endtrans %} 16 | {% endif %} 17 | {% if createdByAdmin %}{% trans %}It was created by an administrator or sub-administrator.{% endtrans %}{% endif %} 18 | {% trans %}The account details are as follows:{% endtrans %} 19 | 20 | {% trans %}User name{% endtrans %}: '{{ user.uname }}' 21 | {{ include('@ZikulaUsers/Email/footer.txt.twig') }} 22 | -------------------------------------------------------------------------------- /src/system/UsersBundle/templates/Email/regdeny.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'mail' %} 2 | {{ include('@ZikulaUsers/Email/header.txt.twig')|nl2br }} 3 |

{% trans with {'%sub%': siteName()} %}A message from %sub%...{% endtrans %}

4 | 5 |

{% trans with {'%email%': user.email, '%site%': siteName(), '%url%': url('user_home')} %}Recently, this e-mail address ("%email") was used to request an account on "%site%" (%url%).{% endtrans %} 6 | {% trans %}The information that was registered is as follows:{% endtrans %}

7 | 8 |

{% trans %}User name{% endtrans %}: {{ user.uname }}

9 | 10 |

{% trans %}Thank you for your application for a new account. At this time we are unable to approve your application.{% endtrans %}

11 | 12 | {% if reason is not empty %} 13 |

{{ reason }}

14 | {% endif %} 15 | {{ include('@ZikulaUsers/Email/footer.txt.twig')|nl2br }} 16 | -------------------------------------------------------------------------------- /src/system/UsersBundle/templates/Email/regdeny.txt.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'mail' %} 2 | {{ include('@ZikulaUsers/Email/header.txt.twig') }} 3 | {% trans with {'%sub%': siteName()} %}A message from %sub%...{% endtrans %} 4 | 5 | {% trans with {'%email%': user.email, '%site%': siteName(), '%url%': url('user_home')} %}Recently, this e-mail address ("%email") was used to request an account on "%site%" (%url%).{% endtrans %} 6 | {% trans %}The information that was registered is as follows:{% endtrans %} 7 | 8 | {% trans %}User name{% endtrans %}: {{ user.uname }} 9 | 10 | {% trans %}Thank you for your application for a new account. At this time we are unable to approve your application.{% endtrans %} 11 | 12 | {% if reason is not empty %} 13 | {{ reason }} 14 | {% endif %} 15 | {{ include('@ZikulaUsers/Email/footer.txt.twig') }} 16 | -------------------------------------------------------------------------------- /src/system/UsersBundle/templates/Email/welcome.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'mail' %} 2 | {{ include('@ZikulaUsers/Email/header.txt.twig')|nl2br }} 3 |

{% trans with {'%sub%': siteName()} %}Welcome to %sub%!{% endtrans %}

4 | 5 |

6 | {% trans %}Hello!{% endtrans %} 7 | {% trans with {'%email%': user.email, '%site%': siteName(), '%url%': url('user_home')} %}This e-mail address ('%email%') has been used to register an account on '%site%' (%url%).{% endtrans %} 8 | {% trans %}The information that was registered is as follows:{% endtrans %} 9 |

10 | 11 |

{% trans %}User name{% endtrans %}: {{ user.uname }}
12 | {% if createdpassword is not empty %} 13 | {% trans %}Password{% endtrans %}: {{ createdpassword }} 14 | {% endif %} 15 |

16 | 17 | {% if createdpassword is not empty %}

{% trans %}(This is the only time you will receive your password. Please keep it in a safe place.){% endtrans %}

{% endif %} 18 | 19 | {% if not user.approved %} 20 |

{% trans %}Thank you for your application for a new account. Your application has been forwarded to the site administrator for review. Please expect a message once the review process is complete.{% endtrans %}

21 | {% elseif not createdByAdmin and user.activated <= 0 %} 22 |

{% trans %}Your account application is pending for some reason. Expect additional email(s) with information on finalizing your registration.{% endtrans %}

23 | {% elseif not createdByAdmin and user.activated > 0 %} 24 |

{% trans %}Your account application has been approved by the site administrator. Thank you for your patience during the new account application review process.{% endtrans %}

25 | {% elseif createdByAdmin %} 26 |

{% trans %}The web site administrator has created this new account for you.{% endtrans %}

27 | {% endif %} 28 | 29 | {% if user.approved and user.activated > 0 %} 30 |

{% trans %}You may now log into the web site.{% endtrans %}

31 | {% endif %} 32 | {{ include('@ZikulaUsers/Email/footer.txt.twig')|nl2br }} 33 | -------------------------------------------------------------------------------- /src/system/UsersBundle/templates/Email/welcome.txt.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'mail' %} 2 | {{ include('@ZikulaUsers/Email/header.txt.twig') }} 3 | {% trans with {'%sub%': siteName()} %}Welcome to %sub%!{% endtrans %} 4 | 5 | {% trans %}Hello!{% endtrans %} 6 | 7 | {% trans with {'%email%': user.email, '%site%': siteName(), '%url%': url('user_home')} %}This e-mail address ('%email%') has been used to register an account on '%site%' (%url%).{% endtrans %} 8 | {% trans %}The information that was registered is as follows:{% endtrans %} 9 | 10 | {% trans %}User name{% endtrans %}: {{ user.uname }} 11 | {% if createdpassword is not empty %} 12 | {% trans %}Password{% endtrans %}: {{ createdpassword }} 13 | {% endif %} 14 | 15 | {% if createdpassword is not empty %}{% trans %}(This is the only time you will receive your password. Please keep it in a safe place.){% endtrans %}{% endif %} 16 | 17 | {% if not user.approved %} 18 | {% trans %}Thank you for your application for a new account. Your application has been forwarded to the site administrator for review. Please expect a message once the review process is complete.{% endtrans %} 19 | {% elseif not createdByAdmin %} 20 | {% trans %}Your account application has been approved. Thank you for your patience during the new account application review process.{% endtrans %} 21 | {% elseif createdByAdmin %} 22 | {% trans %}The web site administrator has created this new account for you.{% endtrans %} 23 | {% endif %} 24 | 25 | {% if user.approved %} 26 | {% trans %}You may now log into the web site.{% endtrans %} 27 | {% endif %} 28 | {{ include('@ZikulaUsers/Email/footer.txt.twig') }} 29 | -------------------------------------------------------------------------------- /templates/bundles/NucleosProfileBundle/Profile/edit_content.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'NucleosProfileBundle' %} 2 | 3 |

{{ 'Edit profile'|trans }}

4 | 5 | {{ form_start(form, { 'action': path('nucleos_profile_profile_edit'), 'attr': { 'class': 'nucleos_profile_profile_edit' } }) }} 6 | {% set policies %} 7 |
8 | {{ 'Site policies'|trans }} 9 | {{ include('@ZikulaLegal/Form/acceptPolicies.html.twig') }} 10 |
11 | {{ form_row(form.save) }} 12 | {% endset %} 13 | {{ form_widget(form) }} 14 | {{ policies }} 15 | {{ form_end(form) }} 16 | 17 | {#{ form_start(form) }} 18 | {% for element in form|filter(e => e.vars.name not in ['save', 'cancel']) %} 19 | {{ form_row(element) }} 20 | {% endfor %} 21 |
22 |
23 | {{ form_widget(form.save) }} 24 | {{ form_widget(form.cancel) }} 25 |
26 | 27 | 28 |
29 | {{ form_end(form) }#} 30 | 31 | 32 | -------------------------------------------------------------------------------- /templates/bundles/NucleosProfileBundle/Profile/show_content.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'NucleosProfileBundle' %} 2 | 3 |
4 |
5 |

{% trans with {'%username': user.username} %}Profile for %username{% endtrans %}

6 |
7 |
8 | {{ userAvatar(user.id) }} 9 |
10 |
11 |
12 |
13 | {{ 'profile.show.username'|trans }} 14 |
15 |
16 | {{ user.username }} 17 |
18 |
19 |
20 |
21 | {{ 'profile.show.email'|trans }} 22 |
23 |
24 | {{ user.email }} 25 |
26 |
27 | {{ include('@NucleosProfile/Profile/show_profile_fields.html.twig') }} 28 |
29 |
30 |
31 | {% if app.user|default and app.user.id == user.id or is_granted('ROLE_EDITOR') %} 32 | 35 | {% endif %} 36 |
37 | -------------------------------------------------------------------------------- /templates/bundles/NucleosProfileBundle/Registration/register_content.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'NucleosProfileBundle' %} 2 | 3 | {{ form_start(form, {'method': 'post', 'action': path('nucleos_profile_registration_register'), 'attr': {'class': 'nucleos_profile_registration_register'}}) }} 4 | {% set policies %} 5 |
6 | {{ 'Site policies'|trans }} 7 | {{ include('@ZikulaLegal/Form/acceptPolicies.html.twig') }} 8 |
9 | {{ form_row(form.save) }} 10 | {% endset %} 11 | {{ form_widget(form) }} 12 | {{ policies }} 13 | {{ form_end(form) }} 14 | -------------------------------------------------------------------------------- /templates/bundles/NucleosUserBundle/layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/page/content.html.twig' %} 2 | 3 | {% block content_title 'Your account'|trans %} 4 | {% block main %} 5 |
6 | {% if is_granted("IS_AUTHENTICATED_REMEMBERED") %} 7 | {{ 'layout.logged_in_as'|trans({'%username%': app.user.username}, 'NucleosUserBundle') }} | 8 | 9 | {{ 'layout.logout'|trans({}, 'NucleosUserBundle') }} 10 | 11 | {% else %} 12 | {{ 'layout.login'|trans({}, 'NucleosUserBundle') }} 13 | {% endif %} 14 |
15 |
16 | {% block nucleos_user_content %} 17 | {% endblock nucleos_user_content %} 18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | bootEnv(dirname(__DIR__) . '/.env'); 20 | } 21 | 22 | if ($_SERVER['APP_DEBUG']) { 23 | umask(0000); 24 | } 25 | -------------------------------------------------------------------------------- /translations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zikula/core/9100e04b4539c47695ec58544a99858f5c2362a8/translations/.gitkeep -------------------------------------------------------------------------------- /var/cache/.htaccess: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------ 2 | # Purpose of file: block any web access to unallowed files 3 | # stored under the /var/cache directory 4 | # ------------------------------------------------------------------ 5 | 6 | # Apache 2.2 7 | 8 | Order deny,allow 9 | Deny from all 10 | 11 | 12 | # Apache 2.4 13 | 14 | Require all denied 15 | 16 | --------------------------------------------------------------------------------