[Sell] Argos CMS / MVC logic less

Преди известно време бях попитан дали рутиранията могат да избегнат ?page=1/?view=2 и т.н., и тогава категорично отказвах, тъй като знаех, че ще трябва играчка и пипане по рутиращия клас.
Днес вече е възможно да се избегнат и с помощта на бота го направихме.
Добавен е нов параметър в рутиранията, ето пример:
Code:
        // Define the route dynamically
        $collection->attachRoute(new PHPRouter\Route('/pages/'.$page_name, [
            '_controller' => 'App\Controllers\CustomPage::CustomPage',
            'methods' => ['POST', 'GET'],
            'parameters' => ['template_file' => $template_file, 'addon_regex' => '(/p/\d+)?'],
        ]));
Става дума за addon_regex параметъра, който ще слухти за добавки с regex правила. В случая става дума за добавка с /p/ или page.
Добавил съм следното htaccess правило:
Code:
RewriteRule ^pages/banlist/p/([0-9]+)$ /pages/banlist?page=$1 [L,QSA]
и така вече от:
Code:
https://argoscms.pw/pages/banlist?page=2
може да го достъпите и от:
Code:
https://argoscms.pw/pages/banlist/p/2
Естествено в момента е хардкоднато, но от екстеншъните в sql.php при sql заявките за нова страница ще добавя нова колона 'regex' и именно от там ще вкарвате regex правилата за страниците генерирани от екстеншъни.
И така вече ще може да избягвате ? query параметъра и вашите линкове ще са идея по-четливи.
Мога да си поиграя и със страницирането, да направя да слухти за /p/ в url, но това не го обещавам. Идеята е страницирането да си остане с ?page=страница, а страници без странициране главно да се правят с regex правила, като pages/server?vew=1 да стане pages/server/view/1, естествено ако си има странициране вътре би трябвало да си работи.
Не съм го тествал обстойно, но във версия 9.0 ще го вкарам като новост и ще пренапиша gmon екстеншъна, който ще търпи още промени и нови функционалности.

Предстоят много нови неща, като повечето екстеншъни ще се сдобият и с админ панели, където е имало пипане в ext.php, за да е по-удобно за вас.
 
Бота подготви и функция, която ще вкарам в системата и ще се ползва от екстеншъните с горната добавка - https://onlinephp.io/c/c29b4
 
Ето и какво ми се върти в главата за gmon екстеншъна:

- aдмин панел от който ще се контролира всичко
- меню с jquery с облак за модовете
- ще се направят проверки ако някой е купил един от буустовете да не може да купува друг
- ще се изведе операционната система на сървъра
- ще се изведе бутон от който ще се виждат настройките на сървъра
- ще се добавят share бутони за социалните мрежи
- ще се изведат последно играни карти в сървърите и търсачка за търсенето им
- ще се добавят флаг икони в търсачката при държавите
- ще се изведе датата на добавяне на сървъра при преглед
- при фаворитите ще се добави странициране
- нов дизайн на таблицата със сървъри
- динамичните банери за сървъра ще са с нов дизайн и смяна на цветове
- on/off за gametracker изображенията за карти, ако е off - локални
 
Време е да опиша разликите във версия 8.8.1fixfree, която ще пусна безплатно и версия 9.0, която ще е платена.
Преди да го направя искам да кажа, че между 8.8.1fixfree и 8.4.3, която вече е пусната безплатно също има не малко разлики и ако сложите 8.8.1fixfree върху нея е възможно някои екстеншъни да не тръгнат.
За това аз ще изискам парична сума за ъпдейти по екстеншъните, като тя ще е делена на 2 на сумата която сте закупили екстеншъна. Ако той е бил 20лв. ще трябва да заплатите 10 за промените по кода.

