<commit_before><?php

namespace Backend\Modules\Extensions\Engine;

use Backend\Core\Engine\Authentication as BackendAuthentication;
use Backend\Core\Engine\DataGridFunctions as BackendDataGridFunctions;
use Backend\Core\Engine\Exception;
use Backend\Core\Engine\Model as BackendModel;
use Backend\Core\Language\Language as BL;
use Backend\Modules\Locale\Engine\Model as BackendLocaleModel;
use Backend\Modules\Pages\Domain\ModuleExtra\ModuleExtraRepository;
use Backend\Modules\Pages\Domain\ModuleExtra\ModuleExtraType;
use Backend\Modules\Pages\Domain\PageBlock\PageBlockRepository;
use Common\ModulesSettings;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;

/**
 * In this file we store all generic functions that we will be using in the extensions module.
 */
class Model
{
    /**
     * Overview of templates.
     *
     * @var string
     */
    const QUERY_BROWSE_TEMPLATES = 'SELECT i.id, i.label AS title
                                  FROM themes_templates AS i
                                  WHERE i.theme = ?
                                  ORDER BY i.label ASC';

    /**
     * Modules which are part of the core and can not be managed.
     *
     * @var array
     */
    private static $ignoredModules = [
        'Authentication',
        'Dashboard',
        'Error',
        'Extensions',
        'Settings',
    ];

    /**
     * Build HTML for a template (visual representation)
     *
     * @param string $format The template format.
     * @param bool $large Will the HTML be used in a large version?
     *
     * @return string
     */
    public static function buildTemplateHTML(string $format, bool $large = false): string
    {
        // cleanup
        $table = self::templateSyntaxToArray($format);

        // init var
        $rows = count($table);
        if ($rows === 0) {
            throw new Exception('Invalid template-format.');
        }
        $cells = count($table[0]);

        $htmlContent = [];

        // loop rows
        for ($y = 0; $y < $rows; ++$y) {
            $htmlContent[$y] = [];

            // loop cells
            for ($x = 0; $x < $cells; ++$x) {
                // skip if needed
                if (!isset($table[$y][$x])) {
                    continue;
                }

                // get value
                $value = $table[$y][$x];

                // init var
                $colspan = 1;

                // reset items in the same column
                while ($x + $colspan < $cells && $table[$y][$x + $colspan] === $value) {
                    $table[$y][$x + $colspan++] = null;
                }

                // init var
                $rowspan = 1;
                $rowMatches = true;

                // loop while the rows match
                while ($rowMatches && $y + $rowspan < $rows) {
                    // loop columns inside spanned columns
                    for ($i = 0; $i < $colspan; ++$i) {
                        // check value
                        if ($table[$y + $rowspan][$x + $i] !== $value) {
                            // no match, so stop
                            $rowMatches = false;
                            break;
                        }
                    }

                    // any rowmatches?
                    if ($rowMatches) {
                        // loop columns and reset value
                        for ($i = 0; $i < $colspan; ++$i) {
                            $table[$y + $rowspan][$x + $i] = null;
                        }

                        // increment
                        ++$rowspan;
                    }
                }

                $htmlContent[$y][$x] = [
                    'title' => \SpoonFilter::ucfirst($value),
                    'value' => $value,
                    'exists' => $value != '/',
                    'rowspan' => $rowspan,
                    'colspan' => $colspan,
                    'large' => $large,
                ];
            }
        }

        $templating = BackendModel::get('template');
        $templating->assign('table', $htmlContent);
        $html = $templating->getContent('Extensions/Layout/Templates/Templates.html.twig');

        return $html;
    }

    /**
     * Checks the settings and optionally returns an array with warnings
     *
     * @return array
     */
    public static function checkSettings(): array
    {
        $warnings = [];
        $akismetModules = self::getModulesThatRequireAkismet();
        $googleMapsModules = self::getModulesThatRequireGoogleMaps();

        // check if this action is allowed
        if (!BackendAuthentication::isAllowedAction('Index', 'Settings')) {
            return [];
        }

        // check if the akismet key is available if there are modules that require it
        if (!empty($akismetModules) && BackendModel::get('fork.settings')->get('Core', 'akismet_key', null) == '') {
            // add warning
            $warnings[] = [
                'message' => sprintf(
                    BL::err('AkismetKey'),
                    BackendModel::createUrlForAction('Index', 'Settings')
                ),
            ];
        }

        // check if the google maps key is available if there are modules that require it
        if (!empty($googleMapsModules)
            && BackendModel::get('fork.settings')->get('Core', 'google_maps_key', null) == '') {
            // add warning
            $warnings[] = [
                'message' => sprintf(
                    BL::err('GoogleMapsKey'),
                    BackendModel::createUrlForAction('Index', 'Settings')
                ),
            ];
        }

        return $warnings;
    }

