master
indeferend 4 years ago
commit df825e3d2f

@ -0,0 +1,48 @@
{
"name": "",
"isOrdered": true,
"folders": {
"CLASSES": {
"name": "CLASSES",
"isOrdered": true,
"folders": {
"core": {
"name": "core",
"isOrdered": true,
"folders": {},
"files": {
"doc__LE_FS": 0
}
}
},
"files": {}
},
"LE": {
"name": "LE",
"isOrdered": true,
"folders": {},
"files": {
"core_fuctions": 0
}
},
"MODULES": {
"name": "MODULES",
"isOrdered": true,
"folders": {},
"files": {}
},
"PUB": {
"name": "PUB",
"isOrdered": true,
"folders": {},
"files": {}
},
"TPL": {
"name": "TPL",
"isOrdered": true,
"folders": {},
"files": {}
}
},
"files": {}
}

@ -0,0 +1,9 @@
<?php
class blog_model
{
}

@ -0,0 +1,206 @@
<?php
/** @var \DB $db*/
if(!defined("I")) die;
//работа с файлами
class LE_FS
{
//+++добавить рекурсивное добавление родительских...
public static function create_folder ($path,$permissions=0755)
{
if(!is_dir($path)) mkdir($path, $permissions);
}
public static function clear_folder($path)
{
$path = rtrim($path,"/")."/";
if (!is_dir($path) || !($handle = opendir($path))) return;
while(false !== ($f = readdir($handle)))
{
if($f == "." || $f == "..") continue;
$obj=$path.$f;
if (is_file($obj))
unlink($obj);
elseif (is_dir($obj))
LE_FS::clear_folder($obj);
}
closedir($handle);
}
//рекурсивное копирование папки LE_FS::copy_folder($src, $dest);
public static function copy_folder($src, $dest) {
if (stripos($src,".DS_Store")>0) return false;
if ( is_dir( $src ) ) {
if (!file_exists($dest)) mkdir($dest, 0777, true);
$d = dir( $src );
while ( false !== ( $entry = $d->read() ) ) {
if ( $entry != '.' && $entry != '..' )
LE_FS::copy_folder( "$src/$entry", "$dest/$entry");
}
$d->close();
}
elseif (!file_exists($dest))
{
copy($src, $dest);
echo 'copy file <b>'.$src.'</b> to <b>'.$dest."</b>\n<br>";
}
}
public static function dir_files($dir,$func=false)
{
if (!$dir||empty($dir)||!is_dir($dir)) return 1;
if($func===false) return 2;
$d = dir( $dir );
while ( false !== ( $entry = $d->read() ) ) {
if ( $entry == '.' || $entry == '..' ) continue;
$func($entry);
}
$d->close();
}
//LE_FS::save_from_post($inp=['f_name'=>,'path'=>])
public static function SAVE_POST($inp,$debug=false)
{
$f_name = (isset($inp['f_name'])) ? $inp['f_name'] : 'file';
if (!isset($inp['path']) || !is_dir($inp['path'])) return false;
$inp['path'] = rtrim($inp['path']);
// echo $inp['path'];
if (!isset($_FILES[$f_name])) return false;
$F = $_FILES[$f_name];
// echo_arr($F);
$SAVE_FILE = function($path,$index=false) use (&$F,&$debug)
{
$f_inf=[];
if ($index!==false)
{
if (!isset($F["tmp_name"][$index])) return false;
$f_inf['tmp_name'] = $tmp_name = $F["tmp_name"][$index];
$f_inf['name'] = $file_name = $F["name"][$index];
$f_inf['type'] = $F["type"][$index];
$f_inf['size'] = $F["size"][$index];
}
else
{
if (!isset($F["tmp_name"])) return false;
$f_inf['tmp_name'] = $tmp_name = $F["tmp_name"];
$f_inf['name'] = $file_name = $F["name"];
$f_inf['type'] = $F["type"];
$f_inf['size'] = $F["size"];
}
// echo $tmp_name.BR;
// echo $file_name.BR;
if (!is_uploaded_file($tmp_name)) return false;
$n = LE_FS::GEN_FNAME($file_name, $path);
$out = $path.DS.$n;
if (!move_uploaded_file($tmp_name, $out)) return false;
if (!file_exists($out)) return false;
if($debug!==false) $debug[$n] = $f_inf;
return $n;
};
if (is_array($F['tmp_name']))
{
$cnt = count($F['tmp_name']);
$res = [];
for ($i=0;$i<$cnt;$i++)
{
$_fn = $SAVE_FILE($inp['path'],$i);
if ($_fn!==false) $res[] = $_fn;
}
}
else
{
return $SAVE_FILE($inp['path']);
}
$cnt = count($res);
if (!$cnt>0) return false;
if ($cnt===1) return $res[0];
return $res;
}
public static function GEN_FNAME($inp_name = false, $path = false, $prefix=false)
{
$ext = ($inp_name) ? '.'.pathinfo ($inp_name,PATHINFO_EXTENSION) : ''; //extension .jpg
//file name alphabet
$fn_alphabet = [0,1,2,3,4,5,6,7,8,9,'A','B','C','D',
'E','F','G','H','I','J','K','L','M','N','O','P','Q',
'R','S','T','U','V','W','X','Y','Z','_','-'
];
$microtime = microtime(1);
$create_time = 1540388275;
$diff_time = Ceil($microtime*10000)-($create_time*10000);
$new = int2alphabet($fn_alphabet,$diff_time);
if ($prefix!==false) $new = $prefix.$new;
//проверка существования
if ($path && is_dir($path))
{
$part = rtrim($path,DS);
$i=1;
while(is_file($path . DS . $new.$ext))
{
if ($i>100) exit("problem gen file name!!!");
$new.=$fn_alphabet[rand(0,27)];
$i++;
}
}
return $new.$ext;
}
public static function Apply2Files($path,&$func,$recouse=0)
{
$path = rtrim($path,"/\\").DS;
if (!is_dir($path) || !($handle = opendir($path))) return;
while(false !== ($f = readdir($handle)))
{
if($f == "." || $f == "..") continue;
$obj=$path.$f;
if (is_file($obj))
$func($obj);
elseif (is_dir($obj) && $recouse)
LE_FS::Apply2Files($obj,$func,$recouse);
}
closedir($handle);
}
}

@ -0,0 +1,145 @@
<?php
abstract class LE_MOD_CONTROLLER
{
public $aliases, $params_url, $model,$cont_type;
function __construct($params_url=false,&$model=false)
{
$this->params_url = $params_url;
$this->model = &$model;
}
//точка входа
public function start()
{
//ajax methods
if (isset($_POST['ajax'])) return $this->ajax();
if (LE::$QUERY_DATA_TYPE=='json') return $this->json();
list($mod,$params) = $this->router();
if (!empty($mod) && isset($this->aliases[$mod])) $mod = $this->aliases[$mod];
$mod = "_inp_".$mod;
if ($mod=="_inp_" || !method_exists($this,$mod)) return $this->_inp_default($params);
return $this->$mod($params);
}
protected function router()
{
//echo_arr($this->params_url);
$url = $this->params_url[3];
$url = PRE::DOWN($url);
preg_match('!([^:]*)[:]?(.*)!ui',$url,$out);
//echo_arr($out);
return [$out[1],$out[2]];
}
protected function ajax()
{
//out without template
if (property_exists(LE::$TPL,'clear')) LE::$TPL->clear=1;
$mod = trim(arr_v($_POST,'mod',''));
if (empty($mod)) return false;
$mod = "_ajx_".$mod;
$data=false;
if (isset($_POST['data']))
{
$data = $_POST['data'];
if (!is_array($data) && !empty($data)) $data = json_decode($data,1);
}
if (!method_exists($this,$mod)) return false;
$res = $this->$mod($data);
//возвращать массив ответа как есть, не оборачивая в data
if (isset($res['as_is']) && $res['as_is'])
{
unset($res['as_id']);
$out = $res;
}
elseif ($res===false)
{
$out = ['success'=>0]; //error
}
else
{
$out = ['success'=>1];
$out['data'] = $res;
}
return json_encode($out);
}
protected function _inp_default($inp)
{
return false;
}
protected function json()
{
$postData = file_get_contents('php://input');
$data = json_decode($postData,1);
if (property_exists(LE::$TPL,'clear')) LE::$TPL->clear=1;
$method = trim(arr_v($data,'method',''));
if (empty($method)) return false;
$method = "_ajx_".$method;
if (!method_exists($this,$method)) return false;
unset($data['method']);
$res = $this->$method($data);
//возвращать массив ответа как есть, не оборачивая в data
if (isset($res['as_is']) && $res['as_is'])
{
unset($res['as_id']);
$out = $res;
}
elseif ($res===false)
{
$out = ['success'=>0]; //error
}
else
{
$out = ['success'=>1];
$out['data'] = $res;
}
return json_encode($out);
}
//301 redirect
public function move2new($url)
{
header("HTTP/1.1 301 Moved Permanently");
header("Location: ".$url);
exit();
}
}

@ -0,0 +1,71 @@
<?php
class LE_MOD_LOAD {
public $m1=false,$m2=false,$space_list=[],$mod_aliases=[];
public $init_path=false,$mod_path=false,$url;
function __construct($autorun=1)
{
$this->m1=SYSDIR."MODULES".DS;
$this->m2=APPDIR."MODULES".DS;
$this->space_list = SYSCONF::$SPACE_LIST;
$this->mod_aliases = SYSCONF::$MOD_ALIASES;
if ($autorun) $this->parse_url();
}
public function parse_url()
{
$query = LE_REQUEST::url2arr()['query_clr'];
$spaces_str = implode('|',array_keys($this->space_list));
preg_match('!^/('.$spaces_str.')?/?([^/?]*)/?(.*?)$!simu', $query,$res);
$this->url = $res;
$space_in_q = $res[1];
$mod_in_q = $res[2];
$space=SYSCONF::$DEFAULT_MODSPACE; //default
if (!empty($space_in_q))
{
$space = $this->search_key($this->space_list,$space_in_q);
if ($space===false) return false;
}
if ($this->select_path($space)===false) return false;
$mod=arr_v(SYSCONF::$DEFAULT_MODULE,$space,false); //default
if (!empty($mod_in_q))
{
$mod_rr=false;
if (isset($this->mod_aliases[$space]))
$mod_rr = $this->search_key($this->mod_aliases[$space],$mod_in_q);
$mod = ($mod_rr) ? $mod_rr : $mod_in_q;
}
$this->init_path = $this->select_path($space,"__space_init.php");
$this->mod_path = $this->select_path($space,$mod.".php");
}
public function select_path($space,$path="")
{
$app_path = $this->m2.$space.DS.$path;
$sys_path = $this->m1.$space.DS.$path;
if (file_exists($app_path)) return $app_path;
if (file_exists($sys_path)) return $sys_path;
return false;
}
public function search_key($arr,$key)
{
foreach ($arr as $tpl => $val)
if(preg_match('!^('.$tpl.')$!simu', $key)) return $val;
return false;
}
}