8.8.1fixfree:
- Ще бъде добавена функцията get_user_id_by_username($username), чрез която ще се взима юзър айдито по име на потребител
- Ще се добави функцията is_online($user_id) с която ще проверявате дали някой е на линия
- Ще бъде добавена нова функция get_user_ip(), която ще прихваща потребителското айпи по няколко метода, включително и под cloudflare.
- Ще бъде добавена функцията ignore_non_utf8($string), която ще премахва специални символи, които не са utf8 валидни
- Ще бъдат добавени функциите add_to_db_config и remove_from_db_config (https://chatgpt.com/share/8994934b-309b-413b-8e64-c303a324afd4) Може да ги ползвате и по екстеншъните.
- Ще бъдат премахнати сесиите в core.php за смяната на стила. С тях е по добре, но не се сменя стила веднага. Бяха сложени с цел да не се прави всеки път заявка към датабазата, но няма да е добре нито за админи, нито за потребители.
- ще сложа новата anonymous статс функция, за която бях писал в предните постове, че си е била бъгава.
- ще премахна migrate.php от екстеншъните и ще сложа нов модел, който ще изпълнява тяхната роля
- Ще се добавят новите ентита (SteamId, Strings, Arrays, Dates, JsonManager) - това са вид helper-и, които може да ползвате по екстеншъните. Бота ги създаде и са много удобни и лесни за използване.
- Ще бъде добавена нова функция request_uri() капсула на $_SERVER['REQUEST_URI']
- Ще бъде добавена нова функция add_event, която ще е капсула на евент диспечера и вече няма да е необходимо да изписвате <style> и <script> при инжектирането им, защото тя ще го прави автоматично според типа на файла, който подавате.
- ще бъдат добавени колоните show и regex в _pages таблицата и ще бъде вкарана новата придобивка в core.php, а именно addon_regex.
- Админските евенти ще пробвам да ги преместя в admin/includes/admin_events.php
- Ще бъде добавена нова функция, а именно - https://chatgpt.com/share/1f9a525b-622a-4ead-bb36-90a888f24f11, която сама ще проверява дали в стиловете има ланг файлове и ще ги вика директно. Ще бъде като метод викнат в BaseController-a.
- Ще бъде добавена и тази функция - https://chatgpt.com/share/25a93137-014d-4262-b55e-addd5de4a53a чрез която по-лесно ще викате евенти в темплейтите от файла _functions.php.
- ще бъде добавена redirect_to($url,$seconds) функция, чрез която ще редиректвате потребителите към определена страница.
- Ще бъде добавена get_user_country($ip) функция, чрез която ще взимате държавата по айпи
- Ще бъде добавена функцията get_user_group($user_id) с цел да взимате групата на потребителя от форума
- Ще бъде добавена и get_user_rank($user_id) за взимане на ранга.
- Ще бъде изключена проверката за версия в ckeditor-a, за да не дава грешки и в някои екстеншъни също (които го ползват).
- Промени в readme папкатa

Това са промените във версията, която ще пусна безплатно. В нея ще е default стила и екстеншъните по-начало.
С нея аз се презапасявам, че занапред от нея и версия 9.0 нататък всичко ще върви без проблеми.

А сега и чейнчлог за версия 9.0:
- Цялото ядро ще бъде обходено от мен и бота с цел оптимизация и премахване на остарял код
- Ще има чисто нов дизайн на инсталатора
- Екстеншъните при бъг в тях няма да навредят на системата при използване на try/catch блок и rollback страница от която ще ги спирате директно при проблем
- при контролера на празниците в евент календара има еднакви дати и ще бъдат премахнати и оставени по важните празници за всяка еднаква дата.
- В админ панела ще бъде добавен js калкулатор
- В админ панела ще бъде добавен лог за активността на потребителите, които са достъпвали дадени страници от него.
- В jquery/js инжекциите ще бъде премахнат head_ready текста в описанието на страницата и заменен с document.ready.
- Ще бъдат добавени броячи на новините и коментарите в админ панела
- Ще бъде сменен fontawesome js kit-a в темите които го ползват, защото стария не работи вече.
- В логовете в админ панела всички айпита ще пренасочват към whois на domaintools за по лесни справки
- В админ панела при отговора на емейли ще бъде добавен quote бутон, за да може да цитирате текста автоматично.
- Ще бъде добавена функция за изкарването на no avatar-ите чрез random flat background color и първата буква от ника.
- Ще може от админ панела да спирате и пускате последните теми от форума
- В конфигурацията ще бъде добавено поле за цвят за мета тага theme color
- ще бъде добавен youtube бутон в ckeditor-a и екстеншъните, които го ползват
- Custom страниците ще могат да се спират и пускат от админ панела.
- Oт админ панела ще може да се избира default timezone от селект поле
- Тестовите менюта ще бъдат премахнати от темплейтите и админ панела, а и от ядрото
- functions.php оптимизации
- Добавяне на още поддържани игри в greyfish
- Всички екстеншъни ще претърпят оптимизации
- voice captcha при клик на бутон до нея
- прилагане на фикс за обновяването на captch-та под файърфокс
- От админ панела ще решавате дали captcha-та да е само с числа.
- Фикс за ajax чата да вади съобщения само при последно различно chat id съобщение

Ами т'ва е...
 
Last edited:
В търсене съм на нов тестови хостинг за демото. Писах си с namecheap и ми казаха, че не поддържат redis на споделените планове. (https://img.onl/jQ8NHe)
Искам да е нещо различно, за да потвърдя, че и там работи системата.
При namecheap .xyz домейните са с голяма промоция и можеби домейна ще е от тях.

Ще ви държа в течение какво съм решил за хостинг.

ПС:
Хоста е намерен https://easyhost.bg/spodelen-hosting
Поддържат redis с ip и порт, nodejs и ffmpeg.
Питах ги дали не са купени от някои от по-големите в бранша, но отрекоха.
Това ще е следващия хост на който аргос 9.0 ще се настани за тестове
Домейна ще е от namecheap.
 
Last edited:
С бота надраскахме един vanilla js плъгин за добро утро, добър ден и добър вечер. Работи с local storage за определен часови диапазон и съобщението се показва само веднъж.
Цена 5 евро

Screenshot-20240822-193941.png
 
Завърших и rollback-a и дори пригодих и try/catch блока за _functions.php в темплейтите.
Ето и как изглеждат двата кода:
Code:
function load_extensions()
{
    global $dbh, $lang_sys, $ext_language, $bb_is_admin;

    $error_ext_name = null;
    $redirect_url = null;

    // Check for URL parameters to prevent infinite redirection loop
    if (str_contains($_SERVER['REQUEST_URI'], 'add_edit_ext.php?error=')) {
        return; // Stop function if we are already on the error page
    }

    $checker = $dbh->query('SELECT ext_name FROM ' . $_SERVER['DB_PREFIX'] . 'ext WHERE ext_active=1');
    if ($checker->rowCount() > 0) {
        while ($row = $checker->fetch(PDO::FETCH_ASSOC)) {
            $ext_name = $row['ext_name'];
            $extPath = __DIR__ . '/../ext/' . $ext_name;
            $corePath = $extPath . '/ext.php';
            $langPath = $extPath . '/lang/' . get_current_language() . '.php';
            $defaultLangPath = $extPath . '/lang/en.php';

            try {
                if (file_exists($corePath)) {
                    require_once $corePath;
                }

                if (file_exists($langPath)) {
                    include $langPath;
                    $lang_sys = array_merge($lang_sys, $ext_language);
                } elseif (file_exists($defaultLangPath)) {
                    include $defaultLangPath;
                    $lang_sys = array_merge($lang_sys, $ext_language);
                }
            } catch (Throwable $e) {
                error_log('Error loading extension ' . $ext_name . ': ' . $e->getMessage());
                if ($bb_is_admin) {
                    $error_ext_name = $ext_name;
                    $redirect_url = url() . '/admin/add_edit_ext.php?error=' . urlencode($error_ext_name);
                    break; // Exit the loop if an exception is caught
                }
            }
        }
    }

    if ($redirect_url !== null) {
        // Redirect to the error page
        header('Location: ' . $redirect_url);
        exit;
    }
}

Code:
function load_theme_functions() {
    global $bb_is_admin;

    // Determine the path to the theme functions file
    $themeFunctionsPath = __DIR__ . '/../template/' . get_style() . '/_functions.php';

    // Check if the file exists
    if (file_exists($themeFunctionsPath)) {
        try {
            require_once $themeFunctionsPath;
        } catch (Throwable $e) {
            if ($bb_is_admin) {
                // Log the error and show an alert for admin users
                error_log('_functions.php error: ' . $e->getMessage());
                echo alert('danger', '_functions.php error!');
            }
        }
    }
}

Преосмислих някои неща и все повече разбирам, че версия 9.0 ще е с цялостно пренаписано ядро (App/ и includes/functions.php)
Също така ще индентна и admin/template/js_libs.html
Дори няма да остане почти никакъв код, който не е докоснат от бота, защото дори в sql заявките обгражда променливите с { }, а не както сме ги писали с ' . $variable .'
Всичко ще бъде със сменена стилистика и оптимизирано.

С горните два кода се застраховаме, че системата никога няма да се счупи пред потребителите, а и при вас и спокойно ще може да вземете действия и да отстраните проблемите спокойно.

Ето и снимки
rollback: https://i.ibb.co/XDSrFLT/Screenshot-20240824-183850.png
След засечен проблемен екстеншън администратора ще бъде редиректнат към страницата с екстеншъни и ще види оградения в различен цвят бъгав екстеншън.

_functions.php error:
https://i.ibb.co/VHsm6zd/Screenshot-20240824-183530.pngТук минуса е, че съобщението излиза над html тага, но не мисля, че е кой знае какъв проблем, тъй като е видимо само от админи. След отстраняването на проблема, съобщението ще се скрие.

Мисля, че се получи супер.
То почти всичко вече е готово, остава само да се сглоби.

Днес ни обявиха, че ще започнем работа от 29, така, че ще гледам да свърша още нещо, за да съм още по-готов с версия 9.0
 
Last edited:
Ако някой е влизал на демото и е видял грешки, то те са от мен, защото търсих вариант да изолирам някак зареждането на екстеншъни да не са в конструкт метода на basecontroller-a, но не успях.
С бота изписахме цели книги, даже ми спряха и чата и ме накараха да платя или да стартирам нов.
Проблемът сега е, че 1 екстеншън е в loop и зарежда всички други.
Ако имаме 3 екстеншъна, то заявките към датабазата ще са 9, защото всеки зарежда всички и това е цикъл.
Сами разбирате, че при повече екстеншъни става грозно.
Опитахме по всякакви начини, със singleton класове, със статични променливи и return, но не става.
Проблемът е в екстеншъните, защото всеки екстеншън наследява basecontroller-a и в конструкт метода вика parent::construct и циклите започват отново и отново, защото пък в бейсконтролера в конструктора му се викат самите екстеншъните и те от своя страна се викат сами.

Много идиотско, но засега ще остане така докато не измисля вариант. При този начин на работа системата ще зарежда горе долу добре при 35-40 нормални екстеншъна. Под нормални имам в предид около 200 до 700 реда код и без ровене в големи таблици, защото таблиците на gmon могат да съберат 40к логове и ровенето в тях е по бавно . Имам в предвид, че такива екстеншъни като него няма как да заредите 35 или 40, защото системата може и да не зареди.
В момента на демото са 74 и заради това леко бавно зарежда.

Със сигурност има вариант да се оправи, но аз все още не го знам. Идеята ми е всичко да си продължи така, но след като заредят всички да се прекъсва някъде функцията, която ги вика.
Ще намеря начин обещавам.
 
Last edited:
Снощи късно вечерта оправих и това нещо, трябвало е променливите да са със self, за да може да ги достъпва само бейсконтролера, а не и екстеншъните.
След това извиках echo 1;, за да видя колко на брой единици ще ми върне и върна толкова, колкото са включените, иначе връщаше стотици.

Ето и кода в бейс контролера:
Първо декларираме променливите :
Code:
private static $initialized = false;

private static $initialized2 = false;

private static $initialized3 = false;

private static $initialized4 = false;

private static $initialized5 = false;

после викаме методите:
Code:
$this->uniqueStats();
$this->initializeExtensions();
$this->initializeExt_langs();
$this->loadThemefuncs();
$this->deleteOldStats();

Самите методи:
Code:
public static function uniqueStats()
{
    if (self::$initialized) {
        return;
    }

    self::$initialized = true;
    unique_statistic(); //@includes/functions.php
}

public static function initializeExtensions()
{
    if (self::$initialized2) {
        return;
    }

    self::$initialized2 = true;
    
    load_extensions(); //@includes/functions.php
}

public static function initializeExt_langs()
{
    if (self::$initialized3) {
        return;
    }
    global $cacher;

    self::$initialized3 = true;
    load_exts_languages($cacher->get('active_exts')); //@includes/functions.php
}

public static function loadThemefuncs()
{
    if (self::$initialized4) {
        return;
    }

    self::$initialized4 = true;
    load_theme_functions(); //@includes/functions.php
}

public static function deleteOldStats()
{
    if (self::$initialized5) {
        return;
    }

    self::$initialized5 = true;
    delete_old_ads(); //@include/functions.php
}

Ето как изглеждат вече функциите, които викат екстеншъните и техните ланг файлове:

ext:
Code:
function load_extensions()
{
    global $dbh, $bb_is_admin, $cacher;

    $error_ext_name = null;

    if (str_contains($_SERVER['REQUEST_URI'], 'add_edit_ext.php?error=')) {
        return;
    }

    $cacheKey = 'active_exts';
    $active_exts = $cacher->get($cacheKey);

    if (!$cacher->has($cacheKey)) {
        $query = 'SELECT ext_name FROM ' . $_SERVER['DB_PREFIX'] . 'ext WHERE ext_active=1';
        try {
            $checker = $dbh->query($query);
            if ($checker === false) {
                throw new Exception('Database query failed.');
            }

            $active_exts = [];
            while ($row = $checker->fetch(PDO::FETCH_ASSOC)) {
                $active_exts[] = $row['ext_name'];
            }

            $cacher->set($cacheKey, $active_exts, 3600);
        } catch (Throwable $e) {
            error_log('Error querying database for active extensions: ' . $e->getMessage());
            return;
        }
    }

    foreach ($active_exts as $ext_name) {
        $extPath = __DIR__ . '/../ext/' . $ext_name;
        $corePath = $extPath . '/ext.php';
        try {
            if (file_exists($corePath)) {
                require_once $corePath;
            }
        } catch (Throwable $e) {
            error_log('Error loading core file for extension ' . $ext_name . ': ' . $e->getMessage());
            $error_ext_name = $ext_name;
            break;
        }
    }

    if ($error_ext_name !== null && $bb_is_admin) {
        $redirect_url = url() . '/admin/add_edit_ext.php?error=' . urlencode($error_ext_name);
        header('Location: ' . $redirect_url);
        exit;
    }
}

lang:
Code:
function load_exts_languages(array $active_exts)
{
    global $ext_language, $lang_sys, $bb_is_admin;
    $error_ext_name = null;

    if (str_contains($_SERVER['REQUEST_URI'], 'add_edit_ext.php?error=')) {
        return;
    }

    foreach ($active_exts as $ext_name) {
        $extPath = __DIR__ . '/../ext/' . $ext_name;
        $langPath = $extPath . '/lang/' . get_current_language() . '.php';
        $defaultLangPath = $extPath . '/lang/en.php';

        try {
            if (file_exists($langPath)) {
                require_once $langPath;
                $lang_sys = array_merge($lang_sys, $ext_language);
            } elseif (file_exists($defaultLangPath)) {
                require_once $defaultLangPath;
                $lang_sys = array_merge($lang_sys, $ext_language);
            }
        } catch (Exception $e) {
            error_log('Error loading language file for extension ' . $ext_name . ': ' . $e->getMessage());
            $error_ext_name = $ext_name;
            break;
        }
    }

    if ($error_ext_name !== null && $bb_is_admin) {
        $redirect_url = url() . '/admin/add_edit_ext.php?error=' . urlencode($error_ext_name);
        header('Location: ' . $redirect_url);
        exit;
    }
}

Разделих ги на 2 и кеширах активните, за да пренасям информация, понеже като 2та кода са заедно, не успява докрай да извика ланг файловете и за това ги разделих на 2. Вместо throwable ползвам exception в долната функция, защото реално само warnings могат да се появят в ланг файловете, а не грешки.

Аз съм с много бавен нет в момента, върти се около 2 до 4 мб/s и ми зарежда бавно демото, не знам при вас как е, някой може да влезе и провери.
Би трябвало да е идея по-бързо зареждането.
 
Last edited:
Във версия 9.0 всички екстеншъни ще четат файла ext_handler.php, който ще изпълнява код при пускане и спиране на екстеншъните. В комбинация с него ще има и 2 функции, които ще добавя, а именно add_env('key','value') и remove_env('key'), естествено вътре в него може да си добавяте всякакъв код.
Тези 2 функции ще добавят и премахват ключове към config.env файла. Така после може да ги взимате през $_SERVER дефиницията в самия екстеншън.

Това е много полезно.
Ето и съдържанието на ext_handler.php:
Code:
<?php
class ext_handler
{
    public function handle($status)
    {
        if ($status == '1') {
            $this->on();
        } elseif ($status == '0') {
            $this->off();
        }
    }

    protected function on()
    {
        add_env('my_ext',1);
    }

    protected function off()
    {
        remove_env('my_ext');
    }
}

и двете функции:
Code:
// Function to get the path to the config.env file
function get_env_file_path()
{
    // Path to the config.env file in the public_html directory
    return 'config.env';
}

function add_env($key, $val)
{
    $envFile = get_env_file_path();

    // Ensure the file exists
    if (!file_exists($envFile)) {
        return; // File does not exist
    }

    // Read the content of the config.env file
    $content = file_get_contents($envFile);

    if ($content === false) {
        return; // Failed to read the file
    }

    // Prepare the new content
    if (preg_match("/^\"?$key\"?=.*/m", $content)) {
        // Update existing key
        $content = preg_replace("/^\"?$key\"?=.*/m", "\"$key\"=\"$val\"", $content);
    } else {
        // Add new key-value pair without leading newline
        $content .= "\"$key\"=\"$val\"" . PHP_EOL;
    }

    // Write the updated content back to the config.env file
    file_put_contents($envFile, $content, LOCK_EX);
}


function remove_env($key)
{
    $envFile = get_env_file_path();

    // Ensure the file exists
    if (!file_exists($envFile)) {
        return; // File does not exist
    }

    // Read the content of the config.env file
    $content = file_get_contents($envFile);

    if ($content === false) {
        return; // Failed to read the file
    }

    // Prepare the content by removing the line with the given key
    $content = preg_replace("/^\"?$key\"?=.*/m", '', $content);

    // Remove any empty lines left behind
    $content = preg_replace("/^\s*$(?:\r\n?|\n)/m", '', $content);

    // Write the updated content back to the config.env file
    file_put_contents($envFile, $content, LOCK_EX);
}

а, това ще е в модела за пускане и спиране:
Code:
        $classFile = 'ext/' . $id . '/ext_handler.php';
        if (file_exists($classFile)) {
            include_once $classFile;

            if (class_exists('ext_handler')) {
                $handler = new \ext_handler();
                $handler->handle($status);
            }
        }
 
Last edited:
В същия модел по-горе (Extension_Updater_Model.php) под последния код, който съм дал се слага:
Code:
$this->run_migration($id, $status);

и в същия файл декларираме метода:
Code:
protected function run_migration($id, $status)
{
    require_once 'ext/' . $id . '/sql.php';

    $sql_insert .= "
        INSERT INTO " . $this->argos_db_prefix . "ext (ext_name, ext_active, ext_version) 
        VALUES(?, '1', ?);";
    
    $sql_drop .= "
        DELETE FROM " . $this->argos_db_prefix . "ext 
        WHERE ext_name=?;";
    
    if ($status == 1) {
        $go = $this->db->prepare($sql_insert);
        $go->bindParam(1, $id, PDO::PARAM_STR);
        $go->bindParam(2, $ext_version, PDO::PARAM_STR);
        $go->execute();
    } else if ($status == 0) {
        $go = $this->db->prepare($sql_drop);
        $go->bindParam(1, $id, PDO::PARAM_STR);
        $go->execute();
    } else {
        $go = $this->db->prepare($sql_insert);
        $go->bindParam(1, $id, PDO::PARAM_STR);
        $go->bindParam(2, $ext_version, PDO::PARAM_STR);
        $go->execute();
    }
}

като направим тези стъпки migrate.php в папките на екстеншъните стават ненужни и могат да се изтрият.
 
Готов е и бокса с плаващите бутони с модове за gmon екстеншъна.
Ще седят под новините в бокс или ако сте с BLOG_MODE=1 под всички сървъри.

Демо https://codepen.io/Pok4-the-encoder/pen/eYwLaZJ
Демо със снимка
Бутоните вътре са с готин ефект, даже може още да ги пипна като започна с ъпдейтите.
 
Както бях обещал събрах модове за игрите за gmon екстеншъна и по конкретно за game_modes.json файла.
Ето ги и тях:
Code:
{
  "cs16": {
    "1": "Public",
    "2": "Classic",
    "3": "DeathMatch",
    "4": "DeathRun",
    "5": "GunGame",
    "6": "HNS",
    "7": "KreedZ",
    "8": "SoccerJam",
    "9": "Knife",
    "10": "SuperHero",
    "11": "Surf",
    "12": "Warcraft3",
    "13": "PaintBall",
    "14": "Zombie",
    "15": "ZombiePlague",
    "16": "ClanWar",
    "17": "AWP",
    "18": "Dust2 only",
    "19": "Aim",
    "20": "BaseBuilder",
    "21": "JailBreak",
    "22": "Inferno only",
    "23": "Mirage only",
    "24": "Assault only",
    "25": "Rats only",
    "26": "Other"
  },
  "source": {
    "1": "Dust 2 only",
    "2": "CSDM",
    "3": "Classic",
    "4": "Surf",
    "5": "Zombie",
    "6": "GunGame",
    "7": "Inferno only",
    "8": "AWP",
    "9": "Mini games",
    "10": "Mirage only",
    "11": "Bhop",
    "12": "HNS",
    "13": "SoccerJam",
    "14": "JailBreak",
    "15": "Aim",
    "16": "KreedZ",
    "17": "Other"
  },
  "cscz": {
    "1": "Dust 2 only",
    "2": "CSDM",
    "3": "Classic",
    "4": "Inferno only",
    "5": "Retro",
    "6": "GunGame",
    "7": "Zombie mod",
    "8": "Aim",
    "9": "Office only",
    "10": "Other"
  },
  "csgo": {
    "1": "Nuke only",
    "2": "Inferno only",
    "3": "Mirage only",
    "4": "Zombie",
    "5": "Surf",
    "6": "AWP",
    "7": "CSDM",
    "8": "Competitive",
    "9": "JailBreak",
    "10": "KreedZ",
    "11": "Mix",
    "12": "Dust2 only",
    "13": "BHOP",
    "14": "Mini games",
    "15": "Aim",
    "16": "Other"
  },
  "cs2": {
    "1": "Nuke only",
    "2": "Inferno only",
    "3": "Mirage only",
    "4": "Zombie",
    "5": "Surf",
    "6": "AWP",
    "7": "CSDM",
    "8": "Competitive",
    "9": "JailBreak",
    "10": "KreedZ",
    "11": "Mix",
    "12": "Dust2 only",
    "13": "BHOP",
    "14": "Mini games",
    "15": "Aim",
    "16": "Other"
  },
  "halflife": {
    "1": "Crossfire only",
    "2": "GunGame",
    "3": "Deathmatch",
    "4": "SvenCoop",
    "5": "Ricochet",
    "6": "Classic",
    "7": "Other"
  },
  "halflife2": {
    "1": "Deathmatch",
    "2": "Fun",
    "3": "Coop",
    "4": "Crossfire only",
    "5": "Jump",
    "6": "Surf",
    "7": "Classic",
    "8": "Other"
  },
  "tf2": {
    "1": "Zombie",
    "2": "JailBreak",
    "3": "Deathrun",
    "4": "Minecraft",
    "5": "2Fort only",
    "6": "Fun",
    "7": "Classic",
    "8": "Jump",
    "9": "Trade",
    "10": "Surf",
    "11": "Respawn",
    "12": "Other"
  },
  "samp": {
    "1": "Roleplay",
    "2": "RPG",
    "3": "Survival",
    "4": "Zombie",
    "5": "Deathmatch",
    "6": "Other"
  },
  "minecraft": {
    "1": "Survival",
    "2": "Other"
  },
  "fivem": {
    "1": "Roleplay",
    "2": "Other"
  }
}
 
Остават точно 31 дни до връщането ми в България. Надявам се всичко да върви по план.
Новостите ще са много, а след пренаписването на ядрото и екстеншъните, ще дойде ред на темплейтите.
Планирам да я пусна и в още форуми като реклама, тъкмо и от там мога да получа съвети, идеи и препоръки.
Най-вероятно версия 9.0 ще дойде с опция по време на инсталация да се реши дали кеша да е с файлове или с redis, защото има много хостинг планове (така де фирми), които не го поддържат.

Напомням, че версия 9.0 ще струва 100 лв.
Заплащането става по еконт,спиди,изипей или пейпал.
Мъррррр... :)
 
Здравейте,
Напомням, че демото изтича съвсем скоро. Ще бъде закупен нов хостинг и домейн веднага след като дойда.
В коментарите към новините и replies екстеншъна ще бъде добавена и bbcode поддръжка за:
Code:
[b], [s], [i], [u]
Code:
        // Refined BBCode patterns
        $bbcode_patterns = [
            '/\[b\](.*?)\[\/b\]/is',    // Bold [b][/b]
            '/\[i\](.*?)\[\/i\]/is',    // Italic [i][/i]
            '/\[u\](.*?)\[\/u\]/is',    // Underline [u][/u]
            '/\[s\](.*?)\[\/s\]/is'     // Strikethrough [s][/s]
        ];

        // Corresponding HTML tags
        $html_replacements = [
            '<strong>$1</strong>',      // <strong> for [b]
            '<em>$1</em>',              // <em> for [i]
            '<u>$1</u>',                // <u> for [u]
            '<strike>$1</strike>'       // <strike> for [s]
        ];

        // Perform BBCode replacements using refined regex
        $com_text = preg_replace($bbcode_patterns, $html_replacements, $com_text);
и на 2те места ще го добавя.

В News_Model има излишно прихващане на $_POST['com_text'], което трябва да се премахне, тъй като $com_text се подава от контролера директно.
После вече с малък екстеншън може (пожелание) да се изкарат bbcodes бутони за горните такива над текстареата или вътре в нея, както направих с кирилизатора в предните постове.
 
Хрумна ми нещо...
Преди една седмица мой клиент му се беше бъгнала логин формата заради грешни пароли и captcha, която се изискваше от phpbb, но не се виждаше защото имаше екстеншън от мен за скриване на форума.
Докато се усетим за проблема сменихме паролата на админския акаунт с md5 такава. (да, phpbb я чете и след първия логин я преобразува с неговия си hash)

В този ред на мисли ми хрумна при инсталация на системата да се изисква 6 цифрен код, чрез който ще може да попълвате форма, която ще рестартира паролата на админския акаунт, ако сте я забравили.
Това ще е отново към версия 9.0.
Така няма да се налага да влизате в phpmyadmin и да го правите ръчно.


Утре пътувам за новото ми работно място, там ще съм 3 седмици и се прибирам.
(Сърбят ме ръцете да я надграждам...хаха :])
 