    /**
     * Clear all applications cache.
     *
     * Note: we do not need to rebuild anything, the core will do this when noticing the cache files are missing.
     */
    public static function clearCache(): void
    {
        $finder = new Finder();
        $filesystem = new Filesystem();
        $files = $finder->files()
            ->name('*.php')
            ->name('*.js')
            ->in(BACKEND_CACHE_PATH . '/Locale')
            ->in(FRONTEND_CACHE_PATH . '/Navigation')
            ->in(FRONTEND_CACHE_PATH . '/Locale');
        foreach ($files as $file) {
            $filesystem->remove($file->getRealPath());
        }
        BackendModel::getContainer()->get('cache.backend_navigation')->delete();
    }<commit_msg>Better link to the api key settings<commit_after><?php

namespace Backend\Modules\Extensions\Engine;

use Backend\Core\Engine\Authentication as BackendAuthentication;
use Backend\Core\Engine\DataGridFunctions as BackendDataGridFunctions;
use Backend\Core\Engine\Exception;
use Backend\Core\Engine\Model as BackendModel;
use Backend\Core\Language\Language as BL;
use Backend\Modules\Locale\Engine\Model as BackendLocaleModel;
use Backend\Modules\Pages\Domain\ModuleExtra\ModuleExtraRepository;
use Backend\Modules\Pages\Domain\ModuleExtra\ModuleExtraType;
use Backend\Modules\Pages\Domain\PageBlock\PageBlockRepository;
use Common\ModulesSettings;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;

/**
 * In this file we store all generic functions that we will be using in the extensions module.
 */
class Model
{
    /**
     * Overview of templates.
     *
     * @var string
     */
    const QUERY_BROWSE_TEMPLATES = 'SELECT i.id, i.label AS title
                                  FROM themes_templates AS i
                                  WHERE i.theme = ?
                                  ORDER BY i.label ASC';

    /**
     * Modules which are part of the core and can not be managed.
     *
     * @var array
     */
    private static $ignoredModules = [
        'Authentication',
        'Dashboard',
        'Error',
        'Extensions',
        'Settings',
    ];

    /**
     * Build HTML for a template (visual representation)
     *
     * @param string $format The template format.
     * @param bool $large Will the HTML be used in a large version?
     *
     * @return string
     */
    public static function buildTemplateHTML(string $format, bool $large = false): string
    {
        // cleanup
        $table = self::templateSyntaxToArray($format);

        // init var
        $rows = count($table);
        if ($rows === 0) {
            throw new Exception('Invalid template-format.');
        }
        $cells = count($table[0]);

        $htmlContent = [];

        // loop rows
        for ($y = 0; $y < $rows; ++$y) {
            $htmlContent[$y] = [];

            // loop cells
            for ($x = 0; $x < $cells; ++$x) {
                // skip if needed
                if (!isset($table[$y][$x])) {
                    continue;
                }

                // get value
                $value = $table[$y][$x];

                // init var
                $colspan = 1;

                // reset items in the same column
                while ($x + $colspan < $cells && $table[$y][$x + $colspan] === $value) {
                    $table[$y][$x + $colspan++] = null;
                }

                // init var
                $rowspan = 1;
                $rowMatches = true;

                // loop while the rows match
                while ($rowMatches && $y + $rowspan < $rows) {
                    // loop columns inside spanned columns
                    for ($i = 0; $i < $colspan; ++$i) {
                        // check value
                        if ($table[$y + $rowspan][$x + $i] !== $value) {
                            // no match, so stop
                            $rowMatches = false;
                            break;
                        }
                    }

                    // any rowmatches?
                    if ($rowMatches) {
                        // loop columns and reset value
                        for ($i = 0; $i < $colspan; ++$i) {
                            $table[$y + $rowspan][$x + $i] = null;
                        }

                        // increment
                        ++$rowspan;
                    }
                }

                $htmlContent[$y][$x] = [
                    'title' => \SpoonFilter::ucfirst($value),
                    'value' => $value,
                    'exists' => $value != '/',
                    'rowspan' => $rowspan,
                    'colspan' => $colspan,
                    'large' => $large,
                ];
            }
        }

        $templating = BackendModel::get('template');
        $templating->assign('table', $htmlContent);
        $html = $templating->getContent('Extensions/Layout/Templates/Templates.html.twig');

        return $html;
    }

    /**
     * Checks the settings and optionally returns an array with warnings
     *
     * @return array
     */
    public static function checkSettings(): array
    {
        $warnings = [];
        $akismetModules = self::getModulesThatRequireAkismet();
        $googleMapsModules = self::getModulesThatRequireGoogleMaps();

        // check if this action is allowed
        if (!BackendAuthentication::isAllowedAction('Index', 'Settings')) {
            return [];
        }

        // check if the akismet key is available if there are modules that require it
        if (!empty($akismetModules) && BackendModel::get('fork.settings')->get('Core', 'akismet_key', null) == '') {
            // add warning
            $warnings[] = [
                'message' => sprintf(
                    BL::err('AkismetKey'),
                    BackendModel::createUrlForAction('Index', 'Settings') . '#settingsApiKeys'
                ),
            ];
        }

        // check if the google maps key is available if there are modules that require it
        if (!empty($googleMapsModules)
            && BackendModel::get('fork.settings')->get('Core', 'google_maps_key', null) == '') {
            // add warning
            $warnings[] = [
                'message' => sprintf(
                    BL::err('GoogleMapsKey'),
                    BackendModel::createUrlForAction('Index', 'Settings') . '#settingsApiKeys'
                ),
            ];
        }

        return $warnings;
    }

    /**
     * Clear all applications cache.
     *
     * Note: we do not need to rebuild anything, the core will do this when noticing the cache files are missing.
     */
    public static function clearCache(): void
    {
        $finder = new Finder();
        $filesystem = new Filesystem();
        $files = $finder->files()
            ->name('*.php')
            ->name('*.js')
            ->in(BACKEND_CACHE_PATH . '/Locale')
            ->in(FRONTEND_CACHE_PATH . '/Navigation')
            ->in(FRONTEND_CACHE_PATH . '/Locale');
        foreach ($files as $file) {
            $filesystem->remove($file->getRealPath());
        }
        BackendModel::getContainer()->get('cache.backend_navigation')->delete();
    }
{'fraction_non_alphanumeric': 0.1247873820937065, 'fraction_numerical': 0.0012370496366166692, 'mean_word_length': 1.478444146388197, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6952742', 'n_tokens_mistral': 3480, 'n_tokens_neox': 3327, 'n_words': 854}