@ -0,0 +1,278 @@
<?php
class LE_MYSQL
{
public $l,$cnt = 0,$debug=0,$echo_sql=0;
private $cnf = [];
function __construct(&$cnf)
{
$this->cnf = &$cnf;
if (defined("DEBUG") && DEBUG==1) $this->debug=1;
$this->connect($cnf);
}
//exit and echo error
protected function err($txt)
{
http_response_code(503);
exit($txt);
}
/*****************************
| private helpers functions |
*****************************/
protected function create_connect()
{
if (isset($this->cnf['socket']) && !empty($this->cnf['socket']))
return new mysqli(NULL, $this->cnf['user'], $this->cnf['pass'], $this->cnf['db_name'], NULL,
$this->cnf['socket']);
return new mysqli($this->cnf['host'], $this->cnf['user'], $this->cnf['pass'], $this->cnf['db_name']);
}
public function connect()
{
$this->l = $this->create_connect();
if ($this->l->connect_errno) $this->err("ERROR CONNECT DB");
$this->sess_conf();
}
private function sess_conf()
{
$this->query("set names utf8");
$this->query("SET @@session.time_zone = '+00:00'");
}
public function check_conn ($debug=0)
{
if ($this->l->ping()!==false) return;
//проверим еще раз не переподключился ли он автоматом
usleep(500);
if ($this->l->ping()===false) $this->connect();
}
/*****************************
| query & anwer functions |
*****************************/
public function query($s, $buffer = true, $o = [])
{
$this->cnt++; //счетчик запросов
$buf = ($buffer) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT;
$type = (isset($o['type'])) ? $o['type'] : $this->detect($s);
if ($this->echo_sql) echo $s.BR;
$res = $this->l->query($s, $buf);
$e = ($this->l->error);
if (!empty($e)) $this->err(($this->c['debug'] ? $e . ' <br>(' . $s . ')' : 'ERR QUERY!!!'));
unset($e, $buf);
return $this->answer($res, $type, $o);
}
private function detect($s) {
if ((stripos($s, 'select', 0) !== false)) return 'S';
if ((stripos($s, 'SHOW', 0) !== false)) return 'S';
if ((stripos($s, 'insert', 0) !== false)) return 'I';
if ((stripos($s, 'update', 0) !== false)) return 'U';
if ((stripos($s, 'delete', 0) !== false)) return 'D';
if ((stripos($s, 'truncate', 0) !== false)) return 'T';
}
private function answer(&$r, $t_, $o) {
$t = &$this;
$l = &$this->l;
switch ($t_) {
case 'S':
if ((isset($o['row']) && $o['row']) || (isset($o['val']) && $o['val']))
{
$r_ = $this->get_row($r);
$r->free_result();
if (isset($o['val']) && $o['val']) return $r_[trim($o['val'])];
return $r_;
}
return $r;
break;
case 'I':
return $l->insert_id;
break;
case 'U';
case 'T';
case 'D';
return $l->affected_rows;
break;
}
return false;
}
public function get_row(&$r)
{
return ($r) ? mysqli_fetch_assoc($r) : FALSE;
}
/*****************************
| query prepare functions |
*****************************/
public function prepare($s)
{
return $this->l->real_escape_string($s);
}
public function arr2in($ids,$str=false)
{
if ($str) array_map(function($id){return "'".$id."'";},$ids);
$ids = (is_array($ids)) ? implode(',',$ids) : $ids;
return $this->prepare($ids);
}
public function gen_set($arr)
{
$arr_ = [];
if (count($arr)) {
foreach ($arr as $k => &$v) {
$arr_[] = "`" . $k . "`='" . (($v === '###') ? '' : $this->prepare($v)) . "'";
}
}
if (!count($arr_) > 0) {
return false;
}
unset($arr);
return implode(', ', $arr_);
}
/**********************
| result functions |
**********************/
public function count(&$res)
{
if (!$res || gettype($res)!=="object") return false;
return mysqli_num_rows ($res);
}
public function cnt(&$res) {return $this->count($res);}
public function res2arr($res = 0,$key=false,$shift_reg=false)
{
$res_arr = [];
if($key===false)
while($r = $this->get_row($res)) $res_arr[] = $r;
else
while($r = $this->get_row($res))
{
$_key = ($shift_reg) ? PRE::SHIFT($r[$key],$shift_reg) : $r[$key];
$res_arr[$_key] = $r;
}
return $res_arr;
}
public function found_rows()
{
return $this->query("SELECT FOUND_ROWS() as `cnt`", false, ['val' => 'cnt']);
}
/****************
QUERY GENERATORS
****************/
public function INS($table, $val_arr)
{
$table = $this->prepare($table);
$set_str = $this->gen_set($val_arr);
$sql = 'INSERT INTO `' . $table . '` SET ' . $set_str;
return $this->query($sql,0,['type'=>'I']);
}
public function UPD($table, $val_arr, $id, $idf = 'id',$str_key=false)
{
if (empty($id)) $this->err("ERR DB UPD");
$table = $this->prepare($table);
$set_str = $this->gen_set($val_arr);
$id_field = $this->prepare($idf);
$in_list = $this->arr2in($id,$str_key);
$sql = 'UPDATE `' . $table . '` SET ' . $set_str . ' WHERE `' . $id_field . '` IN (' . $in_list . ')';
return $this->query($sql,0,['type'=>'U']);
}
public function DEL($table, $id, $idf = "id",$str=false)
{
if (is_array($id) && !count($id)) return false; //нечего удалять, если ничего не передали
if (!is_array($id)) $id = [$id];
$table = $this->prepare($table);
$id_field = $this->prepare($idf);
$in_list = $this->arr2in($id);
$sql = 'DELETE FROM `' . $table . '` WHERE `' . $id_field . '` IN(' . $in_list.')';
return $this->query($sql,0,['type'=>'D']);
}
//ins or upd return index
public function SAVE($t,$v,$idf="id")
{
if (!isset($v[$idf]) || $v[$idf]==0) return $this->INS($t,$v);
$id = $v[$idf]; unset($v[$idf]);
//upd
if ($id>0 && count($v)>0) $this->UPD($t,$v,$id,$idf);
//delete
if ($id<0) $this->DEL($t,($id*-1),$idf);
return $id;
}
/*****************
* custom queries *
*****************/
public function query_arr($sql,$key=false,$shift_reg=0)
{
$res = $this->query($sql,0,['type'=>'S']);
$rez = $this->res2arr($res,$key,$shift_reg);
$res->free();
return $rez;
}
public function query_keyval($sql,$k=false,$v=false)
{
$k = trim($this->prepare($k));
$v = trim($this->prepare($v));
$res = $this->query($sql,0,['type'=>'S']);
$res_arr = [];
while($r = $this->get_row($res)) $res_arr[$r[$k]] = $r[$v];
return $res_arr;
}
public function query_single($s) {
return $this->query($s, false, ['row' => true]);
}
public function query_val($s,$v)
{
return $this->query($s, false, ['val' => $v]);
}
}

@ -0,0 +1,114 @@
<?php
class LE_REQUEST {
public static function url2arr($s=false, $use_forwarded_host = false)
{
if ($s===false) $s = $_SERVER;
$res = [];
$ssl = (isset($s['HTTPS']) && $s['HTTPS'] == 'on' );
$port = (isset($s['SERVER_PORT'])) ? $s['SERVER_PORT'] : '80';
//хак для ssl nginx->apache
/*
if ((!$ssl) && function_exists('apache_request_headers'))
{
$h = apache_request_headers();
if (is_array($h) && isset($h['Nginx-Https']) && $h['Nginx-Https']=='on')
{
$ssl=true; $port=443;
}
}
*/
$protocol = strtolower($s['SERVER_PROTOCOL']);
$scheme = substr( $protocol, 0, strpos( $protocol, '/' ) ) . ( ( $ssl ) ? 's' : '' );
$standart_port = ((!$ssl && $port=='80') || ($ssl && $port=='443'));
$host="locahost";
if ($use_forwarded_host && isset( $s['HTTP_X_FORWARDED_HOST'] ))
$host = $s['HTTP_X_FORWARDED_HOST'];
elseif (isset( $s['HTTP_HOST']))
$host = $s['HTTP_HOST'];
elseif (isset( $s['SERVER_NAME']))
$host = $s['SERVER_NAME'];
$host_full = ($standart_port) ? $host : ($host.":".$port);
$query= isset($s['REQUEST_URI']) ? $s['REQUEST_URI'] : '';
$query_clr = preg_replace('!\?.*?$!','',$query);
return compact('ssl','port','scheme','standart_port','host','host_full','query','query_clr','protocol');
}
public static function TYPE_DETECT()
{
if (!isset($_SERVER["CONTENT_TYPE"])) return false;
$type = trim(explode(';',$_SERVER["CONTENT_TYPE"])[0]);
$type = PRE::DOWN($type);
if ($type=='application/json') return 'json';
return false;
}
public static function get2str($cust_get=null)
{
$get= (is_null($cust_get)) ? $_GET : $cust_get;
if (!is_array($get) || !count($get)) return '';
$arr = [];
foreach ($get as $k => $v)
$arr[] = $k.'='.$v;
return '?'.implode('&',$arr);
}
public static function str2get($q="")
{
if(empty($q)) return false;
$q = explode('&',$q);
$out=[];
$c = count($query);
for ($i=0;$i<$c;$i++)
{
$r=explode('=',$q[$i]);
if(!isset($r[1])) $r[1]='';
$out[$r[0]]=$r[1];
}
return $out;
}
public static function MOVE($u)
{
http_response_code(301);
header("Location: ".$u);
exit();
}
public static function FIX_URLCASE($u)
{
$q = arr_v($u,'query','');
if(empty($q)) return false;
if (PRE::SHIFT($q,'DOWN')!=$q)
LE_URL::MOVE(PRE::SHIFT($u['full'],'DOWN'));
}
}

@ -0,0 +1,7 @@
<?php
class LE_SQLITE
{
}

