• Как трансформировать код из 1 вида в другой?

    @ksnk
    Отредактировал немного, сейчас работает лучше, но в принципе - наверное лучше в класс перетащить, а то 3 анонимные функции как-то криво начинают выглядеть.
    <?php
    
    $source = <<<'code'
    <?php
    
    $name = 'anon';
    echo '<h2>';
    echo 'Number is: ';
    echo count(["1","2","3"]);
    echo '</h2>';
    echo 'CHECK
    
    ';
    echo 1 + 3 . '-'. 4 . '=' . 0;
    echo '
    
    ';
    echo '<h2>';
    echo 'Olololo';
    echo '</h2>';
    echo '
    
    ';
    echo '<h3>';
    echo 'QWErty';
    echo '</h3>';
    echo '
    
    
    ';
    echo '<h2>';
    echo 'Hello, ';
    echo $name;
    echo '</h2>';
    echo '
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        ';
    echo '<h2>';
    echo 'Number is: ';
    echo $item;
    echo '</h2>';
    echo '
    ';
    }
    code;
    
    $tokens = token_get_all($source);
    $last_token=false;
    
    $getnext=function() use (&$tokens, &$last_token){
      $token=array_shift($tokens);
      if(is_null($token)) return false;
      if(is_array($token)){
        $last_token= token_name($token[0]);
        return  $token[1];
      } else {
        $last_token='';
          return  $token;
      }
    };
    
    $getbracket=function($bracket) use (&$tokens,$getnext,&$last_token){
    	$stack=[]; $buf=$bracket;
    	
    	if($bracket=='[') array_unshift($stack,']');
    	if($bracket=='(') array_unshift($stack,')');
    	while(false!==($x=$getnext())){
    		$buf.=$x;
    		if($x==$stack[0]){
    			array_shift($stack);
    			if(count($stack)==0) break;
    		}
    		if($x=='(') array_unshift($stack,')');
    		if($x=='{') array_unshift($stack,'}');
    		if($x=='[') array_unshift($stack,']');
    	}
    	return $buf;
    };
    
    $getecho=function() use (&$tokens,$getnext,$getbracket,&$last_token){
      $buf='';
      $buf2='';
      $waitecho=false;
      while(false!==($x=$getnext())){
      	//echo '{'.$last_token.' '.$x.'}';
        if($last_token==='' && $x==';'){
          $waitecho=true;
          $buf2.=$x;
        } elseif($last_token==='T_ECHO' && $waitecho){ // склеиваем
          $waitecho=false;
          $buf.=',';$buf2='';
        } elseif($last_token==='T_WHITESPACE' && $waitecho){ 
          $buf2.=$x;
        } else if($waitecho){
          return $buf.$buf2.$x;
        } else if($last_token==='T_CONSTANT_ENCAPSED_STRING') {// склеиваем константные строки с одинаковыми кавычками
          $s=$x[0];
          $y = preg_replace('~'.preg_quote($s,"~'").'\s*[\.\,]\s*$~', '', $buf, 1, $count);
          if($count>0)
             $buf=$y.substr($x,1);
          else
            $buf.=$x;
        } else if($last_token==='' && in_array($x,['[','('])) {
        	$buf.=$getbracket($x);
        } else {
          $buf.=$x;
        }
      };
      return '';
    };
    
    while(false!==($x=$getnext())) {
      echo $x;
      if($last_token=='T_ECHO'){
        echo $getecho();
      }
    }
    ?>


    <?php
    
    $name = 'anon';
    echo '<h2>Number is: ', count(["1","2","3"]), '</h2>CHECK
    
    ', 1 + 3 . '-'. 4 . '=' . 0, '
    
    <h2>Olololo</h2>
    
    <h3>QWErty</h3>
    
    
    <h2>Hello, ', $name, '</h2>
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        <h2>Number is: ', $item, '</h2>
    ';
    }
    Ответ написан
  • Как правильно сверстать такую границу у блока?

    @ksnk
    Немного переработал вариант от Ильи Бондаренко, зато с прозрачностью и котиками
    Ответ написан
    Комментировать
  • Как нарисовать тонкую нормальную линию на канвасе между двумя кликами мыши?

    @ksnk
    У канваса есть еще атрибуты - высота и ширина. По этим атрибутам и идет рисование и их нужно установить для корректного пересчета координат рисования в клики.
    const rect = $canvas.getBoundingClientRect(); // после этого вставить 2 строки
        $($canvas).attr('width', rect.width);
        $($canvas).attr('height', rect.height);
    //...

    получится что-то вроде https://codepen.io/ksnk/pen/LYMPbxZ
    Ответ написан
    1 комментарий
  • Как сверстать блок с такой же линией?

    @ksnk
    В общем случае сложно обойтись без скрипта. Можно рисовать линии канвасом, например так.
    Ответ написан
    1 комментарий
  • Как сделать так, чтобы при наведении на блок появлялся список и не исчезал, пока не уберешь со списка курсор?

    @ksnk
    Вообще-то удобнее для отвечающего и быстрее для спрашивающего смастерить пример, например на codepen.io . Например так

    В отличии от кода в вопросе используются методы mouseenter, mouseleave как более подходящие к месту и toggle заменен на явную установку-выкидывание класса.
    Ответ написан
    Комментировать
  • Как в css сделать так чтоб текст был всегда прижат к низу, не зависимо тайтл с переносом или нет?

    @ksnk
    Надо на верстку смотреть, но обычно - заголовку блока задают либо фиксированный размер+overflow:hidden, либо min-height. К примеру 2.5em (подбирается по месту, чтобы влезало точное количество строк). В этом случае в заголовок будет помещаться 2 строки текста. и все описания, расположенные ниже, окажутся на одной высоте. Если min-height задать, то очень большой заголовок не будет обрезан, а поместится полностью, но именно этот блок окажется сдвинут. Останется только вручную посмотреть что не влезло и поменять заголовки, или оставить так...
    Ответ написан
    Комментировать
  • Как выделить строку в таблице?

    @ksnk
    Лучше на JS добавлять класс элементу TR и от него плясать с раскраской. Но можно пользоваться псевдоэлементом has, он уже почти везде есть...
    https://codepen.io/ksnk/pen/dygbmWL
    Ответ написан
  • Как сделать авторизацию по ссылке для фида?

    @ksnk
    Вот упрощенный пример. Пароль-пользователь указан в файле. Каталог для выгрузки файлов - там же.

    <?php
    
    if (!isset($_SERVER['PHP_AUTH_USER'])) {
        header('WWW-Authenticate: Basic realm="My Realm"');
        header('HTTP/1.0 401 Unauthorized');
        echo 'Authentification required.';
        exit;
    } else {
        // config!
        $password='test';
        $user='test';
        $upload_dir=$_SERVER['DOCUMENT_ROOT'].'/tmp/';
        //
    
        if($_SERVER['PHP_AUTH_USER']!=$user ||$_SERVER['PHP_AUTH_USER']!=$password){
            echo 'No user found, sorry.';
            exit;
        }
    
        $filename=$_SERVER['QUERY_STRING'];
        if(!is_readable($upload_dir.$filename)){
            echo 'No file found, sorry.';
            exit;
        }
    
        header('Content-type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        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($upload_dir.$filename));
        readfile($upload_dir.$filename);
    }

    Использование

    https://test:test@site/file.php?filetoupload.txt
    Ответ написан
    Комментировать
  • Строка из БД как условие сравнения в if?

    @ksnk
    У меня где-то использовался `язык фильтров` - строка с условиями, которую удобно вписывать в область фильтра в столбик таблицы с данными. Постим на сервер - получаем фильтрованное.
    Сама строка условий выглядит примерно так
    count=2,<2;count=3,<300,>44
    условия соединяются запятой, по AND, точкой с запятой - по OR, у OR более низкий приоритет. Операция сравнения соединяет 2 операнда, если один из операндов пустой - берется "сравниваемое значение", если число - то число, иначе ищем во внешних "данных".
    Если записать строку на php - будет что-то вроде
    $current=45; // значение, которое сравниваем
    $data=['count'=>3]; // внешние данные
    if( ($data['count']==2 && $current<2) || ($data['count']==3 &&$current>44 && $current<300)){
        // ...
    }

    Удобно в языке то, что парсер его компактен и легко допиливается напильником по месту.
    function evaluate($current,$cond,$data=[]){
        $res=false;
        foreach(explode(';',$cond) as $or){ //or
            foreach(explode(',',$or) as $and) { //and
                if(preg_match('/^(.*?)(<=|>=|<|>|=)(.*?)$/',$and,$m)){
                    $a=trim($m[1]);$b=trim($m[3]);
                    if(empty($a)) $a=$current;
                    else if(is_numeric($a)) $a=0+$a;
                    else if(isset($data[$a])) $a=$data[$a];
                    else {
                        $res=false; break;
                    }
                    if(empty($b)) $b=$current;
                    else if(is_numeric($b)) $b=0+$b;
                    else if(isset($data[$b])) $b=$data[$b];
                    else {
                        $res=false; break;
                    }
                    if($m[2]=='<=') $res=$a<=$b;
                    else if($m[2]=='>=') $res=$a>=$b;
                    else if($m[2]=='>') $res=$a>$b;
                    else if($m[2]=='<') $res=$a<$b;
                    else if($m[2]=='=') $res=$a==$b;
                } else {
                    $res=false;
                    //throw new \Exception('Некорректное условие в строке '.$and)
                }
                if(!$res) break; // выход по AND
            }
            if($res) break; // выход по OR
        }
        return $res;
    }
    
    $data=['count'=>3];
    
    var_dump(true===evaluate(45,'count=2,<2;count=3,<300,>44', $data));
    var_dump(true===evaluate(1,'<2'));
    var_dump(true===evaluate(1,'>3;<2,>1;<2'));
    Ответ написан
    1 комментарий
  • Как валидировать кнопку у формы при незаполненном инпуте?

    @ksnk
    Так ?
    Кнопка отправки формы - одна - Next
    При нажатии на "Ввод" внутри текстового инпута происходит сабмит формы, При этом срабатывает самая первая кнопка сабмит, которая попадется в форме. Так что порядок кнопок немного другой, а чтобы визуально не отличалось - передернуто с помощью float:left .
    Ну и обрабатывать форму должен сервер, так что все набранные данные туда и отправляем....
    Ответ написан
  • Как сделать так, чтобы когда урок начинался (наступало 8:00), то выводилось "Урок начался!", а когда заканчивался (8:40) - "Урок закончился!"?

    @ksnk

    В отличии от предложенных решений,
    • можно указывать время с точностью до секунды, вдруг это кому то надо.
    • используется один таймаут, а не посекундный опрос, что уменьшает нагрузку на броузер
    • таймер срабатывает предварительно за минуту до срока, чтобы компенсировать задержку таймаута броузером.

    Ответ написан
  • Не добавляются нули в таймер обратного отсчета?

    @ksnk
    days.toString().replace(/\d/gi, (substring) => `${substring}`);

    вот такие 3 строки нужно заменить на
    daysVal.innerHTML = '<span>'+days.toString().padStart(2,'0')+'</span>';
        hoursVal.innerHTML = '<span>'+hours.toString().padStart(2,'0')+'</span>';
        minutesVal.innerHTML = '<span>'+minutes.toString().padStart(2,'0')+'</span>';

    и короче и не каждая цифра оборачивается в свой спан
    Ответ написан
    Комментировать
  • Определить модуль по кешу возможно?

    @ksnk
    <?php die("Access Denied"); ?>#x#a:2:{s:6:"result";a:227:{i:0;O:8:"stdClass":8:{s:2:"id";s:3:"870";s:5:"title";s:23:"БПВР-вопросы";s:6:"module";s:13:"mod_widgetkit";

    вот пример (первые несколько символов) файла с кэшем. Как можно заметить - это сериализованное значение (в определенном смысле). закэширован модуль с именем mod_widgetkit
    Ответ написан
    8 комментариев
  • Как сделать круговое расположение букв в словах?

    @ksnk
    Ответ написан
    Комментировать
  • Как сделать адаптивную разделительную линию между 2-мя текстами?

    @ksnk
    codius.ru/articles/%D0%9A%D0%B0%D0%BA_%D1%81%D0%B2...
    Не оно ? если нужно обязательно к левому краю прижимать номера страниц - можно ul.oglavl span.text задать размер в процентах, например.
    или https://qna.habr.com/q/391993
    Ответ написан
    4 комментария
  • Как настроить 301 редирект в битрикс?

    @ksnk
    самый простой - .htaccess
    добавить туда что-то вроде такого - откуда-куда
    Redirect 301 /karera/vakansii /o-kompanii/nasha-komanda/vakansii/

    Правда требуется применять здравый смысл, чтобы файл не становился уж очень большим.
    Ответ написан
    Комментировать
  • Как можно сделать такой range с кастомными этапами?

    @ksnk
    Логарифмическая шкала?
    Ну вот так, например, можно сделать. Ставим на слайдере 1000 элементов. Пишем функцию конверсии значения слайдера в значение инпута и наоборот, рисуем метки под слайдером учитывая конверсию.
    чем больше step тем "кривее" шкала.
    $(function() {
            var valMap = [0, 1, 3, 6, 10, 15, 22, 30,40, 50]; // более равномерно в логарифмической шкале
    			// 0..1000 --> 0..50 (true, обратно false)
    				const step=2, 
    							w=[1000/Math.pow(50,1/step),50/Math.pow(1000,step)] ;
    			  function _conv(x, forvard){
    					if(!forvard)
    						return Math.pow(x,1/step)*w[0];
    					else
    						return Math.round(Math.pow(x,step)*w[1]);
    				}
    			
    			  $("#slider").slider({
                    max: 1000,//valMap.length - 1,
                    slide: function(event, ui) {
                       $("#radiusAmount").val(_conv(ui.value,true));
                    }
                })
                .each(function() {
    
                    var opt = $(this).data().uiSlider.options;
                    var vals = opt.max - opt.min;
                    var arrayLength = valMap.length;
    								for (var i = 0; i < arrayLength; i++) {
                        var el = $('<label>' + (valMap[i]) + '</label>').css('left', (_conv(valMap[i],false) / 10 ) + '%');
                        $("#slider").append(el);
                    }
                });
    			$(document).on('change','#radiusAmount', function(){
    					$("#slider").slider('value',_conv($(this).val(), false))	;				})
        });
    Ответ написан
    Комментировать
  • Как сделать такой инпут?

    @ksnk
    https://jsfiddle.net/wjg8oLsd/ Не то ?
    функция вычисления размера инпута стырена со stackoverflow
    P.S. Обновил решение
    Ответ написан
  • Как сделать вогнутую кнопку css?

    @ksnk
    htmlbook.ru/css/border-image
    Картинку с бордером можно нарисовать хоть в svg, но если png - в этом случае разумно будет примерно соответствовать средним размерам кнопок, чтобы при разных размерах не бросались в глаза артефакты при увеличении картинки
    Ответ написан