<?php

function cms_do_stage($stage = '') {
    global $cms;
    if (!isset($cms['stages'][$stage]) || !is_array($cms['stages'][$stage]) || !empty($cms['stages'][$stage]['disabled'])) return; // disable warnings if stage disabled
    ksort($cms['stages'][$stage]);
    while(list($level, $level_val) = each($cms['stages'][$stage])) {
        // skip 'next', 'disabled'
        if (is_array($cms['stages'][$stage][$level]))
        while(list($forder,$function) = each($cms['stages'][$stage][$level])) {
            $function();
        }
    }
}

function cms_save_config() {
    global $cms;
    @$r = file_put_contents($cms['config_file'], '<?php
$cms["config"] = '.var_export($cms['config'], true).";\n", LOCK_EX);
    if ($r) {
        clearstatcache();
        if (function_exists('opcache_invalidate')) { opcache_invalidate($cms['config_file']); }
        include($cms['config_file']);
    }
    return $r;
}

// Создание нового этапа
// Вторым параметром указываем к какому перейти после этого
// Если ничего не указываем, то CMS завершит работу после него
function cms_add_stage($stage, $next = '') {
    global $cms;
    $cms['stages'][$stage]['next'] = $next;
}

// Вставка этапа
// Вставляет новый этап, между текущим и следующим
// Вторым параметром можно переназначить следующий
function cms_insert_stage($stage, $next = '') {
    global $cms;
    if ($next === '') $next = $cms['stages'][$cms['stage']]['next'];
    $cms['stages'][$stage]['next'] = $next;
}

// Добавление функции в этап
// По умолчанию приоритет 10
// Увеличивая приоритет, отодвигаем функцию в конец, уменьшая - вперед
function cms_add_function($stage, $function, $nice = 10) {
    global $cms;
    $cms['stages'][$stage][$nice][] = $function;
    //if ( !isset( $cms['stages'][$stage]['next'] ) ) $cms['stages'][$stage]['next'] = ''; /* fix warning */
}

// $data['to_name']
// $data['to_email']
// $data['subject']
// $data['email_body']
// $data['from_name']
// $data['from_email']
// $data['files']
// $data['type'] (text/html(default) or text/plain)
// $data['sender'] if empty, then noreply@$_SERVER['SERVER_NAME']
// $data['bcc']
function cms_email($data) {
    global $images;
    $to_name = @trim($data['to_name']);
    if (!empty($to_name)) {
        $to = '=?utf-8?b?'.base64_encode($to_name).'?= <'.$data['to_email'].'>';
    } else {
        $to = $data['to_email'];
    }

    $subject = '=?utf-8?b?'.base64_encode($data['subject']).'?=';
    $from_name = @trim($data['from_name']);
    if (!empty($from_name)) {
        $from = '=?utf-8?b?'.base64_encode($from_name).'?= <'.$data['from_email'].'>';
    } else {
        $from = $data['from_email'];
    }
    $boundary = md5(uniqid(time()-25));
    $boundary_id = md5(uniqid(time()));
    if (empty($data['sender'])) { $sender = "noreply@{$_SERVER['SERVER_NAME']}"; } else { $sender = $data['sender']; }
    $headers = "Sender: $sender\r\nFrom: $from\r\nReply-To: $from\r\nContent-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
    if (!empty($data['bcc'])) $headers .= "Bcc: {$data['bcc']}\r\n";

    $images = array();
    $body2 = preg_replace_callback('/<img +src="([^"]+)"/', 
        function($matches){
            $r2 = preg_replace_callback('/data:image\/(\w+);base64,(.+)/',
                function($matches){
                    global $images;
                    $n = count($images);
                    $images[$n] = array('ext'=>$matches[1], 'base64'=>$matches[2]);
                    return "cid:$n.".$matches[1];
                }, $matches[1]);
            return '<img src="'.$r2.'"';
        }, $data['email_body']
    );

    if (empty($data['type']) || $data['type'] === 'html') {
        $type = 'text/html';
    } else {
        $type = 'text/plain';
    }
    $body_all = "--$boundary\r\nContent-Type: multipart/related; boundary=\"$boundary_id\"\r\n\r\n";
    $body_all .= "--$boundary_id\r\nContent-Type: $type; charset=utf-8;\r\nContent-Transfer-Encoding: base64\r\n\r\n" . chunk_split(base64_encode($body2) . "\r\n\r\n");

    foreach($images as $ind=>$image) {
        $body_all .= "--$boundary_id\r\nContent-Type: image/".$image['ext']."; name=\"$ind.".$image['ext']."\"\r\nContent-ID: <$ind.".$image['ext'].">\r\nContent-Disposition: inline; filename=\"$ind.".$image['ext']."\"\r\nContent-transfer-encoding: base64\r\n\r\n".chunk_split($image['base64'])."\r\n\r\n";
    }

    if (isset($data['files']) && is_array($data['files']))
    foreach($data['files'] as $file) {
        $file_full_path = realpath($file);
        $mime = mime_content_type($file_full_path);
        $file_name = preg_replace("/.*\//u", "", $file);
        $body_all .= "--$boundary_id\r\nContent-Type: $mime; name=\"$file_name\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"$file_name\"\r\n\r\n".chunk_split(base64_encode(file_get_contents($file_full_path)))."\r\n\r\n";
    }

    $body_all .= "--$boundary_id--\r\n\r\n";
    $body_all .= "--$boundary--\r\n\r\n";

    return $r = mail($to, $subject, $body_all, $headers, "-f{$data['from_email']}");
}

function cms_readfile($file) {
    if (file_exists($file)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        @ob_clean();
        flush();
        readfile($file);
    }
}

function __( $string, $module = "admin.mod.php" ) {
    global $cms;
    if ( !isset( $cms['config'] ) ) return $string;
    // Load lang file
    if ( !isset( $cms["lang"][$module][ $cms['config']['locale'] ] ) ) {
        $file = $cms['cms_dir'].'/lang/'.$cms['config']['locale'].'/'.$module;
        if ( file_exists( $file ) ) {
            include_once( $file );
        } else {
            $cms["lang"][$module][ $cms['config']['locale'] ] = array();
        }
    }
    // Translate
    if ( isset( $cms["lang"][$module][ $cms['config']['locale'] ][$string] ) ) {
        return $cms["lang"][$module][ $cms['config']['locale'] ][$string];
    } else {
        return $string;
    }
}

function cms_translit( $string ) {
    global $cms;
    $tr = array(
        "—"=>"-","«"=>"","»"=>"","…"=>"",
        '1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6','7'=>'7','8'=>'8','9'=>'9','0'=>'0',
        ' '=>'-','('=>'',')'=>'',','=>'-',';'=>'-','='=>'-','"'=>'','#'=>'',':'=>'','?'=>'','--'=>'-','.'=>''
    );
    $string = strtr( strtr( $string, $tr ), $tr );
    return strtr( $string, $cms['tr'] );
}

function cms_asort( &$array ) {
    if ( !is_array( $array ) ) return false;
    return uasort( $array, 'cms_uasort' );
}

function cms_uasort( $a, $b ) {
    if ( !isset($a['sort']) || !isset($b['sort']) ) {
        return 0;
    }
    if ( $a['sort'] <= $b['sort'] ) {
        return -1;
    } else {
        return 1;
    }
}