Още два екстеншъна са готови.

Единият е за проверка на vac status-a по steamid64: https://i.ibb.co/09k2YwF/Screenshot-20240922-133801.png

Вторият е за ббкодовете, за които споменах по-горе: https://i.ibb.co/qjd8xVq/Screenshot-20240922-134039.png
В новия default темплейт, textarea-та ще е по-голяма.

Ще направя и още един екстеншън, който ще е доста полезен, а именно проследяване на ?refs, тоест, ако разменяте банери и линкове с някой сайт, давайте url your-site.com?refs=darksteam.net и така ще логвам колко пъти е влизано от darksteam.net, но това ще е другата събота и неделя, защото ще е малко по-голям и се изисква повече време.
 
Както обещах завърших и екстеншъна за проследяване на url адреси при размяна на линкове и банери.
Поразтърсих се и параметъра в url трябва да е utm_source, понеже го ползват и фейсбук и гугъл, така, ако плащате за реклама при тях, то екстеншъна ще може да проследява колко клика имате от там.
демо: https://i.ibb.co/71QywMd/Screenshot-20240929-124612.png

Има проверка за http refferer и само, ако съвпада с параметъра utm_source тогава го логва.
Ето примерен линк:
https://argoscms.pw?utm_source=darksteam.net
 
Last edited:
Закупих и домейна argoscms.xyz - https://i.ibb.co/vLSCmTy/Screenshot-20240929-174404.png
За срок от 2 години.
Надявам се, че всичко ще се нареди така, както съм го планирал.
Трябва да си взема и нов лаптоп, че с този моя е мъка голяма.
Най-вероятно ще е този https://www.kvantservice.com/product/lenovo-thinkpad-t480s-17255-id38569/ с 2 г. гаранция.
Че с моя ядовете са големи, взех го от Аликанте на промоция от един carrefour, но той си изби парите...