@ -0,0 +1,493 @@
<?php
class LE_TPL {
public $load_tpls=[]; //список загруженных шаблонов
public $meta,$cont_top,$cont_bottom,$mod_cont,$head_cont;
public $vars=[],$prefix,$tpl_arr,$debug=0,$clear=0;
function __construct()
{
$this->meta = ['title'=>'','keywords'=>'','description'=>''];
$this->prefix="main";
$this->mod_cont="";
$this->vars = ['tpl_arr'=>&$this->tpl_arr,'tpl'=>&$this];
}
public function fetch($t,&$vars=array(),$prefix=false,$cache_en=false)
{
//выгружаем переменные в функцию
if (is_array($this->vars)) extract($this->vars);
if (is_array($vars)) extract($vars);
//определяем путь до шаблона
$this->load_tpls[] = $__p = $this->path($t,$prefix);
//инклудим шаблон, буферизуем его выхлоп
ob_start();
include($__p);
return ob_get_clean();
}
public function path($tpl_path,$prefix=false)
{
if ($prefix===false) $prefix = $this->prefix;
$path = $prefix.DS.$tpl_path.".tpl";
$path_app = realpath((APPDIR."TPL".DS.$path));
$path_sys = realpath((SYSDIR."TPL".DS.$path));
//echo APPDIR.$path.BR;
//echo SYSDIR.$path.BR;
if (is_file($path_app)) return $path_app;
if (is_file($path_sys)) return $path_sys;
exit($path." - NOT FOUND TPL");
}
public function display($prefix=false,$main_tpl="main")
{
//global $config,$db;
$tpl = &$this;
if ($this->debug) echo_arr($this->load_tpls);
if (arr_v($_POST,'clear')=='yes') $this->clear=1;
if($prefix===false) $prefix = $this->prefix;
include SYSDIR."TPL".DS.$prefix.DS."static_list.php";
$this->static_dep_apply();
$this->add_need_static();
$path= $this->path($main_tpl,$prefix);
if ($this->clear)
{
echo $this->mod_cont;
return ($this->clear=0);
}
$tpl_arr = &$this->tpl_arr;
include($path);
}
//static elements
public $need_st_list=[],$static_list=[],$static_dep=[],$top_st=[],$bottom_st=[];
public function need_static($inp)
{
if (!is_array($inp)) $inp = [$inp];
$cnt = count($inp);
for($i=0;$i<$cnt;$i++)
{
$v = $inp[$i];
if (empty($v)) continue;
$this->need_st_list[$v]=1;
}
}
public function static_dep_apply($dep_list=false)
{
if ($dep_list===false) $dep_list=$this->static_dep;
if (!is_array($dep_list) || empty($dep_list)) return;
$need = &$this->need_st_list;
foreach ($dep_list as $m_name => $dep_items)
{
//для выключенных модулей не применяем зависимости
if ( !(isset($need[$m_name]) && $need[$m_name]==1) ) continue;
foreach ($dep_items as $k => $dep)
{
$need[$dep]=1;
}
}
}
public function add_need_static()
{
$need = $this->need_st_list;
$list = $this->static_list;
foreach ($this->static_list as $key => $item)
{
$pos = arr_v($item,'pos',false);
$type = arr_v($item,'type',"");
$link = arr_v($item,'link',"");
//echo $link.BR;
if ($pos===false) $pos = ($type=="js") ? "bottom" : "top";
$mod=arr_v($item,'mod','default');
if ( !((isset($need[$mod]) && $need[$mod]==1) || $mod=='default') ) continue;
switch ($type)
{
case 'js':
$cont = $this->js($link);
break;
case 'css':
$cont = $this->css($link);
break;
default:
continue 2;
break;
}
if ($pos=="top")
$this->top_st[]=$cont;
else
$this->bottom_st[]=$cont;
}
$_gl = "\n\t";
$this->head_cont.=implode($_gl,$this->top_st);
$this->cont_bottom.=implode($_gl,$this->bottom_st);
//echo_arr($this->top_st);
}
public function css($p,$min=0)
{
return '<link rel="stylesheet" type="text/css" href="'.$this->p2min($p,$min,'css').'?v='.VER.'" />';
}
public function js($p,$min=0)
{
return '<script src="'.$this->p2min($p,$min,'js').'?v='.VER.'"></script>';
}
public function p2min($path,$min,$ext)
{
if ($min)
{
$path = str_replace('.'.$ext,'.min.'.$ext,$path);
$path = str_replace('min.min','min',$path);
}
return $path;
}
}
/*
<?php
MP::DEF('TPLDIR1',SYSDIR.'TPL'.DS);
MP::DEF('TPLDIR2',APPDIR.'TPL'.DS);
MP::DEF('LST_TPL',0);
MP::DEF('DBG_MGS',0);
MP::DEF('ST_DEV');
MP::DEF('ST_GLUE');
class TPL
{
public $template='default.tpl',$prefix='default',$clear=0;
public $js2bottom=1;
public $tpl_arr=[],$vars=[],$txt,$declare_parts=[], $load_tpls = []; //зарегистрированные части css и js
public $glue_arr = ['css'=>[],'js'=>[]];
function __construct() {
$this->tpl_arr = ['text'=>'','_html_'=>'','head_objects'=>'','meta_title'=>'','meta_keywords'=>'','meta_description'=>''];
$this->txt = &$this->tpl_arr['text'];
$this->vars = ['tpl_arr'=>&$this->tpl_arr,'tpl'=>&$this];
}
public function decl_p($inp)
{
$inp = MP_ARR::FROM_STR($inp);
while ($r = array_shift($inp)) $this->declare_parts[$r]=1;
}
public function js4part($p,$f,$EOL=false,$pre="",$glued=1)
{
if (ST_GLUE && $glued) return $this->glue_reg('js',$p,$f);
return $this->st4p($p,$this->js($f),$EOL,$pre);
}
public function css4part($p,$f,$EOL=false,$pre="",$glued=1)
{
if (ST_GLUE && $glued) return $this->glue_reg('css',$p,$f);
return $this->st4p($p,$this->css($f),$EOL,$pre);
}
public function glue_reg($type,$p,$url)
{
$path = str_replace('/mp_pub',SYSDIR."PUB", $url);
$path = str_replace('/pub_data',WEBDIR."pub_data", $path);
switch ($type) {
case 'css':
$path = str_replace('.css','.min.css',$path);
break;
case 'js':
$path = str_replace('.js','.min.js',$path);
break;
}
$this->glue_arr[$type][] =
['u'=>$url,'p'=>$path,'l'=> ((int)$this->if_decl_p($p))];
}
public function glue_stat()
{
$js_k = $css_k = "";
if (!ST_GLUE) return;
foreach ($this->glue_arr['js'] as $key => $it) $js_k.=$it['l'];
foreach ($this->glue_arr['css'] as $key => $it) $css_k.=$it['l'];
$alph = [0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','I','J','K',
'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','-','='];
$js_k = int2alphabet($alph,bindec($js_k));
$css_k = int2alphabet($alph,bindec($css_k));
$glue_path = WEBDIR."pub_data/static_cache/";
$js_path = $glue_path.$js_k.".js";
$css_path = $glue_path.$css_k.".css";
$glue_path = $alph = NULL;
unset($glue_path,$alph);
if (!is_file($js_path) && count($this->glue_arr['js']))
{
foreach ($this->glue_arr['js'] as $key => $it)
{
if (!$it['l']) continue;*/
//$pre = '/* file: '.$it['u'].'*/'."\n";
/* file_put_contents($js_path,$pre.file_get_contents($it['p'])."\n",FILE_APPEND);
}
}
if (!is_file($css_path) && count($this->glue_arr['css']))
{
foreach ($this->glue_arr['css'] as $key => $it)
{
if (!$it['l']) continue;*/
//$pre = '/* file: '.$it['u'].'*/'."\n";
/*file_put_contents($css_path,$pre.file_get_contents($it['p'])."\n",FILE_APPEND);
}
}
$this->to_head($this->css('/pub_data/static_cache/'.$css_k.".css",1));
$js_block = ($this->js2bottom) ? 'bottom_js' : 'head_objects';
$this->add2block($js_block,$this->js('/pub_data/static_cache/'.$js_k.".js",1));
}
public function st4p ($p,$inc,$EOL=false,$pre="")
{
if($this->if_decl_p($p)) return $pre.$inc.(($EOL)?$EOL:'');
}
public function st_format($inp,$pre="",$EOL="")
{
preg_match_all('!(\<[^>]+\>)!simu',$inp,$res);
foreach ($res[1] as $key => $v) echo $pre.$v.$EOL;
}
public function undecl_p($inp)
{
if($this->if_decl_p($inp)) unset($this->declare_parts[$inp]);
}
public function if_decl_p($inp)
{
if ($inp===0) return true;
return (isset($this->declare_parts[$inp]));
}
//+++добавить несколько частей в массиве
public function part_css($part,$css)
{
if ($this->if_decl_p($part))
echo $this->css($css);
}
public function display($prefix=false,$tpl_name="default")
{
global $tpl,$config,$db;
if (LST_TPL) echo_arr($this->load_tpls);
if (arr_v($_POST,'clear')=='yes') $this->clear=1;
if($prefix===false) $prefix = $this->prefix;
if ($this->clear)
{
echo $this->tpl_arr['text'];
return ($this->clear=0);
}
$tpl_arr = &$this->tpl_arr;
include($this->path($tpl_name,$prefix));
if (DBG_MGS) include($this->path('debug_message','default'));
return 1;
}
public function path($tpl_name,$prefix=false)
{
$p = ((empty($prefix))?$this->prefix:$prefix).DS.$tpl_name.'.tpl';
if (is_file($p_=TPLDIR2.$p) || is_file($p_=TPLDIR1.$p))
return str_replace('//','/',$p_);
exit($tpl_name.' - NOT FOUND!!!');
}
public function add2block($k,$v){
$this->tpl_arr[$k] = (isset($this->tpl_arr[$k]))? $this->tpl_arr[$k]."\r\n".$v : $v;
return $this;
}
public function canonical($url)
{
$this->to_head('<link rel="canonical" href="'.$url.'" />');
}
public function show_bl($n)
{
if (isset($this->tpl_arr[$n])) echo $this->tpl_arr[$n];
}
public function css($p,$nm=0)
{
return '<link rel="stylesheet" type="text/css" href="'.$this->p2min($p,$nm,'css').'?v='.MP_VER.'" />';
}
public function js($p,$nm=0)
{
return '<script src="'.$this->p2min($p,$nm,'js').'?v='.MP_VER.'"></script>';
}
public function to_head($str)
{
return $this->add2block('head_objects',$str);
}
public function add_js ($inp,$no_mod=0){
return $this->to_head($this->js($inp,$no_mod));
}
public function add_css ($inp,$no_mod=0){
return $this->to_head($this->css($inp,$no_mod));
}
public function mp_css($inp)
{
$inp = MP_ARR::FROM_STR($inp);
for ($i=0,$c=count($inp); $i < $c; $i++)
$this->add_css(M_PUB.'/css/'.$inp[$i]);
return $this;
}
public function mp_js($inp)
{
$inp = MP_ARR::FROM_STR($inp);
for ($i=0,$c=count($inp); $i < $c; $i++)
$this->add_js(M_PUB.'/js/'.$inp[$i]);
return $this;
}
public function meta_tags ($i,$i2=false)
{
if ($i===false && is_array($i2))
{
$i=[];
list($i['meta_title'],$i['meta_keywords'],$i['meta_description']) = $i2;
}
$f = function($n) {return(htmlspecialchars($n));};
$m_arr = SELECT_FROM_ARR('meta_description;meta_keywords',$i);
$m_arr = array_map($f,$m_arr);
//титл не экранируем
$m_arr['meta_title'] = $i['meta_title'];
unset($i);
$this->tpl_arr = array_merge($this->tpl_arr,$m_arr);
//echo_arr($m_arr);
unset($f,$m_arr);
}
public function ograph($title,$description,$image,$url,$type="website")
{
$a = &$this->tpl_arr;
$a['_html_'] = ' prefix="og: http://ogp.me/ns#"';
$_arr = compact('title','type','url','description','image');
foreach ($_arr as $p => $v)
{
$v=htmlspecialchars($v);
$this->to_head('<meta property="og:'.$p.'" content="'.$v.'"/>');
}
}
public function fetch($t,&$vars=array(),$prefix=false,$cache_en=false)
{
if ($cache_en)
{
$cache_key = MPCACHE::gen_key_p(array($t,$vars,$prefix));
$cache = MPCACHE::from_cache("tpl_cache",$cache_key);
if($cache!==false) return $cache['content'];
}
if (empty($t)||(mb_substr($t,0,1)=="#")) return '';
if (is_array($this->vars))extract($this->vars);
if (is_array($vars))extract($vars);
$tpl = &$this;
$this->load_tpls[] = $__p = $this->path($t,$prefix);
ob_start();
include($__p);
if ($cache_en)
{
$html = ob_get_clean();
MPCACHE::to_cache("tpl_cache",$cache_key,['content'=>$html]);
return $html;
}
return ob_get_clean();
}
public function txt($txt){$this->add2block('text',$txt);}
}
*/

@ -0,0 +1,36 @@
# LE\_FS - класс для работы с файловой системой и файлами
## GEN\_FNAME($inp\_name, $path, $prefix);
example
```
LE_FS::GEN_FNAME("picture.png",WEBDIR."/pub_data/","prod_");
```
Генерирует уникальное имя файла для указанной папки, расширение нового файла соответствует расширению входного в `$inp_name`
Опционально к имени файла в начале пристыковывается в префикс, например `prod_` `cat_` ...
***
## Apply2Files($path,&$func,$recouse=0)
> Данная функция создана для обработки массива данных
```
LE_FS::Apply2Files("./inp_folder/",$callback,0);
```
* `$path` \- путь до папки
* `$func` \- callback функция в которую передается полный путь до файла
* `$recourse` \- признак рекурсивности\, по умолчанию применяется только к указанной папке\, но если указан флаг то пройдет по всем подпапкам
>Внутри callback функции нужно предусматривать фильтрацию по расширению файла, например только xml или только jpg...
>
## SAVE_POST($inp,&$debug=false) - сохранение файла из POST
Сохраняет файл переданный в POST с указанным именем поля формы в POST в указанную папку `<input type="file" name="img_file">`
```
LE_FS::SAVE_POST(['f_name'=>'img_file','path'=>'/www/path/'])
```
Уникальное имя файлов генерируется автоматически...

