Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
.*
!.github
!.gitignore
!.htaccess
!.gitkeep
!.ddev
!.php-cs-fixer.php
!.github/ci-files/.my.cnf
.ddev/mautic-preference
/.ddev/docker-compose.host-docker-internal.yaml
!/.ddev/.env.*.dist
/.ddev/docker-compose.phpmyadmin_norouter.yaml
!.gitpod.Dockerfile
!.gitpod.yml
!.ddev/commands/web/dd
.php_cs.cache
/.env.local
/.env.local.php
/.env.*.local
/composer.phar
/coverage.xml
/app/bootstrap*
/app/console
/app/tests.bootstrap*
/app/phpunit.xml
/var/bootstrap*
/app/bundles/CoreBundle/Assets/css/app/less/**/*.css
/app/bundles/CoreBundle/Assets/pictograms/
/app/bundles/CoreBundle/Assets/css/libraries/**/*.css
!/app/bundles/CoreBundle/Assets/css/libraries/builder.css
!/app/bundles/CoreBundle/Assets/css/*.css
/app/cache/*
!/app/cache/.gitkeep
/var/cache/*
!/var/cache/.gitkeep
/var/phpstan-cache/*
/app/logs/*
!/app/logs/.gitkeep
/var/logs/*
!/var/logs/.gitkeep
/app/spool/*
!/app/spool/.gitkeep
/var/spool/*
!/var/spool/.gitkeep
/var/tmp/*
!/var/tmp/.gitkeep
/app/config/local*.php
/app/config/config_local.php
/app/config/paths_local.php
/app/config/parameters_defaults.php
/config/*
!/config/.gitkeep
/vendor/*
!/vendor/.htaccess
/bin/*
!/bin/.htaccess
!/bin/console
/assets/ckeditor/build/*
/bundles
/node_modules
/build/coverage
/build/packaging
/build/packages/*
!/build/packages/.placeholder
/mockup
/upgrade
/upgrade_errors.txt
/media/libraries/ckeditor/*
/media/bundles/*
/media/dashboards/*
!/media/dashboards/*.json
/media/files/*
!/media/files/.htaccess
/media/assets/*
/media/images/*
!/media/images/flags
!/media/images/mejs
!/media/images/apple-touch-icon.png
!/media/images/avatar.png
!/media/images/placeholder*
!/media/images/favicon.ico
!/media/images/mautic_logo*
!/media/images/.htaccess
/media/css/app.css
/media/css/libraries.css
/media/css/mediaelementplayer.min.css
/media/css/modal.min.css
/media/js/app.js
/media/js/libraries.js
/media/js/mautic-form.js
/media/js/froogaloop.min.js
/media/js/jquery.min.js
/plugins/*
!/plugins/GrapesJsBuilderBundle
!/plugins/MauticClearbitBundle
!/plugins/MauticCloudStorageBundle
!/plugins/MauticCrmBundle
!/plugins/MauticDynamicsBundle
!/plugins/MauticEmailMarketingBundle
!/plugins/MauticFocusBundle
!/plugins/MauticFullContactBundle
!/plugins/MauticGmailBundle
!/plugins/MauticOutlookBundle
!/plugins/MauticSocialBundle
!/plugins/MauticZapierBundle
!/plugins/MauticTagManagerBundle
!/plugins/index.html
!/plugins/.gitkeep
tests/**/*.sql
/themes/*
!/themes/aurora
!/themes/blank
!/themes/cards
!/themes/confirmme
!/themes/fresh-center
!/themes/fresh-fixed
!/themes/fresh-left
!/themes/fresh-wide
!/themes/goldstar
!/themes/neopolitan
!/themes/oxygen
!/themes/skyline
!/themes/sparse
!/themes/sunday
!/themes/vibrant
!/themes/blank.png
!/themes/blank-big.png
/translations

View File

@@ -0,0 +1,158 @@
# Composer template for Mautic projects
This project template provides a starter kit for managing your Mautic
dependencies with [Composer](https://getcomposer.org/).
## Usage
First you need to install [Composer v2](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx).
> Note: The instructions below refer to the [global composer installation](https://getcomposer.org/doc/00-intro.md#globally).
You might need to replace `composer` with `php composer.phar` (or similar)
for your setup.
After that you can create the project:
```
composer create-project mautic/recommended-project:^7.0 some-dir --no-interaction
```
With `composer require ...` you can download new dependencies to your installation.
Example of installing a plugin:
```
cd some-dir
composer require mautic/helloworld-bundle
```
The `composer create-project` command passes ownership of all files to the
project that is created. You should create a new git repository, and commit
all files not excluded by the .gitignore file.
## What does the template do?
When installing the given `composer.json` some tasks are taken care of:
* Mautic will be installed in the `docroot`-directory.
* Autoloader is implemented to use the generated composer autoloader in `vendor/autoload.php`,
instead of the one provided by Mautic (`docroot/vendor/autoload.php`).
* Plugins (packages of type `mautic-plugin`) will be placed in `docroot/plugins/`
* Themes (packages of type `mautic-theme`) will be placed in `docroot/themes/`
* Creates `docroot/media`-directory.
* Creates environment variables based on your .env file. See [.env.example](.env.example).
## Updating Mautic Core
This project will attempt to keep all of your Mautic Core files up-to-date; the
project [mautic/core-composer-scaffold](https://github.com/mautic/core-composer-scaffold)
is used to ensure that your scaffold files are updated every time mautic/core is
updated. If you customize any of the "scaffolding" files (commonly .htaccess),
you may need to merge conflicts if any of your modified files are updated in a
new release of Mautic core.
Follow the steps below to update your core files.
1. Run `composer update mautic/core --with-dependencies` to update Mautic Core and its dependencies.
2. Run `git diff` to determine if any of the scaffolding files have changed.
Review the files for any changes and restore any customizations to
`.htaccess` or others.
1. Commit everything all together in a single commit, so `docroot` will remain in
sync with the `core` when checking out branches or running `git bisect`.
1. In the event that there are non-trivial conflicts in step 2, you may wish
to perform these steps on a branch, and use `git merge` to combine the
updated core files with your customized files. This facilitates the use
of a [three-way merge tool such as kdiff3](http://www.gitshah.com/2010/12/how-to-setup-kdiff-as-diff-tool-for-git.html). This setup is not necessary if your changes are simple;
keeping all of your modifications at the beginning or end of the file is a
good strategy to keep merges easy.
## FAQ
### Should I commit the contributed plugins I download?
Composer recommends **no**. They provide [argumentation against but also
workrounds if a project decides to do it anyway](https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md).
### Should I commit the scaffolding files?
The [Mautic Composer Scaffold](https://github.com/mautic/core-composer-scaffold) plugin can download the scaffold files (like
index.php, .htaccess, …) to the docroot/ directory of your project. If you have not customized those files you could choose
to not check them into your version control system (e.g. git). If that is the case for your project it might be
convenient to automatically run the mautic-scaffold plugin after every install or update of your project. You can
achieve that by registering `@composer mautic:scaffold` as post-install and post-update command in your composer.json:
```json
"scripts": {
"post-install-cmd": [
"@composer mautic:scaffold",
"..."
],
"post-update-cmd": [
"@composer mautic:scaffold",
"..."
]
},
```
### How can I apply patches to downloaded plugins?
If you need to apply patches (depending on the project being modified, a pull
request is often a better solution), you can do so with the
[composer-patches](https://github.com/cweagans/composer-patches) plugin.
To add a patch to Mautic plugin foobar insert the patches section in the extra
section of composer.json:
```json
"extra": {
"patches": {
"mautic/foobar": {
"Patch description": "URL or local path to patch"
}
}
}
```
### How do I specify a PHP version?
This project supports PHP 8.2 as the minimum version (see [Mautic requirements](https://mautic.org/mautic-requirements/)). However, running a `composer update` may upgrade some package that will require a higher PHP version.
To prevent this, you can specify the PHP version in the `config` section of `composer.json` by adding the following code:
```json
"config": {
"sort-packages": true,
"platform": {
"php": "8.2"
}
},
```
Alternatively, you can run the following command:
```bash
composer config platform.php 8.2
```
### How do I use another folder than docroot as webroot?
By default the composer.json file is configures to put all Mautic core, plugin and theme files in the `docroot` folder.
It is possible to change this folder to your own needs.
In following examples, we will change `docroot` into `public`.
#### New installations
* Run the `create-project` command without installing
```bash
composer create-project mautic/recommended-project:^7.0 some-dir --no-interaction --no-install
```
* Do a find and replace in the `composer.json` file to change `docroot/` into `public/`.
* Review the changes in the `composer.json` file to ensure there are no unintentional replacements.
* Run `composer install` to install all dependencies in the correct location.
#### Existing installations
* move the `docroot/` to `public/`
```bash
mv docroot public
```
* Do a find and replace in the `composer.json` file to change `docroot/` into `public/`.
* review the changes in the `composer.json` file to ensure there are no unintentional replacements.
* run `composer update --lock` to ensure the autoloader is aware of the changed folder.

View File

@@ -0,0 +1 @@
deny from all

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env php
<?php
use Mautic\CoreBundle\Console\Output\ConsoleDatetimeOutput;
use Symfony\Component\Console\Input\ArgvInput;
require_once __DIR__.'/../vendor/autoload.php';
$input = new ArgvInput();
$output = (false !== $input->getParameterOption(['--no-interaction', '-n'])) ? new ConsoleDatetimeOutput() : null;
$reflection = new \ReflectionClass(AppKernel::class);
$project_dir = dirname($reflection->getFileName(), 2);
$application = include $project_dir.'/app/console-application.php';
$application->run($input, $output);

View File

@@ -0,0 +1,168 @@
{
"name": "mautic/recommended-project",
"description": "Project template for Mautic 7 projects with Composer",
"type": "project",
"license": "GPL-2.0-or-later",
"homepage": "https://www.mautic.org/mautic-releases",
"support": {
"user-docs": "https://docs.mautic.org/en",
"developer-docs": "https://developer.mautic.org",
"chat": "https://www.mautic.org/slack"
},
"funding": [
{
"type": "other",
"url": "https://opencollective.com/mautic"
},
{
"type": "other",
"url": "https://github.com/sponsors/mautic"
}
],
"authors": [
{
"name": "",
"role": ""
}
],
"require": {
"composer/installers": "^2.3",
"mautic/core-composer-scaffold": "1.0.0",
"mautic/core-lib": "7.0.0",
"mautic/core-project-message": "4.x-dev",
"mautic/grapes-js-builder-bundle": "7.0.0",
"mautic/plugin-clearbit": "7.0.0",
"mautic/plugin-cloudstorage": "7.0.0",
"mautic/plugin-crm": "7.0.0",
"mautic/plugin-emailmarketing": "7.0.0",
"mautic/plugin-focus": "7.0.0",
"mautic/plugin-fullcontact": "7.0.0",
"mautic/plugin-gmail": "7.0.0",
"mautic/plugin-outlook": "7.0.0",
"mautic/plugin-social": "7.0.0",
"mautic/plugin-tagmanager": "7.0.0",
"mautic/plugin-zapier": "7.0.0",
"mautic/theme-1-2-1-2-column": "7.0.0",
"mautic/theme-1-2-1-column": "7.0.0",
"mautic/theme-1-2-column": "7.0.0",
"mautic/theme-1-3-1-3-column": "7.0.0",
"mautic/theme-1-3-column": "7.0.0",
"mautic/theme-attract": "7.0.0",
"mautic/theme-aurora": "7.0.0",
"mautic/theme-blank": "7.0.0",
"mautic/theme-blend": "7.0.0",
"mautic/theme-brienz": "7.0.0",
"mautic/theme-capture": "7.0.0",
"mautic/theme-cards": "7.0.0",
"mautic/theme-chord": "7.0.0",
"mautic/theme-confirmme": "7.0.0",
"mautic/theme-connect-through-content": "7.0.0",
"mautic/theme-creative": "7.0.0",
"mautic/theme-eclipse": "7.0.0",
"mautic/theme-educate": "7.0.0",
"mautic/theme-formscape": "7.0.0",
"mautic/theme-fresh-center": "7.0.0",
"mautic/theme-fresh-fixed": "7.0.0",
"mautic/theme-fresh-left": "7.0.0",
"mautic/theme-fresh-wide": "7.0.0",
"mautic/theme-gallery": "7.0.0",
"mautic/theme-goldstar": "7.0.0",
"mautic/theme-make-announcement": "7.0.0",
"mautic/theme-mono": "7.0.0",
"mautic/theme-multi-step": "7.0.0",
"mautic/theme-neopolitan": "7.0.0",
"mautic/theme-oxygen": "7.0.0",
"mautic/theme-paprika": "7.0.0",
"mautic/theme-reachout": "7.0.0",
"mautic/theme-showcase": "7.0.0",
"mautic/theme-simple-text": "7.0.0",
"mautic/theme-skyline": "7.0.0",
"mautic/theme-sparse": "7.0.0",
"mautic/theme-sunday": "7.0.0",
"mautic/theme-survey": "7.0.0",
"mautic/theme-trulypersonal": "7.0.0",
"mautic/theme-vibrant": "7.0.0",
"mautic/theme-welcome": "7.0.0"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/mautic/SymfonyBridgeBundle.git"
}
],
"conflict": {
"mautic/mautic": "*",
"mautic/core": "*"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true,
"allow-plugins": {
"composer/installers": true,
"symfony/flex": true,
"mautic/core-composer-scaffold": true,
"mautic/core-project-message": true,
"php-http/discovery": true
}
},
"autoload": {
"psr-4": {
"MauticPlugin\\": "docroot/plugins/"
}
},
"scripts": {
"post-install-cmd": [
"@npm-ci",
"@npx-patch-package",
"@generate-assets"
],
"post-update-cmd": [
"@npm-ci",
"@npx-patch-package",
"@generate-assets"
],
"npm-ci": "npm ci --prefer-offline --no-audit",
"npx-patch-package": "npx patch-package",
"generate-assets": "@php bin/console mautic:assets:generate"
},
"extra": {
"mautic-scaffold": {
"locations": {
"web-root": "docroot/"
}
},
"installer-paths": {
"docroot/app": [
"type:mautic-core"
],
"docroot/plugins/{$name}": [
"type:mautic-plugin"
],
"docroot/themes/{$name}": [
"type:mautic-theme"
]
},
"mautic-core-project-message": {
"include-keys": [
"homepage",
"support"
],
"post-create-project-cmd-message": [
"<bg=blue;fg=white> </>",
"<bg=blue;fg=white> Congratulations, youve installed the Mautic codebase </>",
"<bg=blue;fg=white> from the mautic/recommended-project template! </>",
"<bg=blue;fg=white> </>",
"",
"<bg=yellow;fg=black>Next steps</>:",
" * Install Mautic",
" * Read the user guide",
" * Get support: https://www.mautic.org/support",
" * Get involved with the Mautic community:",
" https://www.mautic.org/getting-involved",
" * Remove the plugin that prints this message:",
" composer remove mautic/core-project-message"
]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
gitkeep file

View File

@@ -0,0 +1,149 @@
# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
#DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
# Set Authorization header for OAuth2 for when php is running under fcgi
RewriteCond %{HTTP:Authorization} .+
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Determine the RewriteBase automatically and set it as environment variable.
# If you are using Apache aliases to do mass virtual hosting or installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the app.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/app.php`). Only do this redirect on the initial
# rewrite by Apache and not on subsequent cycles. Otherwise we would get an
# endless redirect loop (request -> rewrite to front controller ->
# redirect -> request -> ...).
# So in case you get a "too many redirects" error or you always get redirected
# to the start page because your Apache does not expose the REDIRECT_STATUS
# environment variable, you have 2 choices:
# - disable this feature by commenting the following 2 lines or
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/index.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 302 ^(?!/(index\.php|app|addons|plugins|media|upgrade))(/(.*))$ /index.php$2
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
<IfModule mod_php5.c>
# @link https://github.com/mautic/mautic/issues/1504
php_value always_populate_raw_post_data -1
</IfModule>
<IfModule mod_deflate.c>
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
# Do not enable compression for file types that could contain secrets
#AddOutputFilterByType DEFLATE text/html
#AddOutputFilterByType DEFLATE text/plain
#AddOutputFilterByType DEFLATE text/xml
#AddOutputFilterByType DEFLATE application/xhtml+xml
#AddOutputFilterByType DEFLATE application/xml
#AddOutputFilterByType DEFLATE application/json
<IfModule mod_setenvif.c>
<IfModule mod_header.c>
# Remove browser bugs (only needed for really old browsers)
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent
</IfModule>
</IfModule>
</IfModule>
</IfModule>
# Apache 2.4+
<IfModule authz_core_module>
# Deny access via HTTP requests to all .env files.
<FilesMatch "^\.env.*$">
Require all denied
</FilesMatch>
# Deny access via HTTP requests to all PHP files.
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
# Deny access via HTTP requests to composer files.
<FilesMatch "^(composer\.json|composer\.lock)$">
Require all denied
</FilesMatch>
# Except those allowed below.
<If "%{REQUEST_URI} =~ m#^/(index|upgrade/upgrade)\.php#">
Require all granted
</If>
</IfModule>
# Fallback for Apache < 2.4
<IfModule !authz_core_module>
# Deny access via HTTP requests to all .env files.
<FilesMatch "^\.env.*$">
Order deny,allow
Deny from all
</FilesMatch>
# Deny access via HTTP requests to all PHP files.
<FilesMatch "\.php$">
Order deny,allow
Deny from all
</FilesMatch>
# Deny access via HTTP requests to composer files
<FilesMatch "^(composer\.json|composer\.lock)$">
Order deny,allow
Deny from all
</FilesMatch>
# Except those allowed below.
<If "%{REQUEST_URI} =~ m#^/(index|upgrade/upgrade)\.php#">
Order allow,deny
Allow from all
</If>
</IfModule>

View File

@@ -0,0 +1,26 @@
# Workflow name:
name: Close Pull Requests
# Workflow triggers:
on:
pull_request_target:
types: [opened]
# Workflow jobs:
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thank you for submitting a pull request. :raised_hands:
We greatly appreciate your willingness to submit a contribution. However, we are not accepting pull requests against this repository, as all development happens on the [main project repository](https://github.com/mautic/mautic).
We kindly request that you submit this pull request against the [respective directory](https://github.com/mautic/mautic/blob/head/app/) of the main repository where we'll review and provide feedback. If this is your first Mautic contribution, be sure to read the [contributing guide](https://github.com/mautic/mautic/blob/head/.github/CONTRIBUTING.md) which provides guidelines and instructions for submitting contributions.
Thank you again, and we look forward to receiving your contribution! :smiley:
Best,
The Mautic team

View File

@@ -0,0 +1 @@
deny from all

View File

@@ -0,0 +1,351 @@
<?php
use Mautic\CoreBundle\Loader\ParameterLoader;
use Mautic\CoreBundle\Release\ThisRelease;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Kernel;
/**
* Mautic Application Kernel.
*/
class AppKernel extends Kernel
{
/**
* @var bool|null
*/
private $installed;
/**
* @var ParameterLoader|null
*/
private $parameterLoader;
/**
* @var string
*/
private $projectDir;
/**
* @param string $environment The environment
* @param bool $debug Whether to enable debugging or not
*
* @api
*/
public function __construct($environment, $debug)
{
$metadata = ThisRelease::getMetadata();
defined('MAUTIC_ENV') or define('MAUTIC_ENV', $environment);
defined('MAUTIC_VERSION') or define('MAUTIC_VERSION', $metadata->getVersion());
/**
* This is required for Doctrine's automatic database detection. When Mautic hasn't been
* installed yet, we don't have a database to connect to, causing automatic database platform
* detection to fail. We use the MAUTIC_DB_SERVER_VERSION constant to temporarily set a server_version
* if no database settings have been provided yet.
*/
if (!defined('MAUTIC_DB_SERVER_VERSION')) {
$localConfigFile = ParameterLoader::getLocalConfigFile($this->getApplicationDir().'/app', false);
define('MAUTIC_DB_SERVER_VERSION', file_exists($localConfigFile) ? null : '8.4');
}
parent::__construct($environment, $debug);
}
public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUEST, $catch = true): Response
{
if (false !== strpos($request->getRequestUri(), 'installer') || !$this->isInstalled()) {
defined('MAUTIC_INSTALLER') or define('MAUTIC_INSTALLER', 1);
}
if (defined('MAUTIC_INSTALLER')) {
$uri = $request->getRequestUri();
if (false === strpos($uri, 'installer')) {
$base = $request->getBaseUrl();
$prefix = '';
// check to see if the .htaccess file exists or if not running under apache
if (false === stripos($request->server->get('SERVER_SOFTWARE', ''), 'apache')
|| !file_exists($this->getProjectDir().'/.htaccess')
&& false === strpos(
$base,
'index'
)
) {
$prefix .= '/index.php';
}
return new RedirectResponse($request->getUriForPath($prefix.'/installer'));
}
}
if (false === $this->booted) {
$this->boot();
}
// Check for an an active db connection and die with error if unable to connect
if (!defined('MAUTIC_INSTALLER')) {
$db = $this->getContainer()->get('database_connection');
try {
$db->connect();
} catch (Exception $e) {
error_log($e);
throw new Mautic\CoreBundle\Exception\DatabaseConnectionException($this->getContainer()->get('translator')->trans('mautic.core.db.connection.error', ['%code%' => $e->getCode()]), 0, $e);
}
}
return parent::handle($request, $type, $catch);
}
public function registerBundles(): iterable
{
$bundles = [
// Symfony/Core Bundles
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new FOS\OAuthServerBundle\FOSOAuthServerBundle(),
new FOS\RestBundle\FOSRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Oneup\UploaderBundle\OneupUploaderBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new LightSaml\SymfonyBridgeBundle\LightSamlSymfonyBridgeBundle(),
new LightSaml\SpBundle\LightSamlSpBundle(),
new FM\ElfinderBundle\FMElfinderBundle(),
new Exercise\HTMLPurifierBundle\ExerciseHTMLPurifierBundle(),
new ApiPlatform\Symfony\Bundle\ApiPlatformBundle(),
// Mautic Bundles
new Mautic\ApiBundle\MauticApiBundle(),
new Mautic\AssetBundle\MauticAssetBundle(),
new Mautic\CampaignBundle\MauticCampaignBundle(),
new Mautic\CategoryBundle\MauticCategoryBundle(),
new Mautic\ChannelBundle\MauticChannelBundle(),
new Mautic\ConfigBundle\MauticConfigBundle(),
new Mautic\CoreBundle\MauticCoreBundle(),
new Mautic\DashboardBundle\MauticDashboardBundle(),
new Mautic\DynamicContentBundle\MauticDynamicContentBundle(),
new Mautic\EmailBundle\MauticEmailBundle(),
new Mautic\FormBundle\MauticFormBundle(),
new Mautic\InstallBundle\MauticInstallBundle(),
new Mautic\IntegrationsBundle\IntegrationsBundle(),
new Mautic\LeadBundle\MauticLeadBundle(),
new Mautic\MarketplaceBundle\MarketplaceBundle(),
new Mautic\MessengerBundle\MauticMessengerBundle(),
new Mautic\NotificationBundle\MauticNotificationBundle(),
new Mautic\PageBundle\MauticPageBundle(),
new Mautic\PluginBundle\MauticPluginBundle(),
new Mautic\PointBundle\MauticPointBundle(),
new Mautic\ProjectBundle\MauticProjectBundle(),
new Mautic\ReportBundle\MauticReportBundle(),
new Mautic\SmsBundle\MauticSmsBundle(),
new Mautic\StageBundle\MauticStageBundle(),
new Mautic\StatsBundle\MauticStatsBundle(),
new Mautic\UserBundle\MauticUserBundle(),
new Mautic\WebhookBundle\MauticWebhookBundle(),
new Mautic\CacheBundle\MauticCacheBundle(),
];
// dynamically register Mautic Plugin Bundles
$searchPath = $this->getApplicationDir().'/plugins';
$finder = new Symfony\Component\Finder\Finder();
$finder->files()
->followLinks()
->depth('1')
->in($searchPath)
->name('*Bundle.php');
foreach ($finder as $file) {
$dirname = basename($file->getRelativePath());
$filename = substr($file->getFilename(), 0, -4);
$class = '\\MauticPlugin\\'.$dirname.'\\'.$filename;
if (class_exists($class)) {
$plugin = new $class();
if ($plugin instanceof Symfony\Component\HttpKernel\Bundle\Bundle) {
if (defined($class.'::MINIMUM_MAUTIC_VERSION')) {
// Check if this version supports the plugin before loading it
if (version_compare($this->getVersion(), constant($class.'::MINIMUM_MAUTIC_VERSION'), 'lt')) {
continue;
}
}
$bundles[] = $plugin;
}
unset($plugin);
}
}
if (in_array($this->getEnvironment(), ['dev', 'test'])) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Symfony\Bundle\MakerBundle\MakerBundle();
}
if (in_array($this->getEnvironment(), ['test'])) {
$bundles[] = new Liip\FunctionalTestBundle\LiipFunctionalTestBundle();
$bundles[] = new Liip\TestFixturesBundle\LiipTestFixturesBundle();
}
// Check for local bundle inclusion
if (file_exists($this->getProjectDir().'/config/bundles_local.php')) {
include $this->getProjectDir().'/config/bundles_local.php';
}
return $bundles;
}
protected function build(ContainerBuilder $container): void
{
$container->registerForAutoconfiguration(Mautic\CoreBundle\Model\MauticModelInterface::class)
->addTag(Mautic\CoreBundle\DependencyInjection\Compiler\ModelPass::TAG);
}
public function boot(): void
{
if (true === $this->booted) {
return;
}
// load parameters with defaults into the environment
$parameterLoader = $this->getParameterLoader();
$parameterLoader->loadIntoEnvironment();
if (!defined('MAUTIC_TABLE_PREFIX')) {
// Set the table prefix before boot.
// Firstly look into environment variables.
$prefix = $_SERVER['MAUTIC_TABLE_PREFIX'];
// Secondly look into the local.php file.
if (empty($prefix)) {
$prefix = $parameterLoader->getLocalParameterBag()->get('db_table_prefix', '');
}
define('MAUTIC_TABLE_PREFIX', $prefix);
}
// init bundles
$this->initializeBundles();
// init container
$this->initializeContainer();
// boot bundles
foreach ($this->getBundles() as $name => $bundle) {
$bundle->setContainer($this->container);
$bundle->boot();
}
$this->booted = true;
}
protected function prepareContainer(ContainerBuilder $container): void
{
$container->setParameter('mautic.application_dir', $this->getApplicationDir());
parent::prepareContainer($container);
}
public function registerContainerConfiguration(LoaderInterface $loader): void
{
$loader->load($this->getApplicationDir().'/app/config/config_'.$this->getEnvironment().'.php');
}
/**
* Retrieves the application's version number.
*/
public function getVersion(): string
{
return MAUTIC_VERSION;
}
/**
* Checks if the application has been installed.
*/
protected function isInstalled(): bool
{
if (null === $this->installed) {
$localParameters = $this->getParameterLoader()->getLocalParameterBag();
$dbDriver = $localParameters->get('db_driver');
$siteUrl = $localParameters->get('site_url');
$this->installed = !empty($dbDriver) && !empty($siteUrl);
}
return $this->installed;
}
public function getApplicationDir(): string
{
return dirname(__DIR__);
}
public function getProjectDir(): string
{
if (null === $this->projectDir) {
$r = new ReflectionObject($this);
if (!is_file($dir = $r->getFileName())) {
throw new LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name));
}
// We need 1 level deeper than the parent method, as the app folder contains a composer.json file
$dir = $rootDir = \dirname($dir, 2);
while (!is_file($dir.'/composer.json')) {
if ($dir === \dirname($dir)) {
return $this->projectDir = $rootDir;
}
$dir = \dirname($dir);
}
$this->projectDir = $dir;
}
return $this->projectDir;
}
/**
* @api
*/
public function getCacheDir(): string
{
if ($cachePath = $this->getParameterLoader()->getLocalParameterBag()->get('cache_path')) {
$envFolder = ('/' != substr($cachePath, -1)) ? '/'.$this->environment : $this->environment;
return str_replace('%kernel.project_dir%', $this->getProjectDir(), $cachePath.$envFolder);
}
return $this->getProjectDir().'/var/cache/'.$this->getEnvironment();
}
public function getLogDir(): string
{
if ($logPath = $this->getParameterLoader()->getLocalParameterBag()->get('log_path')) {
return str_replace('%kernel.project_dir%', $this->getProjectDir(), $logPath);
}
return $this->getProjectDir().'/var/logs';
}
/**
* Get local config file.
*/
public function getLocalConfigFile(): string
{
return ParameterLoader::getLocalConfigFile($this->getApplicationDir().'/app');
}
private function getParameterLoader(): ParameterLoader
{
if ($this->parameterLoader) {
return $this->parameterLoader;
}
return $this->parameterLoader = new ParameterLoader();
}
}

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
use Symfony\Component\DependencyInjection\ContainerInterface;
class AppTestKernel extends AppKernel
{
private bool $isTestContainerSet = false;
/**
* {@inheritdoc}
*/
protected function isInstalled(): bool
{
return true;
}
public function getCacheDir(): string
{
if ($dir = getenv('TEST_CACHE_DIR')) {
return dirname(__DIR__).'/'.$dir;
}
return parent::getCacheDir();
}
public function getLogDir(): string
{
if ($dir = getenv('TEST_LOG_DIR')) {
return dirname(__DIR__).'/'.$dir;
}
return parent::getLogDir();
}
/**
* @throws Exception
*/
public function getContainer(): ContainerInterface
{
if (!$this->container) {
$this->boot();
}
if ($this->isTestContainerSet) {
return $this->container;
}
$this->isTestContainerSet = true;
$testContainer = $this->container->get('test.service_container');
$testContainer->setPublicContainer($this->container);
return $this->container;
}
}