Сега като се върна (след 2 пълни седмици), ще пусна бързо безплатната 8.8.1fixfree и след това веднага върху нея ще ръчкам 9.0.

Хоста ще е от easyhost, но ще взема средния споделен, че позволява няколко домейна, трябва да кача още 1 сайт и заради това..

След версия 9.0 ще почна и новия default стил, а след него ще почна да обновявам и оптимизирам екстеншъните с бота.
Над 200 са вече.

Най-вероятно ще почна работа в БГ, но спокойно аз работя бързо :) Ще оправим нещата с всички, които се свържат с мен. Обещавам!
Не изключвам варианта края на февруари или март пак да замина за Франция за неопределен период. За това, момента да ме хванете е сега... :]
 
В Неделя ще направя нов екстеншън, чрез който ще може да давате шанс на вашите потребители да се абонират за известия чрез дискорд. Чрез плаваща иконка в някои от ъглите на сайта ви било то дясно горе или ляво долу и при клик, ще вкарва юзър айдито на потребителя от дискорд във ваша датабаза и от админ панела в текстареа ще може да известите всеки абониран потребител чрез бот, който се прави от дев конзолата на дискорд.
Потребителите вече трябва да са във вашия канал присъединени, иначе няма да работи.
Бота ще праща лста като реален потребител, тук не говорим за хуукове (hooks), а за реално получени съобщения.