@ -0,0 +1,133 @@
<?php
/******************
* LE Core *
*****************/
/*core functions*/
function arr_v($arr,$field,$default=false)
{
return isset($arr[$field]) ? $arr[$field] : $default;
}
function echo_arr(&$arr) {
if (ISWEB) echo '<pre>';
print_r($arr);
if (ISWEB) echo '</pre>';
}
/*core class*/
class LE
{
public static $DB,$TPL,$CACHE,$QUERY_DATA_TYPE;
public static function DEF ($constant_name,$val=false)
{
if (!defined($constant_name)) define($constant_name, $val);
}
}
/*date prepare class*/
//prepare class
class PRE {
public static $MASK = ['D' => '0-9', 'R' => 'а-яё', 'L' => 'a-z', 'S' => '\s'];
public static $SH_MASK = [
'UP' => MB_CASE_UPPER,
'DOWN' => MB_CASE_LOWER,
'U1' => MB_CASE_TITLE];
public static function SQL($s)
{
if (method_exists(LE::$DB, 'prepare')) return LE::$DB->prepare($s);
return addslashes($s);
}
public static function DOWN($s)
{
return mb_convert_case($s, MB_CASE_LOWER);
}
public static function UP($s)
{
return mb_convert_case($s, MB_CASE_UPPER);
}
public static function SHIFT($s, $t)
{
if (isset(PRE::$SH_MASK[$t])) {
return mb_convert_case($s, PRE::$SH_MASK[$t]);
}
exit('shift err mask');
}
public static function f2int($n,int $m):int
{
if (empty($n)) return 0;
$n=(float)$n;
$n*=pow(10,$m+1);
return (int) Ceil(round($n)/10);
}
public static function F($s, $t) {
$preg = strtr(preg_quote(trim($t), '!'), PRE::$MASK);
return preg_replace('![^' . $preg . ']!iu', '', $s);
}
public static function UP1($s) {
$s = PRE::SHIFT(trim($s),'DOWN');
$w = preg_split('/\s+/', $s);
if (isset($w[0]))
{
$w[0] = PRE::SHIFT($w[0],'U1');
return implode(' ',$w);
}
return $s;
}
public static function INT($i):int {return (int)PRE::NUM($i);}
public static function NUM($i) {return preg_replace('![^0-9]!', '', $i);}
public static function DEC($i):float {
$i= preg_replace('/[^\-0-9,.]/u', '', $i);
return (float)preg_replace('!([\-]?[0-9]+)[,.]?([0-9]+)?!', '$1.$2', $i);
}
public static function MONEY_OUT($i) {return money_format('%n', $i);}
//удаляет двойные пробелы и табы
public static function DSP($i)
{
return preg_replace('/\s{1,}/u', " ", $i);
}
public static function PLAIN_FORMAT($str,$one_str=0)
{
$str = PRE::DSP($str);
if ($one_str) $str = preg_replace('!([\n]*)!simu', '', $str);
$str = preg_replace('![\s]*([,.])!simu', '$1', $str);
$str = trim($str);
return $str;
}
//подрезает строку по разрешенному лимиту
public static function CROP($s,$l=0){return (($l>0)?mb_substr($s,0,$l):$s);}
}
/**приведение в алфавит $a числа $int */
function int2alphabet(array $a,int $int):string
{
$cnt = count($a); //емкость алфавита
$out="";
while ($int>=$cnt)
{
$out = ($a[($int % $cnt)]).$out;
$int = intdiv($int, $cnt);
}
return $a[$int].$out;
}

@ -0,0 +1,5 @@
# Описание базовых
>jjj
>kkk
>

@ -0,0 +1,5 @@
<?php
if (SYSCONF::$USE_MYSQL)
LE::$DB = new LE_MYSQL(SYSCONF::$DB);
//+++add sqlite

@ -0,0 +1,11 @@
<?php
if (! function_exists("array_key_last")) {
function array_key_last($array) {
if (!is_array($array) || empty($array)) {
return NULL;
}
return array_keys($array)[count($array)-1];
}
}

@ -0,0 +1,14 @@
<?php
$le_mod_loader = new LE_MOD_LOAD();
LE::$QUERY_DATA_TYPE = LE_REQUEST::TYPE_DETECT();
//init space
if ($le_mod_loader->init_path!==false)
include $le_mod_loader->init_path;
//load mod
if ($le_mod_loader->mod_path!==false)
include $le_mod_loader->mod_path;
//not found
if ($le_mod_loader->mod_path==false)
include $le_mod_loader->select_path('main','__404.php');

@ -0,0 +1,19 @@
<?php
ini_set('session.gc_maxlifetime', SYSCONF::$SESS_TIME);
ini_set('session.cookie_lifetime', SYSCONF::$SESS_TIME);
ini_set('session.save_path', SYSCONF::$SESS_DIR);
if (!is_dir(SYSCONF::$SESS_DIR)) mkdir(SYSCONF::$SESS_DIR,0700,true);
session_start();
//при первом входе знать откуда пришел человек
if (!isset($_SESSION['ref']) && isset($_SERVER["HTTP_REFERER"]))
$_SESSION['ref'] = $_SERVER["HTTP_REFERER"];
//каждые 3 минуты делаем обновление времени жизни сессии
$_exp = time()+SYSCONF::$SESS_TIME;
if (!isset($_SESSION['_exp']))
$_SESSION['_exp'] = $_exp;
elseif (($_exp-$_SESSION['_exp'])>180)
setcookie ("PHPSESSID", session_id() , ($_SESSION['_exp']=$_exp) ,'/');

@ -0,0 +1,6 @@
<?php
/* LE Framework autoload core classes */
spl_autoload_register(function ($class_name)
{
if (is_file(CORE_CLSDIR.$class_name.".php")) include CORE_CLSDIR.$class_name.".php";
});

@ -0,0 +1,38 @@
<?php
if(!defined("I")) die('err c001');
if(setlocale(LC_ALL, 'ru_RU.UTF-8','Russian_Russia.65001')===false)
exit('!!!not find UTF-8 LOCALE');
if(setlocale(LC_NUMERIC, 'en_US.UTF-8', 'C.UTF-8','C')===false)
exit('!!!not find C NUMERIC LOCALE');
mb_internal_encoding("UTF-8");
date_default_timezone_set('UTC');
LE::DEF('NO_CACHE'); //по-умолчанию кеширование включено
class SYSCONF
{
public static $DEFAULT_MODSPACE = "main";
public static $DEFAULT_MODULE = ['main' => 'welcome','admin'=>'dashboard'];
public static $MOD_ALIASES;
public static $USE_MYSQL = TRUE;
public static $USE_TPL = TRUE;
public static $ADMIN_MAIL = '';
public static $ROBOT_MAIL = '';
public static $DISP_TIME = FALSE;
public static $DB = ['host'=>'localhost','user'=>'','pass'=>'','db_name' =>''];
public static $SPACE_LIST=['admin|cabinet'=>'admin','main'=>'main'];
public static $SESS_DIR;
public static $SESS_TIME=120960;
public static $MPV;
public static $DR_N="LE CMS";
public static $CACH_DIR;
}
SYSCONF::$SESS_DIR = APPDIR.'sessions'.DS;
SYSCONF::$CACH_DIR = APPDIR.'cache'.DS;
if (is_file(APPDIR.'app_conf.php')) include APPDIR.'app_conf.php';

@ -0,0 +1,3 @@
<?php
LE::$TPL->prefix="admin";

@ -0,0 +1,94 @@
<?php
class CONTR extends LE_MOD_CONTROLLER {
protected function check_dest_folder($f)
{
if (!is_dir($uploaddir))
if(mkdir($uploaddir,0777,true)===false)
return false;
return true;
}
protected function _ajx_add_img($data)
{
if (!isset($_FILES['upload'])) return false;
$dest = WEBDIR.'pub_data/upload/img/';
if (!$this->check_dest_folder($dest)) return false;
$filename = LE_FS::SAVE_POST(['f_name'=>'upload','path'=>$dest]);
return ['url'=>'/pub_data/upload/img/'.$filename, 'as_is'=>1];
}
protected function _ajx_save_content($data)
{
$id = PRE::INT($data['id']);
$html_cont = $data['html_cont'];
preg_match('!(<h1>(.*?)<\/h1>)?(.*)!simu',$html_cont,$out);
$html_cont = $out[3];
$html_head = trim($out[2]);
//return;
$save_data = ['id'=>$id,'html'=>$html_cont,'head'=>$html_head];
$id = LE::$DB->SAVE('text_content',$save_data);
return $id;
}
protected function _ajx_remove_it($inp)
{
if (!isset($inp['id'])) return false;
$id=PRE::INT($inp['id']);
if (!$id>0) return false;
$res = LE::$DB->DEL('text_content',$id);
return ($res>0);
}
protected function _inp_default($inp)
{
$res = LE::$DB->query_arr("SELECT * FROM `text_content`",'id');
$to_tpl['cont_list'] = $res;
return LE::$TPL->fetch('blog/list',$to_tpl);
}
protected function _inp_edit($inp)
{
$id = PRE::INT($inp);
if ($id>0)
{
$res = LE::$DB->query_single("SELECT * FROM `text_content` WHERE `id`=".$id);
$it_data = json_decode($res['data'],1);
}
else
{
$res = ['html'=>'','head'=>''];
$it_data = [];
$id=0;
}
$to_tpl = [
'data'=>$it_data,
'id'=>$id,
'html_cont'=>$res['html'],
'head'=>$res['head']
];
return LE::$TPL->fetch('blog/edit_item',$to_tpl);
}
}
include CLSDIR."blog.php";
$blog_model = new blog_model;
$controller = new CONTR($le_mod_loader->url,$blog_model);
LE::$TPL->mod_cont .= $controller->start();

@ -0,0 +1,3 @@
<?php
http_response_code(404);
echo "<h1>PAGE NOT FOUND</h1>";

@ -0,0 +1,68 @@
<?php
class CONTR extends LE_MOD_CONTROLLER {
protected function _ajx_upload_img($data)
{
if (!isset($_FILES['upl_img'])) return false;
$uploaddir = WEBDIR.'pub_data/upload/img/';
if (!is_dir($uploaddir))
if(mkdir($uploaddir,0777,true)===false)
return false;
$filename = LE_FS::SAVE_POST(['f_name'=>'upl_img','path'=>$uploaddir]);
return ['url'=>'/pub_data/upload/img/'.$filename];
}
protected function _ajx_save_content($data)
{
$md_cont = $data['md_cont'];
$id = PRE::INT($data['id']);
$_data = json_encode(['md_cont'=>$md_cont]);
$html_cont = $data['html_cont'];
$save_data = ['id'=>$id,'data'=>$_data,'html'=>$html_cont];
$id = LE::$DB->SAVE('text_content',$save_data);
return $id;
}
protected function _inp_default($inp)
{
$res = LE::$DB->query_arr("SELECT * FROM `text_content`",'id');
$to_tpl['cont_list'] = $res;
return LE::$TPL->fetch('le_ui_kit/editor_list',$to_tpl);
}
protected function _inp_edit($inp)
{
$id = PRE::INT($inp);
if (!$id>0) return false;
$res = LE::$DB->query_single("SELECT * FROM `text_content` WHERE `id`=".$id);
$it_data = json_decode($res['data'],1);
$to_tpl = compact('it_data','res','id');
$to_tpl['md_cont'] = (isset($it_data['md_cont'])) ? $it_data['md_cont'] : '';
return LE::$TPL->fetch('le_ui_kit/test_ckeditor',$to_tpl);
//return LE::$TPL->fetch('le_ui_kit/test_editor',$to_tpl);
}
}
//echo_arr($le_mod_loader->url);
$controller = new CONTR($le_mod_loader->url);
//$mod_out = $controller->start();
LE::$TPL->mod_cont .= $controller->start();