View File

@@ -0,0 +1,5 @@
# Mautic Core-lib repo
## This is a mirror repository of the /app folder of Mautic, and is managed centrally in https://github.com/mautic/mautic/blob/head/app. This is a read-only mirror repository.
**📣 Please make PRs and issues against the [mautic/mautic](https://github.com/mautic/mautic) repository, not here!**

View File

@@ -0,0 +1 @@
allow from all

View File

@@ -0,0 +1,172 @@
/* Modal Base CSS */
.mauticForm-overlay
{
position: fixed;
z-index: 9998;
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100%;
-webkit-transition: 1ms opacity ease;
-moz-transition: 1ms opacity ease;
-ms-transition: 1ms opacity ease;
-o-transition: 1ms opacity ease;
transition: 1ms opacity ease;
background: rgba(0,0,0,.6);
}
.mauticForm-modal
{
position: absolute;
z-index: 9999;
top: 50%;
left: 50%;
opacity: 0;
width: 94%;
padding: 24px 20px;
-webkit-transition: 1ms opacity ease;
-moz-transition: 1ms opacity ease;
-ms-transition: 1ms opacity ease;
-o-transition: 1ms opacity ease;
transition: 1ms opacity ease;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border-radius: 2px;
background: #fff;
}
.mauticForm-modal.mauticForm-open.mauticForm-anchored
{
top: 20px;
-webkit-transform: translate(-50%, 0);
-moz-transform: translate(-50%, 0);
-ms-transform: translate(-50%, 0);
-o-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
.mauticForm-modal.mauticForm-open
{
opacity: 1;
}
.mauticForm-overlay.mauticForm-open
{
opacity: 1;
}
/* Close Button */
.mauticForm-close
{
font-family: Helvetica,Arial,sans-serif;
font-size: 24px;
font-weight: 700;
line-height: 12px;
position: absolute;
top: 5px;
right: 5px;
padding: 5px 7px 7px;
cursor: pointer;
color: #fff;
border: 0;
outline: none;
background: #e74c3c;
}
.mauticForm-close:hover
{
background: #c0392b;
}
/* Default Animation */
.mauticForm-overlay.fade-and-drop
{
display: block;
opacity: 0;
}
.mauticForm-modal.fade-and-drop
{
top: -300%;
opacity: 1;
display: block;
}
.mauticForm-modal.fade-and-drop.mauticForm-open
{
top: 50%;
-webkit-transition: 500ms top 500ms ease;
-moz-transition: 500ms top 500ms ease;
-ms-transition: 500ms top 500ms ease;
-o-transition: 500ms top 500ms ease;
transition: 500ms top 500ms ease;
}
.mauticForm-modal.fade-and-drop.mauticForm-open.mauticForm-anchored
{
-webkit-transition: 500ms top 500ms ease;
-moz-transition: 500ms top 500ms ease;
-ms-transition: 500ms top 500ms ease;
-o-transition: 500ms top 500ms ease;
transition: 500ms top 500ms ease;
}
.mauticForm-overlay.fade-and-drop.mauticForm-open
{
top: 0;
-webkit-transition: 500ms opacity ease;
-moz-transition: 500ms opacity ease;
-ms-transition: 500ms opacity ease;
-o-transition: 500ms opacity ease;
transition: 500ms opacity ease;
opacity: 1;
}
.mauticForm-modal.fade-and-drop
{
-webkit-transition: 500ms top ease;
-moz-transition: 500ms top ease;
-ms-transition: 500ms top ease;
-o-transition: 500ms top ease;
transition: 500ms top ease;
}
.mauticForm-overlay.fade-and-drop
{
-webkit-transition: 500ms opacity 500ms ease;
-moz-transition: 500ms opacity 500ms ease;
-ms-transition: 500ms opacity 500ms ease;
-o-transition: 500ms opacity 500ms ease;
transition: 500ms opacity 500ms ease;
}
.mauticForm-content {
height: 100%;
}

View File

@@ -0,0 +1,140 @@
{
"name": "Engagement",
"description": "Start with a dashboard of 13 widgets that provide insights into lead generation, engagement, email interactions, and contact management.",
"widgets": [
{
"name": "Contacts created",
"width": 100,
"height": 330,
"ordering": 0,
"type": "created.leads.in.time",
"params": {
"lists": "identifiedVsAnonymous",
"flag": null
},
"template": null
},
{
"name": "Visits",
"width": 50,
"height": 330,
"ordering": 1,
"type": "page.hits.in.time",
"params": {
"flag": null
},
"template": null
},
{
"name": "Contact map",
"width": 50,
"height": 330,
"ordering": 3,
"type": "map.of.leads",
"params": [
],
"template": null
},
{
"name": "Emails sent \/ opened",
"width": 50,
"height": 330,
"ordering": 5,
"type": "emails.in.time",
"params": {
"flag": null
},
"template": null
},
{
"name": "Points",
"width": 50,
"height": 330,
"ordering": 6,
"type": "points.in.time",
"params": [
],
"template": null
},
{
"name": "Unique\/returning visitors",
"width": 25,
"height": 330,
"ordering": 7,
"type": "unique.vs.returning.leads",
"params": [
],
"template": null
},
{
"name": "Identified vs anonymous leads",
"width": 25,
"height": 330,
"ordering": 8,
"type": "anonymous.vs.identified.leads",
"params": [
],
"template": null
},
{
"name": "Ignored\/opened emails",
"width": 25,
"height": 330,
"ordering": 9,
"type": "ignored.vs.read.emails",
"params": [
],
"template": null
},
{
"name": "Upcoming Emails",
"width": 25,
"height": 330,
"ordering": 10,
"type": "upcoming.emails",
"params": [
],
"template": null
},
{
"name": "Top Contact Creators",
"width": 100,
"height": 330,
"ordering": 11,
"type": "top.creators",
"params": [
],
"template": null
},
{
"name": "Dwell times",
"width": 25,
"height": 330,
"ordering": 12,
"type": "dwell.times",
"params": [
],
"template": null
},
{
"name": "Recent activity",
"width": 50,
"height": 330,
"ordering": 13,
"type": "recent.activity",
"params": [
],
"template": null
},
{
"name": "Top lists",
"width": 25,
"height": 330,
"ordering": 14,
"type": "top.lists",
"params": [
],
"template": null
}
]
}

View File

@@ -0,0 +1,48 @@
{
"name": "Default",
"description": "Start with a dashboard of 5 widgets that provide an overview of your marketing activities and performance metrics.",
"widgets":
[
{
"name": "Contacts Created",
"width": 100,
"height": 330,
"ordering": 0,
"type": "created.leads.in.time",
"params": {
"lists": "identifiedVsAnonymous"
}
},
{
"name": "Page Visits",
"width": 50,
"height": 330,
"ordering": 1,
"type": "page.hits.in.time",
"params": {
"flag": "unique"
}
},
{
"name": "Form Submissions",
"width": 50,
"height": 330,
"ordering": 2,
"type": "submissions.in.time"
},
{
"name": "Recent Activity",
"width": 50,
"height": 330,
"ordering": 3,
"type": "recent.activity"
},
{
"name": "Upcoming Emails",
"width": 50,
"height": 330,
"ordering": 4,
"type": "upcoming.emails"
}
]
}

View File

@@ -0,0 +1,74 @@
{
"name": "Example - Email Overview",
"description": "Start with a dashboard of 7 widgets that provide insights into email interactions and contact management.",
"widgets": [
{
"name": "Emails sent \/ opened",
"width": 100,
"height": 330,
"ordering": 0,
"type": "emails.in.time",
"params": {
"flag": "sent_and_opened"
},
"template": null
},
{
"name": "Upcoming emails",
"width": 25,
"height": 330,
"ordering": 1,
"type": "upcoming.emails",
"params": [],
"template": null
},
{
"name": "Ignored\/opened emails",
"width": 25,
"height": 330,
"ordering": 2,
"type": "ignored.vs.read.emails",
"params": [],
"template": null
},
{
"name": "Most sent emails",
"width": 25,
"height": 330,
"ordering": 3,
"type": "most.sent.emails",
"params": [],
"template": null
},
{
"name": "Most read emails",
"width": 25,
"height": 330,
"ordering": 4,
"type": "most.read.emails",
"params": [],
"template": null
},
{
"name": "Contact map",
"width": 50,
"height": 330,
"ordering": 5,
"type": "map.of.leads",
"params": [],
"template": null
},
{
"name": "Contacts created",
"width": 50,
"height": 330,
"ordering": 6,
"type": "created.leads.in.time",
"params": {
"lists": "identifiedVsAnonymous",
"flag": null
},
"template": null
}
]
}

View File

@@ -0,0 +1,138 @@
{
"name": "Forms and Assets",
"description": "Start with a dashboard of 14 widgets that help you to check form submissions and identified contacts.",
"widgets": [
{
"name": "Contacts Created",
"width": 100,
"height": 330,
"ordering": 0,
"type": "created.leads.in.time",
"params": {
"lists": "identifiedVsAnonymous"
},
"template": null
},
{
"name": "Created contacts in time",
"width": 100,
"height": 215,
"ordering": 0,
"type": "created.leads.in.time",
"params": {
"flag": "identified"
},
"template": null
},
{
"name": "Page Visits",
"width": 50,
"height": 330,
"ordering": 1,
"type": "page.hits.in.time",
"params": {
"flag": "unique"
},
"template": null
},
{
"name": "Top segments",
"width": 50,
"height": 215,
"ordering": 1,
"type": "top.lists",
"params": [],
"template": null
},
{
"name": "Created contacts",
"width": 50,
"height": 215,
"ordering": 2,
"type": "created.leads",
"params": [],
"template": null
},
{
"name": "Form Submissions",
"width": 50,
"height": 330,
"ordering": 3,
"type": "submissions.in.time",
"params": [],
"template": null
},
{
"name": "Recent Activity",
"width": 50,
"height": 330,
"ordering": 3,
"type": "recent.activity",
"params": [],
"template": null
},
{
"name": "Upcoming Emails",
"width": 50,
"height": 330,
"ordering": 4,
"type": "upcoming.emails",
"params": [],
"template": null
},
{
"name": "Top submission referrers",
"width": 25,
"height": 330,
"ordering": 4,
"type": "top.submission.referrers",
"params": [],
"template": null
},
{
"name": "Created forms",
"width": 25,
"height": 330,
"ordering": 5,
"type": "created.forms",
"params": [],
"template": null
},
{
"name": "Downloads in time",
"width": 25,
"height": 330,
"ordering": 6,
"type": "asset.downloads.in.time",
"params": [],
"template": null
},
{
"name": "Popular assets",
"width": 25,
"height": 330,
"ordering": 7,
"type": "popular.assets",
"params": [],
"template": null
},
{
"name": "Unique vs repetitive downloads",
"width": 25,
"height": 330,
"ordering": 8,
"type": "unique.vs.repetitive.downloads",
"params": [],
"template": null
},
{
"name": "Created assets",
"width": 25,
"height": 330,
"ordering": 9,
"type": "created.assets",
"params": [],
"template": null
}
]
}

View File

@@ -0,0 +1,109 @@
{
"name": "Landing pages",
"description": "Start with a dashboard of 11 widgets that provide insights related to landing pages and interactions.",
"widgets": [
{
"name": "Contacts Created",
"width": 100,
"height": 215,
"ordering": 0,
"type": "created.leads.in.time",
"params": {
"lists": "identifiedVsAnonymous"
},
"template": null
},
{
"name": "Page visits in time",
"width": 50,
"height": 215,
"ordering": 1,
"type": "page.hits.in.time",
"params": {
"flag": ""
},
"template": null
},
{
"name": "Downloads in time",
"width": 50,
"height": 215,
"ordering": 2,
"type": "asset.downloads.in.time",
"params": [],
"template": null
},
{
"name": "Unique vs returning visitors",
"width": 50,
"height": 330,
"ordering": 4,
"type": "unique.vs.returning.leads",
"params": [],
"template": null
},
{
"name": "Upcoming Emails",
"width": 50,
"height": 330,
"ordering": 4,
"type": "upcoming.emails",
"params": [],
"template": null
},
{
"name": "Dwell times",
"width": 50,
"height": 330,
"ordering": 5,
"type": "dwell.times",
"params": [],
"template": null
},
{
"name": "Popular landing pages",
"width": 25,
"height": 330,
"ordering": 6,
"type": "popular.pages",
"params": [],
"template": null
},
{
"name": "Created Landing pages",
"width": 25,
"height": 330,
"ordering": 7,
"type": "created.pages",
"params": [],
"template": null
},
{
"name": "Device granularity",
"width": 25,
"height": 330,
"ordering": 8,
"type": "device.granularity",
"params": [],
"template": null
},
{
"name": "Popular assets",
"width": 25,
"height": 330,
"ordering": 9,
"type": "popular.assets",
"params": [],
"template": null
},
{
"name": "Form Submissions",
"width": 50,
"height": 330,
"ordering": 11,
"type": "submissions.in.time",
"params": [],
"template": null
}
]
}

View File

@@ -0,0 +1,103 @@
{
"name": "Example - Stats Overview",
"description": "Start with a dashboard of 10 widgets that provide statistic about lead generation, engagement, and email interactions.",
"widgets": [
{
"name": "Contacts created",
"width": 50,
"height": 330,
"ordering": 0,
"type": "created.leads.in.time",
"params": {
"lists": "identifiedVsAnonymous",
"flag": null
},
"template": null
},
{
"name": "Visits",
"width": 50,
"height": 330,
"ordering": 1,
"type": "page.hits.in.time",
"params": {
"flag": null
},
"template": null
},
{
"name": "Points",
"width": 50,
"height": 330,
"ordering": 3,
"type": "points.in.time",
"params": [],
"template": null
},
{
"name": "Downloads in time",
"width": 50,
"height": 330,
"ordering": 4,
"type": "asset.downloads.in.time",
"params": [],
"template": null
},
{
"name": "Emails sent \/ opened",
"width": 50,
"height": 330,
"ordering": 5,
"type": "emails.in.time",
"params": {
"flag": null
},
"template": null
},
{
"name": "Submissions in time",
"width": 50,
"height": 330,
"ordering": 6,
"type": "submissions.in.time",
"params": [],
"template": null
},
{
"name": "Identified vs anonymous leads",
"width": 25,
"height": 330,
"ordering": 7,
"type": "anonymous.vs.identified.leads",
"params": [],
"template": null
},
{
"name": "Ignored\/opened emails",
"width": 25,
"height": 330,
"ordering": 8,
"type": "ignored.vs.read.emails",
"params": [],
"template": null
},
{
"name": "Unique\/returning visitors",
"width": 25,
"height": 330,
"ordering": 9,
"type": "unique.vs.returning.leads",
"params": [],
"template": null
},
{
"name": "Dwell times",
"width": 25,
"height": 330,
"ordering": 11,
"type": "dwell.times",
"params": [],
"template": null
}
]
}

View File

@@ -0,0 +1,16 @@
<IfModule mod_php4.c>
php_flag engine Off
</IfModule>
<IfModule mod_php5.c>
php_flag engine Off
</IfModule>
<IfModule mod_php6.c>
php_flag engine Off
</IfModule>
<IfModule mod_cgi.c>
Options -ExecCGI
</IfModule>
RemoveHandler .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc
RemoveType .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc
SetHandler None
SetHandler default-handler

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More