@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>LE UIKit</title>
<link rel="stylesheet" type="text/css" href="/assets/css/le_uikit.css" />
<meta name="viewport" content="width=device-width,initial-scale=1">
<?/*
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
*/?>
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js"></script>
<link rel="stylesheet" href="/pub/css/le_form.css">
<script src="https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js"></script>
<!-- Editor's Dependecy Style -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/codemirror.min.css"
/>
<!-- Editor's Style -->
<link rel="stylesheet" href="https://uicdn.toast.com/editor/latest/toastui-editor.min.css" />
</head>
<body>
<div id="page_cont" style="max-width:1000px;margin:10px auto;padding:10px;">
<button type="button" class="btn btn-primary">Button</button>
<form class="le_form le_shadow">
<span class="le_form_head">Заголовок формы</span>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Горизонтальный инпут</span></label>
<div class="le_inp"><input type="text" value="kokoko" id="inp_name"></div>
</div>
<div class="le_ve">
<label for="inp_name" class="le_fl"><span>Вертикальный инпут</span></label>
<div class="le_inp"><input type="text" value="kokoko" id="inp_name"></div>
</div>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Горизонтальный инпут у которого допустим пару строчек, строчки тут две <sup>*</sup></span></label>
<div class="le_inp"><input type="text" value="kokoko" id="inp_name"></div>
</div>
<div class="le_he">
<div for="select_koko" class="le_fl"><span>Горизонтальный селект</span></div>
<div class="le_inp">
<select id="select_koko">
<option>select</option>
<option>select</option>
<option>select</option>
<option>select</option>
<option>select</option>
</select>
</div>
</div>
<div class="le_he le_me">
<div for="inp_name" class="le_fl"><span>Радиокнопки</span></div>
<div class="le_inp">
<label><input type="radio" name="radio1">Radio1</label>
<label><input type="radio" name="radio1">Radio2</label>
</div>
</div>
<div class="le_ve le_me">
<div for="inp_name" class="le_fl"><span>Радиокнопки вертикально</span></div>
<div class="le_inp">
<label><input type="radio" name="radio1">Radio1</label>
<label><input type="radio" name="radio1">Radio2</label>
</div>
</div>
<div class="le_he le_me">
<div for="inp_name" class="le_fl"><span>Чекбоксы<sup>*</sup></span></div>
<div class="le_inp">
<label><input type="checkbox" name="checkbox1">checkbox1</label>
<label><input type="checkbox" name="checkbox1">checkbox2</label>
</div>
</div>
<div class="le_he le_me le_meh">
<div for="inp_name" class="le_fl"><span>Радиокнопки в линию</span></div>
<div class="le_inp">
<label><input type="radio" name="radio1">Radio1</label>
<label><input type="radio" name="radio1">Radio2</label>
</div>
</div>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Дата <sup>*</sup></span></label>
<div class="le_inp"><input type="date" value="kokoko" id="inp_name"></div>
</div>
<div class="le_ve">
<label for="inp_name" class="le_fl"><span>Текст</span></label>
<div class="le_inp"><textarea class="cktxt">тролололо</textarea></div>
</div>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Текст горизонтально</span></label>
<div class="le_inp"><textarea>тролололо</textarea></div>
</div>
<div class="le_ve">
<label for="inp_name" class="le_fl"><span>Текст</span></label>
<div class="le_inp"><textarea class="tu-editor">тролололо</textarea></div>
</div>
<div class="le_bbl">
<button type="submit">Сохранить</button>
<button class="le_btn_blue" type="submit">Синяя</button>
<button class="le_btn_red" type="submit">Красная</button>
<button class="le_btn_green" type="submit">Зеленая</button>
</div>
</form>
<br>
<br>
<br>
<br>
<h2>Markdown Editor from ToastUI</h2>
<div id="editor"></div>
<a href="#" onclick="alert(editor.getHtml()); return false;">html get</a> |
<a href="#" onclick="alert(editor.getMarkdown()); return false;">markdown get</a> |
<a href="#" onclick="hljs.highlightAll(); return false;">Code hilight</a> |
</div>
<script>
/*ClassicEditor
.create( document.querySelector( '.cktxt' ) )
.then( editor => {
console.log( editor );
} )
.catch( error => {
console.error( error );
} );
*/
</script>
<script src="https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js"></script>
<script>
const editor = new toastui.Editor({
el: document.querySelector('#editor'),
previewStyle: 'vertical',
height: '500px',
initialValue: '### hello world \n```\n<?="<?"?>php\n```'
});
editor.on('change',function(e){
/*hljs.highlightAll();*/
document.querySelectorAll('div.te-preview pre').forEach(block => {
// then highlight each
hljs.highlightBlock(block);
});
});
</script>
</body>
</html>

@ -0,0 +1,33 @@
<?php
/*
1. Подключить нужные для модуля классы и конфиги
2. Определить какой метод контроллера выполнить и запустить его
3. Внутри метода идет вывод или запись данных, при выводе передается в шаблон
4. Содержимое
*/
//compute
//if (isset($_POST)) echo_arr($_POST);
//if (isset($_FILES)) echo_arr($_FILES);
if (isset($_FILES['upl_img']))
{
$uploaddir = WEBDIR.'pub_data/upload/img/';
$f_name=basename($_FILES['upl_img']['name']);
$uploadfile = $uploaddir . basename($_FILES['upl_img']['name']);
if (move_uploaded_file($_FILES['upl_img']['tmp_name'], $uploadfile))
{
$out = ['success'=>1];
$out['data'] = ['url'=>'/pub_data/upload/img/'.$f_name];
$mod_out = json_encode($out);
}
}
else
$mod_out = LE::$TPL->fetch('le_ui_kit/test1');
//out to tpl
LE::$TPL->mod_cont .= $mod_out;

@ -0,0 +1 @@
Добро пожаловать в новый мир!!!

@ -0,0 +1,275 @@
/*sys*/
body {
font-family: sans-serif;
}
/*reset form*/
input, select, button, textarea {
border:1px solid #b8b8b8;
border-radius: 0;
-webkit-border-radius: 0px;
border-radius:0;
padding:1px 5px;
height: 40px;
box-sizing: border-box;
font-family: inherit;
font-size:16px;
}
textarea {
min-height: 200px;
padding:8px 8px;
}
select {
-webkit-appearance: none;
-moz-appearance: none;
padding-right: 20px;
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2224%22%20height%3D%2216%22%20viewBox%3D%220%200%2024%2016%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23666%22%20points%3D%2212%201%209%206%2015%206%22%20%2F%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23666%22%20points%3D%2212%2013%209%208%2015%208%22%20%2F%3E%0A%3C%2Fsvg%3E%0A")
,
linear-gradient(to bottom, #ffffff 0%,#ffffff 100%);
background-repeat: no-repeat;
/*background-position: 100% 50%;*/
background-size: 30px auto, 100%;
background-position: right -5px top 50%, 0 0;
}
input[type=radio], input[type=checkbox]
{
display: inline-block;
height: 16px;
width: 16px;
overflow: hidden;
margin-top: -1px;
vertical-align: middle;
-webkit-appearance: none;
-moz-appearance: none;
background-color: transparent;
background-repeat: no-repeat;
background-position: 50% 50%;
border: 1px solid #ccc;
transition: .2s ease-in-out;
transition-property: all;
transition-property: background-color,border;
margin-right: 4px;
}
input[type=radio] {
border-radius: 50%;
margin-top: -4px;
}
input[type=radio]:checked {
background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Ccircle%20fill%3D%22%23fff%22%20cx%3D%228%22%20cy%3D%228%22%20r%3D%222%22%20%2F%3E%0A%3C%2Fsvg%3E");
background-color: #1e87f0;
border-color: transparent;
background-size: 30px auto;
}
input[type=checkbox]:checked {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2214%22%20height%3D%2211%22%20viewBox%3D%220%200%2014%2011%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23fff%22%20points%3D%2212%201%205%207.5%202%205%201%205.5%205%2010%2013%201.5%22%20%2F%3E%0A%3C%2Fsvg%3E%0A");
background-color: #1e87f0;
border-color: transparent;
}
input:focus:not([type="checkbox"]):not([type="radio"]), select:focus, textarea:focus {
outline: none;
border-color:#70aae4;
box-shadow: inset 0 0 3px -2px #117de9;
}
/*form blocks style*/
.le_form {
display: block;
overflow: hidden;
margin: 10px 0;
padding:25px;
color:#555;
}
.le_form_head {
display: block;
font-size: 150%;
padding-bottom: 10px;
border-bottom: 1px solid #d9d9d9;
margin-bottom: 20px;
}
.le_shadow {
box-shadow: 0 2px 10px rgba(94, 94, 94, 0.08);
border:1px solid #ececec;
}
.le_he .le_inp {
margin-left:300px;
}
.le_fl {
font-size: 14px;
}
.le_he .le_fl {
width:290px;
float:left;
display: flex;
align-items: center;
min-height: 40px;
}
.le_he, .le_ve {
margin-bottom: 25px;
overflow: hidden;
border-bottom: 1px solid #e9e9e9;
padding-bottom: 25px;
}
.le_ve .le_fl {
margin-bottom: 3px;
display: block;
}
.le_inp input:not([type="checkbox"]):not([type="radio"]),
.le_inp select,
.le_inp textarea
{
max-width: 100%;
width:100%;
}
/*le multi elements*/
.le_me label{
display: block;
padding-top:8px;
}
/*Multi Element Horizontal*/
.le_meh label{
float:left;
margin-right:10px;
}
.le_he {
display:flex;
flex-wrap: wrap;
}
.le_he .le_fl {
min-width: 200px;
flex:40%;
flex-grow: 1;
}
.le_he .le_inp {
margin-left:0;
flex-grow: 1; /*растягиваться на свободное пространство*/
min-width: 200px;
flex:60%;
}
.le_fl sup {
color:red;
font-size: 17px;
font-weight: bold;
padding-left: 2px;
}
/*buttons*/
.le_btn {
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border: 1px solid #c9c9c9;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
background-color: #f9f9f9;
background: linear-gradient(to bottom, #f9f9f9,#f9f9f9);
}
.le_btn:hover {
background: linear-gradient(to bottom, #f9f9f9,#f3f3f3);
border-color:#b5b5b5;
}
/*гамбургеры и крестики*/
#nav-icon6 {
width: 60px;
height: 45px;
position: relative;
transition-duration: 1s;
margin: 48px auto 12px auto;
cursor: pointer;
}
#nav-icon6 span {
height: 9px;
width: 60px;
background-color: #337AB7;
border-radius: 20px;
position: absolute;
transition-duration: .25s;
transition-delay: .25s;
}
#nav-icon6 span:before {
left: 0;
position: absolute;
top: -18px;
height: 9px;
width: 60px;
background-color: #337AB7;
content: "";
border-radius: 20px;
transition-duration: .25s;
transition: transform .25s, top .25s .25s;
}
#nav-icon6 span:after {
left: 0;
position: absolute;
top: 18px;
height: 9px;
width: 60px;
background-color: #337AB7;
content: "";
border-radius: 20px;
transition-duration: .25s;
transition: transform .25s, top .25s .25s;
}
#nav-icon6.open span {
transition-duration: 0.1s;
transition-delay: .25s;
background: transparent;
}
#nav-icon6.open span:before {
transition: top .25s, transform .25s .25s;
top: 0px;
transform: rotateZ(-45deg);
}
#nav-icon6.open span:after {
transition: top 0.4s, transform .25s .25s;
top: 0px;
transform: rotateZ(45deg);
}

@ -0,0 +1 @@
body{font-family:sans-serif}button,input,select,textarea{border:1px solid #b8b8b8;border-radius:0;-webkit-border-radius:0;border-radius:0;padding:1px 5px;height:40px;box-sizing:border-box;font-family:inherit;font-size:16px}textarea{min-height:200px;padding:8px 8px}select{-webkit-appearance:none;-moz-appearance:none;padding-right:20px;background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2224%22%20height%3D%2216%22%20viewBox%3D%220%200%2024%2016%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23666%22%20points%3D%2212%201%209%206%2015%206%22%20%2F%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23666%22%20points%3D%2212%2013%209%208%2015%208%22%20%2F%3E%0A%3C%2Fsvg%3E%0A"),linear-gradient(to bottom,#fff 0,#fff 100%);background-repeat:no-repeat;background-size:30px auto,100%;background-position:right -5px top 50%,0 0}input[type=checkbox],input[type=radio]{display:inline-block;height:16px;width:16px;overflow:hidden;margin-top:-1px;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;background-color:transparent;background-repeat:no-repeat;background-position:50% 50%;border:1px solid #ccc;transition:.2s ease-in-out;transition-property:all;transition-property:background-color,border;margin-right:4px}input[type=radio]{border-radius:50%;margin-top:-4px}input[type=radio]:checked{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Ccircle%20fill%3D%22%23fff%22%20cx%3D%228%22%20cy%3D%228%22%20r%3D%222%22%20%2F%3E%0A%3C%2Fsvg%3E");background-color:#1e87f0;border-color:transparent;background-size:30px auto}input[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2214%22%20height%3D%2211%22%20viewBox%3D%220%200%2014%2011%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23fff%22%20points%3D%2212%201%205%207.5%202%205%201%205.5%205%2010%2013%201.5%22%20%2F%3E%0A%3C%2Fsvg%3E%0A");background-color:#1e87f0;border-color:transparent}input:focus:not([type=checkbox]):not([type=radio]),select:focus,textarea:focus{outline:0;border-color:#70aae4;box-shadow:inset 0 0 3px -2px #117de9}.le_form{display:block;overflow:hidden;margin:10px 0;padding:25px;color:#555}.le_form_head{display:block;font-size:150%;padding-bottom:10px;border-bottom:1px solid #d9d9d9;margin-bottom:20px}.le_shadow{box-shadow:0 2px 10px rgba(94,94,94,.08);border:1px solid #ececec}.le_he .le_inp{margin-left:300px}.le_fl{font-size:14px}.le_he .le_fl{width:290px;float:left;display:flex;align-items:center;min-height:40px}.le_he,.le_ve{margin-bottom:25px;overflow:hidden;border-bottom:1px solid #e9e9e9;padding-bottom:25px}.le_ve .le_fl{margin-bottom:3px;display:block}.le_inp input:not([type=checkbox]):not([type=radio]),.le_inp select,.le_inp textarea{max-width:100%;width:100%}.le_me label{display:block;padding-top:8px}.le_meh label{float:left;margin-right:10px}.le_he{display:flex;flex-wrap:wrap}.le_he .le_fl{min-width:200px;flex:40%;flex-grow:1}.le_he .le_inp{margin-left:0;flex-grow:1;min-width:200px;flex:60%}.le_fl sup{color:red;font-size:17px;font-weight:700;padding-left:2px}.le_btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid #c9c9c9;padding:.375rem .75rem;font-size:1rem;line-height:1.5;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;background-color:#f9f9f9;background:linear-gradient(to bottom,#f9f9f9,#f9f9f9)}.le_btn:hover{background:linear-gradient(to bottom,#f9f9f9,#f3f3f3);border-color:#b5b5b5}#nav-icon6{width:60px;height:45px;position:relative;transition-duration:1s;margin:48px auto 12px auto;cursor:pointer}#nav-icon6 span{height:9px;width:60px;background-color:#337ab7;border-radius:20px;position:absolute;transition-duration:.25s;transition-delay:.25s}#nav-icon6 span:before{left:0;position:absolute;top:-18px;height:9px;width:60px;background-color:#337ab7;content:"";border-radius:20px;transition-duration:.25s;transition:transform .25s,top .25s .25s}#nav-icon6 span:after{left:0;position:absolute;top:18px;height:9px;width:60px;background-color:#337ab7;content:"";border-radius:20px;transition-duration:.25s;transition:transform .25s,top .25s .25s}#nav-icon6.open span{transition-duration:.1s;transition-delay:.25s;background:0 0}#nav-icon6.open span:before{transition:top .25s,transform .25s .25s;top:0;transform:rotateZ(-45deg)}#nav-icon6.open span:after{transition:top .4s,transform .25s .25s;top:0;transform:rotateZ(45deg)}

@ -0,0 +1,369 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0-modified | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* make sure to set some focus styles for accessibility */
:focus {
outline: 0;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
input[type=search]::-webkit-search-cancel-button,
input[type=search]::-webkit-search-decoration,
input[type=search]::-webkit-search-results-button,
input[type=search]::-webkit-search-results-decoration {
-webkit-appearance: none;
-moz-appearance: none;
}
input[type=search] {
-webkit-appearance: none;
-moz-appearance: none;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
textarea {
overflow: auto;
vertical-align: top;
resize: vertical;
}
/**
* Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
*/
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
max-width: 100%;
}
/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.
* Known issue: no IE 6 support.
*/
[hidden] {
display: none;
}
/**
* 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using
* `em` units.
* 2. Prevent iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-size: 100%; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-ms-text-size-adjust: 100%; /* 2 */
}
/**
* Address `outline` inconsistency between Chrome and other browsers.
*/
a:focus {
outline: thin dotted;
}
/**
* Improve readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/**
* 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.
* 2. Improve image quality when scaled in IE 7.
*/
img {
border: 0; /* 1 */
-ms-interpolation-mode: bicubic; /* 2 */
}
/**
* Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11.
*/
figure {
margin: 0;
}
/**
* Correct margin displayed oddly in IE 6/7.
*/
form {
margin: 0;
}
/**
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct color not being inherited in IE 6/7/8/9.
* 2. Correct text not wrapping in Firefox 3.
* 3. Correct alignment displayed oddly in IE 6/7.
*/
legend {
border: 0; /* 1 */
padding: 0;
white-space: normal; /* 2 */
*margin-left: -7px; /* 3 */
}
/**
* 1. Correct font size not being inherited in all browsers.
* 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5,
* and Chrome.
* 3. Improve appearance and consistency in all browsers.
*/
button,
input,
select,
textarea {
font-size: 100%; /* 1 */
margin: 0; /* 2 */
vertical-align: baseline; /* 3 */
*vertical-align: middle; /* 3 */
}
/**
* Address Firefox 3+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
button,
input {
line-height: normal;
border-radius: 0;
border: 1px solid rgb(187, 183, 183);
background: #fff;
}
/**
* Address inconsistent `text-transform` inheritance for `button` and `select`.
* All other form control elements do not inherit `text-transform` values.
* Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+.
* Correct `select` style inheritance in Firefox 4+ and Opera.
*/
button,
select {
text-transform: none;
}
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
* 4. Remove inner spacing in IE 7 without affecting normal text inputs.
* Known issue: inner spacing remains in IE 6.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
*overflow: visible; /* 4 */
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
html input[disabled] {
cursor: default;
}
/**
* 1. Address box sizing set to content-box in IE 8/9.
* 2. Remove excess padding in IE 8/9.
* 3. Remove excess padding in IE 7.
* Known issue: excess padding remains in IE 6.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
*height: 13px; /* 3 */
*width: 13px; /* 3 */
}
/**
* 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/**
* Remove inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Remove inner padding and border in Firefox 3+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/**
* 1. Remove default vertical scrollbar in IE 6/7/8/9.
* 2. Improve readability and alignment in all browsers.
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/**
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
html,
button,
input,
select,
textarea {
color: #222;
}
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
img {
vertical-align: middle;
}
fieldset {
border: 0;
margin: 0;
padding: 0;
}
textarea {
resize: vertical;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}

@ -0,0 +1 @@
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}:focus{outline:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{-webkit-appearance:none;-moz-appearance:none}input[type=search]{-webkit-appearance:none;-moz-appearance:none;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}textarea{overflow:auto;vertical-align:top;resize:vertical}audio,canvas,video{display:inline-block;max-width:100%}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted}a:active,a:hover{outline:0}img{border:0;-ms-interpolation-mode:bicubic}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline}button,input{line-height:normal;border-radius:0;border:1px solid #bbb7b7;background:#fff}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}button,html,input,select,textarea{color:#222}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}img{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}

@ -0,0 +1,153 @@
/*text block*/
.txt_cont
{
overflow: hidden;
font-size: 20px;
color:#404040;
}
/*heading*/
.txt_cont h1 {font-size:2em;}
.txt_cont h2 {font-size:1.6em;}
.txt_cont h3 {font-size:1.4em;}
.txt_cont h4 {font-size:1.1em;}
.txt_cont p {
/*text-indent:1em;*/
font-size: 1em;
line-height: 1.5em;
}
/*image*/
.txt_cont img {
display: block;
margin: 0 auto;
max-width: 100%;
min-width: 50px;
}
.txt_cont .image {
display: table;
clear: both;
text-align: center;
margin: 1em auto;
/*border: 1px solid #e6e6e6;*/
box-shadow: 0 0 6px 1px #aeaeae;
}
/*image float*/
.ck-content .image-style-side,
.txt_cont .image-style-side
{
float:right;
margin-left:1.5em;
margin-top:0.2em !important;
}
.txt_cont .image > figcaption {
display:table-caption;
caption-side: bottom;
word-break: break-word;
color: #333;
background-color: #f7f7f7;
padding: .6em;
font-size: .75em;
outline-offset: -1px;
box-shadow: 0 0 6px 1px #aeaeae;
}
.txt_cont figure.table {margin:0;}
/*video*/
.txt_cont .media {
clear: both;
margin: 1em 0;
display: block;
min-width: 15em;
}
.txt_cont figure.table
{
display: table;
}
.ck-content .table table td,
.ck-content .table table th,
.txt_cont .table table td,
.txt_cont .table table th
{
min-width: 2em;
padding: .4em;
border: 1px solid #bfbfbf;
}
.txt_cont table { border-collapse: collapse; width: 100%; }
.ck-content .table table th ,
.txt_cont .table table th
{
font-weight: 700;
background: hsla(0,0%,0%,5%);
}
.txt_cont .table th {
text-align: left;
}
.txt_cont hr {
margin: 15px 0;
height: 4px;
background: #dedede;
border: 0;
}
.txt_cont code {
background-color: hsla(0,0%,78%,.3);
padding: .15em;
border-radius: 2px;
}
.txt_cont pre {
padding: 1em;
color: #353535;
background: hsla(0,0%,78%,.3);
border: 1px solid #c4c4c4;
border-radius: 2px;
text-align: left;
direction: ltr;
tab-size: 4;
white-space: pre-wrap;
font-style: normal;
min-width: 200px;
position: relative;
}
.txt_cont pre code {
background-color: transparent;
}
.txt_cont ul {
list-style-type: disc;
padding-left:18px;
}
.txt_cont blockquote {
overflow: hidden;
padding-right: 1.5em;
padding-left: 1.5em;
margin-left: 0;
margin-right: 0;
font-style: italic;
border-left: 5px solid #ccc;
}

@ -0,0 +1 @@
.txt_cont{overflow:hidden;font-size:20px;color:#404040}.txt_cont h1{font-size:2em}.txt_cont h2{font-size:1.6em}.txt_cont h3{font-size:1.4em}.txt_cont h4{font-size:1.1em}.txt_cont p{font-size:1em;line-height:1.5em}.txt_cont img{display:block;margin:0 auto;max-width:100%;min-width:50px}.txt_cont .image{display:table;clear:both;text-align:center;margin:1em auto;box-shadow:0 0 6px 1px #aeaeae}.ck-content .image-style-side,.txt_cont .image-style-side{float:right;margin-left:1.5em;margin-top:.2em!important}.txt_cont .image>figcaption{display:table-caption;caption-side:bottom;word-break:break-word;color:#333;background-color:#f7f7f7;padding:.6em;font-size:.75em;outline-offset:-1px;box-shadow:0 0 6px 1px #aeaeae}.txt_cont figure.table{margin:0}.txt_cont .media{clear:both;margin:1em 0;display:block;min-width:15em}.txt_cont figure.table{display:table}.ck-content .table table td,.ck-content .table table th,.txt_cont .table table td,.txt_cont .table table th{min-width:2em;padding:.4em;border:1px solid #bfbfbf}.txt_cont table{border-collapse:collapse;width:100%}.ck-content .table table th,.txt_cont .table table th{font-weight:700;background:hsla(0,0%,0%,5%)}.txt_cont .table th{text-align:left}.txt_cont hr{margin:15px 0;height:4px;background:#dedede;border:0}.txt_cont code{background-color:hsla(0,0%,78%,.3);padding:.15em;border-radius:2px}.txt_cont pre{padding:1em;color:#353535;background:hsla(0,0%,78%,.3);border:1px solid #c4c4c4;border-radius:2px;text-align:left;direction:ltr;tab-size:4;white-space:pre-wrap;font-style:normal;min-width:200px;position:relative}.txt_cont pre code{background-color:transparent}.txt_cont ul{list-style-type:disc;padding-left:18px}.txt_cont blockquote{overflow:hidden;padding-right:1.5em;padding-left:1.5em;margin-left:0;margin-right:0;font-style:italic;border-left:5px solid #ccc}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,34 @@
le_crud = {
rem: function(id,el_id)
{
u = window.location.href;
el = document.querySelector(el_id);
if (typeof el !=='object') return false;
data = {id:id,method:"remove_it"};
if(!confirm("Удалить статью?")) return false;
fetch(u,
{
method: 'POST',
body: JSON.stringify(data),
headers: {'Content-Type': 'application/json'}
}
).then ((resp)=>{return resp.json()}).then
((resp)=>{
if (!resp.success) {alert('Произошла ошибка!'); return false;}
el.remove();
});
}
}

@ -0,0 +1 @@
le_crud={rem:function(id,el_id){return u=window.location.href,el=document.querySelector(el_id),"object"==typeof el&&(data={id:id,method:"remove_it"},!!confirm("Удалить статью?")&&void fetch(u,{method:"POST",body:JSON.stringify(data),headers:{"Content-Type":"application/json"}}).then(resp=>resp.json()).then(resp=>{if(!resp.success)return alert("Произошла ошибка!"),!1;el.remove()}))}};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,162 @@
<?$tpl->need_static(['-tui-editor','jquery','le_form','ckeditor5','highlight.js','txt_cont'])?>
<a href="/admin/blog">Назад к списку</a>
<h2>Редактор статьи</h2>
<div id="editor" class="txt_cont">
<h1><?=$head?></h1>
<?=$html_cont?>
</div>
<button onclick="save_cont();">Сохранить</button>
<div id="result_cont" class="txt_cont">
load
</div>
<script>
editor = false;
function save_cont()
{
cont_html = editor.getData();
//cont_body = cont_html.getTitle();
//alert(cont_body);
const formData = new FormData();
formData.append('clear', 'yes');
formData.append('ajax', 'yes');
formData.append('mod', 'save_content');
formData.append('data[html_cont]', cont_html);
formData.append('data[id]', <?=$id?>);
fetch('/admin/blog', {method: 'POST',body: formData}).then((resp)=>{return resp.json()}).then(
(resp)=>{
if (!resp.success) return false;
window.location.href="/admin/blog/";
}
);
//alert(response);
//console.log(response);
}
window.addEventListener('load', (event) =>
{
var options = {
toolbar: {
items: [
'bold',
'italic',
'underline',
'strikethrough',
'link',
'subscript',
'superscript',
'-',
'code',
'fontColor',
'removeFormat',
'undo',
'redo'
],
shouldNotGroupWhenFull: true
},
language: 'ru',
blockToolbar: [
'codeBlock',
'horizontalLine',
'htmlEmbed',
'imageUpload',
'imageInsert',
'indent',
'outdent',
'numberedList',
'bulletedList',
'blockQuote',
'mediaEmbed',
'insertTable',
'alignment'
],
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:full',
'imageStyle:side',
'linkImage'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'tableCellProperties',
'tableProperties'
]
},
licenseKey: '',
mediaEmbed: {previewsInData:true},
simpleUpload: {uploadUrl: '/admin/blog'}
};
BalloonBlockEditor
.create( document.querySelector( '#editor' ), options )
.then( editor => {
window.editor = editor;
document.querySelector( '#result_cont' ).innerHTML=editor.getData();
editor.model.document.on( 'change:data', () =>
{
console.log( 'The data has changed!' );
document.querySelector( '#result_cont' ).innerHTML=editor.getData();
}
);
} )
.catch( error => {
console.error( 'Oops, something went wrong!' );
console.error( 'Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:' );
console.warn( 'Build id: 9v07c6uegbjg-a3pt58397xor' );
console.error( error );
} );
});
</script>
<style>
#editor,
.txt_cont {
border: 1px solid #d0d0d0;
padding: 20px 30px;
margin-top:40px;
}
</style>

@ -0,0 +1,47 @@
<?$tpl->need_static(['-tui-editor','jquery','le_form','ckeditor5','highlight.js','txt_cont','le_crud'])?>
<h2>Список статей</h2>
<a href="/admin/blog/edit:0">Создать</a>
<?foreach($cont_list as $id=>$cont):?>
<div href="/admin/blog/edit:<?=$id?>" class="el_cont" id="el_<?=$id?>">
<h3><a href="/admin/blog/edit:<?=$id?>"><?=empty($cont['head'])?"Статья ".$id: $cont['head']?></a>
<button style="" onclick="le_crud.rem(<?=$id?>,'#el_<?=$id?>')">Удалить</button>
</h3>
<div class="el_cont_content txt_cont">
<?=$cont['html']?>
</div>
</div>
<?endforeach;?>
<style>
.el_cont {
text-decoration:none;
display:block;
color:inherit;
border:1px solid #d0d0d0;
margin: 20px;
padding: 20px;
}
.el_cont:hover {background:#fafafa;}
.el_cont_content {border: 2px dotted #d9d9d9;padding:10px;}
</style>
<script>
window.addEventListener('load', (event) =>
{
document.querySelectorAll('pre code').forEach((block) => {
hljs.highlightElement(block);
});
});
</script>

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?=$tpl->meta['title'];?></title>
<meta name="description" content="<?=$tpl->meta['description'];?>">
<meta name="keywords" content="<?=$tpl->meta['keywords'];?>">
<meta name="viewport" content="width=device-width,initial-scale=1">
<?=$tpl->head_cont;?>
</head>
<body>
<?=$tpl->cont_top;?>
<?=$tpl->fetch('main_body');?>
<?=$tpl->cont_bottom;?>
</body>
</html>

@ -0,0 +1,4 @@
<!--тут будет шапка и меню...-->
<div class="page_cont" style="max-width:1000px; margin:20px auto;">
<?=$tpl->mod_cont;?>
</div>

@ -0,0 +1,66 @@
<?php
$st_cnf = &LE::$TPL->static_list;
$st_dep = &LE::$TPL->static_dep;
$st_cnf[] = [
'mod'=>'highlight.js',
'pos'=>'top',
'type'=>'css',
'link'=>'//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css'];
$st_cnf[] = [
'mod'=>'highlight.js',
'pos'=>'bottom',
'type'=>'js',
'link'=>'//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js'];
$st_cnf[] = [
'mod'=>'le_form',
'type'=>'css',
'link'=>'/pub/css/le_form.css'];
$st_cnf[] = [
'mod'=>'ckeditor5',
'type'=>'js',
'link'=>'/pub/js/ckeditor5.js'];
$st_cnf[] = [
'mod'=>'codemirror',
'type'=>'css',
'link'=>'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/codemirror.min.css'];
$st_cnf[] = [
'mod'=>'tui-editor',
'type'=>'css',
'link'=>'https://uicdn.toast.com/editor/latest/toastui-editor.min.css'];
$st_cnf[] = [
'mod'=>'tui-editor',
'type'=>'js',
'link'=>'https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js'
//'link'=>'/pub/js/tui-editor.js'
];
$st_cnf[] = [
'mod'=>'jquery',
'type'=>'js',
'link'=>'https://code.jquery.com/jquery-3.6.0.slim.min.js'];
$st_cnf[] = [
'mod'=>'txt_cont',
'type'=>'css',
'link'=>'/pub/css/txt_cont.css'];
$st_cnf[] = [
'mod'=>'embedly',
'type'=>'js',
'link'=>'//cdn.embedly.com/widgets/platform.js'];
$st_cnf[] = [
'mod'=>'le_crud',
'type'=>'js',
'link'=>'/pub/js/le_crud.js'];
$st_dep['tui-editor']=['codemirror','oth'];

@ -0,0 +1,31 @@
<?$tpl->need_static(['-tui-editor','jquery','le_form','ckeditor5','highlight.js'])?>
<h2>Список статей</h2>
<?foreach($cont_list as $id=>$cont):?>
<a href="/editor_test/edit:<?=$id?>" class="el_cont">
<h3>Статья <?=$id?></h3>
<div class="el_cont_content">
<?=$cont['html']?>
</div>
</a>
<?endforeach;?>
<style>
.el_cont {
text-decoration:none;
display:block;
color:inherit;
border:1px solid #d0d0d0;
margin: 20px;
padding: 20px;
}
.el_cont:hover {background:#fafafa;}
.el_cont_content {border: 2px dotted #d9d9d9;padding:10px;}
</style>

@ -0,0 +1,213 @@
<?$tpl->need_static(['tui-editor','jquery','le_form','ckeditor5','highlight.js'])?>
<form class="le_form le_shadow">
<span class="le_form_head">Заголовок формы</span>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Горизонтальный инпут</span></label>
<div class="le_inp"><input type="text" value="kokoko" id="inp_name"></div>
</div>
<div class="le_ve">
<label for="inp_name" class="le_fl"><span>Вертикальный инпут</span></label>
<div class="le_inp"><input type="text" value="kokoko" id="inp_name"></div>
</div>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Горизонтальный инпут у которого допустим пару строчек, строчки тут две <sup>*</sup></span></label>
<div class="le_inp"><input type="text" value="kokoko" id="inp_name"></div>
</div>
<div class="le_he">
<div for="select_koko" class="le_fl"><span>Горизонтальный селект</span></div>
<div class="le_inp">
<select id="select_koko">
<option>select</option>
<option>select</option>
<option>select</option>
<option>select</option>
<option>select</option>
</select>
</div>
</div>
<div class="le_he le_me">
<div for="inp_name" class="le_fl"><span>Радиокнопки</span></div>
<div class="le_inp">
<label><input type="radio" name="radio1">Radio1</label>
<label><input type="radio" name="radio1">Radio2</label>
</div>
</div>
<div class="le_ve le_me">
<div for="inp_name" class="le_fl"><span>Радиокнопки вертикально</span></div>
<div class="le_inp">
<label><input type="radio" name="radio1">Radio1</label>
<label><input type="radio" name="radio1">Radio2</label>
</div>
</div>
<div class="le_he le_me">
<div for="inp_name" class="le_fl"><span>Чекбоксы<sup>*</sup></span></div>
<div class="le_inp">
<label><input type="checkbox" name="checkbox1">checkbox1</label>
<label><input type="checkbox" name="checkbox1">checkbox2</label>
</div>
</div>
<div class="le_he le_me le_meh">
<div for="inp_name" class="le_fl"><span>Радиокнопки в линию</span></div>
<div class="le_inp">
<label><input type="radio" name="radio1">Radio1</label>
<label><input type="radio" name="radio1">Radio2</label>
</div>
</div>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Дата <sup>*</sup></span></label>
<div class="le_inp"><input type="date" value="kokoko" id="inp_name"></div>
</div>
<div class="le_ve">
<label for="inp_name" class="le_fl"><span>Текст</span></label>
<div class="le_inp"><textarea class="cktxt">тролололо</textarea></div>
</div>
<div class="le_he">
<label for="inp_name" class="le_fl"><span>Текст горизонтально</span></label>
<div class="le_inp"><textarea>тролололо</textarea></div>
</div>
<div class="le_ve">
<label for="inp_name" class="le_fl"><span>Текст</span></label>
<div class="le_inp"><textarea class="tu-editor">тролололо</textarea></div>
</div>
<div class="le_bbl">
<button class="le_btn" type="submit">Сохранить</button>
<button class="le_btn le_btn_blue" type="submit">Синяя</button>
<button class="le_btn le_btn_red" type="submit">Красная</button>
<button class="le_btn le_btn_green" type="submit">Зеленая</button>
</div>
</form>
<br>
<br>
<br>
<br>
<h2>Markdown Editor from ToastUI</h2>
<div id="editor"></div>
<a href="#" onclick="alert(editor.getHtml()); return false;">html get</a> |
<a href="#" onclick="alert(editor.getMarkdown()); return false;">markdown get</a> |
<a href="#" onclick="hljs.highlightAll(); return false;">Code hilight</a> |
<script>
window.addEventListener('load', (event) =>
{
function uploadImage(blob) {
let formData = new FormData();
formData.append("upl_img", blob, blob.name);
formData.append("opt", 'upload_img');
formData.append("clear", 'yes');
return fetch('/ui_test', {
method: 'POST',
body: formData
}).then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Server or network error');
});
};
function onAddImageBlob(blob, callback) {
uploadImage(blob)
.then(response => {
if (!response.success) {
throw new Error('Validation error');
}
callback(response.data.url, 'alt text');
}).catch(error => {
console.log(error);
});
};
const editor = new toastui.Editor({
el: document.querySelector('#editor'),
previewStyle: 'vertical',
height: '500px',
initialValue: '### hello world \n```\n<?="<?"?>php\n```',
hooks:
{
addImageBlobHook:function(blob, callback)
{
let formData = new FormData();
formData.append("upl_img", blob, blob.name);
formData.append("opt", 'upload_img');
formData.append("clear", 'yes');
fetch('/ui_test', {method: 'POST',body: formData
}).then(resp => resp.json()).then(resp=>{
if (!resp.success) {throw new Error('Validation error');}
callback(resp.data.url, 'alt text');
});
}
}
});
editor.on('change',function(e){
document.querySelectorAll('div.te-preview pre').forEach(block => {hljs.highlightBlock(block);});
});
hljs.highlightAll();
$(function() {
$('#nav-icon6').click(function(){
$(this).toggleClass('open');
});
});
});
</script>
<hr/>
<button class="c-hamburger c-hamburger--rot">
<span>toggle menu</span>
</button>
<button class="c-hamburger c-hamburger--htx">
<span>toggle menu</span>
</button>
<button class="c-hamburger c-hamburger--htla">
<span>toggle menu</span>
</button>
<button class="c-hamburger c-hamburger--htra">
<span>toggle menu</span>
</button>
<div id="nav-icon6">
<span></span>
</div>

@ -0,0 +1,26 @@
<?$tpl->need_static(['tui-editor','jquery','le_form','ckeditor5','highlight.js'])?>
<a href="/editor_test">Назад к списку</a>
<h2>Редактор статьи</h2>
<div class="txt_cont" id="editor" style="overflow:hidden;">
kokoko
</div>
<script>
window.addEventListener('load', (event) =>
{
ClassicEditor.create( document.querySelector( '#editor' ) )
.catch( error => {
console.error( error );
} );
/* editor.on('change',function(e){
document.querySelectorAll('div.te-preview pre').forEach(block => {hljs.highlightElement(block);});
});*/
hljs.highlightAll();
});
</script>

@ -0,0 +1,128 @@
<?$tpl->need_static(['tui-editor','jquery','le_form','ckeditor5','highlight.js'])?>
<a href="/editor_test">Назад к списку</a>
<h2>Редактор статьи</h2>
<div id="editor" style="overflow:hidden;"></div>
<a href="#" onclick="alert(editor.getHtml()); return false;">html get</a> |
<a href="#" onclick="alert(editor.getMarkdown()); return false;">markdown get</a>
<button onclick="save_md_cont();">Сохранить</button>
<script>
editor = false;
function save_md_cont()
{
cont_md = editor.getMarkdown();
cont_html = editor.getHtml();
const formData = new FormData();
formData.append('clear', 'yes');
formData.append('ajax', 'yes');
formData.append('mod', 'save_content');
formData.append('data[md_cont]', cont_md);
formData.append('data[html_cont]', cont_html);
formData.append('data[id]', <?=$id?>);
fetch('/editor_test', {method: 'POST',body: formData});
}
window.addEventListener('load', (event) =>
{
editor = new toastui.Editor({
el: document.querySelector('#editor'),
previewStyle: 'vertical',
height: '500px',
<?/*initialValue: "<?=$md_cont?>",*/?>
initialValue: <?=json_encode($md_cont)?>,
hooks:
{
addImageBlobHook:function(blob, callback)
{
let formData = new FormData();
formData.append("upl_img", blob, blob.name);
formData.append("mod", 'upload_img');
formData.append("ajax", 'yes');
fetch('/editor_test', {method: 'POST',body: formData
}).then(resp => resp.json()).then(resp=>{
if (!resp.success) {throw new Error('Validation error');}
callback(resp.data.url, 'alt text');
});
}
},
customHTMLRenderer:
{
image(node, context)
{
const { destination } = node;
const { getChildrenText, skipChildren } = context;
console.log(node);
skipChildren();
return {
type: 'html',
//content: '<figure><img src="'+destination+'"></figure>'
content: '<span><img src="'+destination+'"></span>'
};
/*return [
{
type: 'openTag',
tagName: 'img',
selfClose: true,
attributes: {
src: destination,
alt: getChildrenText(node)+"kokoko",
title: "zhopa"}
}
];*/
return [
{ type: 'openTag', tagName: 'figure'},
{
type: 'openTag',
tagName: 'img',
selfClose: true,
attributes: {
src: destination,
alt: getChildrenText(node)+"kokoko",
title: "zhopa"}
}
,
//{ type: 'openTag', tagName: 'figcaption' },
//{ type: 'text', content: node.title },
//{ type: 'closeTag', tagName: 'figcaption' },
{ type: 'closeTag', tagName: 'figure' }
];
}
}
});
/* editor.on('change',function(e){
document.querySelectorAll('div.te-preview pre').forEach(block => {hljs.highlightElement(block);});
});*/
hljs.highlightAll();
});
</script>

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?=$tpl->meta['title'];?></title>
<meta name="description" content="<?=$tpl->meta['description'];?>">
<meta name="keywords" content="<?=$tpl->meta['keywords'];?>">
<meta name="viewport" content="width=device-width,initial-scale=1">
<?=$tpl->head_cont;?>
</head>
<body>
<?=$tpl->cont_top;?>
<?=$tpl->fetch('main_body');?>
<?=$tpl->cont_bottom;?>
</body>
</html>

@ -0,0 +1,4 @@
<!--тут будет шапка и меню...-->
<div class="page_cont" style="max-width:1000px; margin:20px auto;">
<?=$tpl->mod_cont;?>
</div>

@ -0,0 +1,53 @@
<?php
$st_cnf = &LE::$TPL->static_list;
$st_dep = &LE::$TPL->static_dep;
$st_cnf[] = [
'mod'=>'highlight.js',
'pos'=>'top',
'type'=>'css',
'link'=>'//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css'];
$st_cnf[] = [
'mod'=>'highlight.js',
'pos'=>'bottom',
'type'=>'js',
'link'=>'//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js'];
$st_cnf[] = [
'mod'=>'le_form',
'type'=>'css',
'link'=>'/pub/css/le_form.css'];
$st_cnf[] = [
'mod'=>'ckeditor5',
'type'=>'js',
'link'=>'https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js'];
$st_cnf[] = [
'mod'=>'codemirror',
'type'=>'css',
'link'=>'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/codemirror.min.css'];
$st_cnf[] = [
'mod'=>'tui-editor',
'type'=>'css',
'link'=>'https://uicdn.toast.com/editor/latest/toastui-editor.min.css'];
$st_cnf[] = [
'mod'=>'tui-editor',
'type'=>'js',
'link'=>'https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js'
//'link'=>'/pub/js/tui-editor.js'
];
$st_cnf[] = [
'mod'=>'jquery',
'type'=>'js',
'link'=>'https://code.jquery.com/jquery-3.6.0.slim.min.js'];
$st_dep['tui-editor']=['codemirror','oth'];

@ -0,0 +1,26 @@
This project based on many open source projects.
#######################
## CSS, Images, Icons #
#######################
1. normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
2. Google Material Icons
3. Hamburger menu https://atuin.ru/blog/gamburger-ikonki-s-animirovannymi-perexodami/
#######################
# JS Scipts and libs #
#######################
1. JQuery v3.6 https://jquery.com/
2. CkEditor5 https://ckeditor.com/ckeditor-5/download/
3. ToastUI https://ui.toast.com/tui-editor
########################
# PHP Scripts and Libs #
########################
1. PHP Spreadsheet

@ -0,0 +1,44 @@
<?php
/********************************************
* LE Framework v0.1 | 18.04.2021 *
* Lite Elephant (PHP) Framework *
* Elizavet , Ural State, Russia *
* Thanks to many open source projects *
* read copyrights.txt file *
* ---------------------------------------- *
* by Pavel Belyaev | pavelbbb@gmail.com *
* Tech-Research.Ru *
*********************************************/
if (!defined("APPDIR") || !is_dir(APPDIR)) exit ("APPDIR not defined");
define("DS",DIRECTORY_SEPARATOR); //directory separator (/ or \)
define("SYSDIR", __DIR__.DS); // system dir
define("I", SYSDIR."LE".DS); //include sys files
require I."deprecated.php";
require I."core.php";
LE::DEF("VER","0.1.0");
LE::DEF("CLI"); //console mode 0
LE::DEF('BR',(CLI?PHP_EOL:'<br/>')); //перенос строк
LE::DEF('ISWEB',(!CLI)); //web mode 1
LE::DEF('WEBDIR',APPDIR."web".DS);
define('CLSDIR', SYSDIR.'CLASSES'.DS); //class sys
define('CORE_CLSDIR', CLSDIR.'core'.DS); //core class sys
define('CLSDIR2', APPDIR.'CLASSES'.DS); //class app
require I."sys_conf.php";
include I."sys_autoload.php";
include I."db_init.php"; //mysql
if (ISWEB):
include I."session.php";
LE::$TPL = new LE_TPL; //шаблонизатор
include I."load_mod.php"; //load module
LE::$TPL->display();
exit();
else:
LE::DEF('SDOM', 'localhost');
endif;
Loading…
Cancel
Save