Всего 125 962 комментария

Vladimir
29 апреля 2022, 08:38
0
$res = $modx->getObject('modTemplate', 7);
echo $res->getContent();
Оказалось что шаблон который я просил был пустым, сори
Vladimir
29 апреля 2022, 08:17
0
По webp у меня есть такой сниппет, для google page speed insgiht хватает полностью, автоматом конвертирует все найденные картинки будь то в source будто в src, так же в функции может уменьшить или увеличить качетсво. работает на всех хостах.
<?php
/**
 * OnManagerPageBeforeRender
 * OnWebPagePrerender
 * OnSiteRefresh
 * 
 * Generate Webp image format
 * 
 * Uses either Imagick or imagewebp to generate webp image
 * 
 * @param string $file Path to image being converted.
 * @param int $compression_quality Quality ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file).
 * 
 * @return false|string Returns path to generated webp image, otherwise returns false.
 */


if(
	$modx->event->name == 'OnSiteRefresh' ||
	$modx->event->name == 'OnTemplateSave' ||
	$modx->event->name == 'OnChunkSave' ||
	$modx->event->name == 'OnPluginSave' ||
	$modx->event->name == 'OnTemplateVarSave' ||
	$modx->event->name == 'OnDocFormSave' ||
	$modx->event->name == 'OnSnippetSave'
) {
	$options= [xPDO::OPT_CACHE_KEY=>'webp_on_page']; // Clear webp modx cache
	$modx->cacheManager->clean($options);
}

function jcphp01_modx_custom_generate_webp_image($file, $compression_quality = 80)
{
    
    
    $fileWithBasePath = preg_replace("~\/(?!.*\/)(.*)~", '', MODX_BASE_PATH) . $file;
    
    // check if file exists
    if (!file_exists($fileWithBasePath)) {
        return false;
    }

    // If output file already exists return path
    $output_file = $file . '.webp';
    $outputFileWithBasePath = $fileWithBasePath . '.webp';
    
    if (file_exists($outputFileWithBasePath)) {
        return $output_file;
    }
    
    
    $file_type = strtolower(pathinfo($fileWithBasePath, PATHINFO_EXTENSION));

    if (function_exists('imagewebp')) {
        
        switch ($file_type) {
            case 'jpeg':
            case 'jpg':
                $image = imagecreatefromjpeg($fileWithBasePath);
                break;

            case 'png':
                $image = imagecreatefrompng($fileWithBasePath);
                imagepalettetotruecolor($image);
                imagealphablending($image, true);
                imagesavealpha($image, true);
                break;

            case 'gif':
                $image = imagecreatefromgif($fileWithBasePath);
                break;
            default:
                return false;
        }

        // Save the image
        $result = imagewebp($image, $outputFileWithBasePath, $compression_quality);
        if (false === $result) {
            return false;
        }

        // Free up memory
        imagedestroy($image);

        return $output_file;
    } elseif (class_exists('Imagick')) {
        $image = new Imagick();
        $image->readImage($fileWithBasePath);

        if ($file_type === 'png') {
            $image->setImageFormat('webp');
            $image->setImageCompressionQuality($compression_quality);
            $image->setOption('webp:lossless', 'true');
        }

        $image->writeImage($outputFileWithBasePath);
        return $output_file;
    }

    return false;
}





function check_image_file_for_webp_converter_custom($img_real, &$webp_on_page){
	static $uniq_imgs= [];
	

	$img_real= trim($img_real);
	if(in_array($img_real, $uniq_imgs)) return;
	$uniq_imgs[]= $img_real;
	
	$ext= strtolower(pathinfo($img_real, PATHINFO_EXTENSION));
	if(
		$ext == 'jpg' ||
		$ext == 'jpeg' ||
		$ext == 'png' 
	) {
		$abs= jcphp01_modx_custom_generate_webp_image($img_real);
		$abs_base= str_replace('//', '/', MODX_BASE_PATH.$abs);

		if( file_exists($abs_base)){
			$webp_on_page[$img_real]= $abs;
		}
	}
}


try{

    if( // replace jpg and png images to webp
    	$modx->event->name == 'OnWebPagePrerender' && 
    	stripos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false
    ){
        
    	if($disable_replacing_for_logged_user && $modx->user->hasSessionContext('mgr')) return ''; 
    	
    	$options= [xPDO::OPT_CACHE_KEY=>'webp_on_page'];
    	$cache_key= md5(MODX_SITE_URL.$_SERVER['REQUEST_URI']);
    
    	$cached_webp_on_page= $modx->cacheManager->get($cache_key, $options);
    	$output= &$modx->resource->_output;
    
        
    
    	if( empty($cached_webp_on_page) ){
    		$webp_on_page= [];
    		
    		preg_match_all('/<img[^>]+>/i', $output, $result);
    		
    		if(count($result)){ // Search images in img tag
    			foreach($result[0] as $img_tag)	{
    				$img_tag= str_replace("'", '"', $img_tag); // src
    				preg_match('/(src)=("[^"]*")/i', $img_tag, $img[$img_tag]);						
    				$img_real= str_replace('"', '', $img[$img_tag][2]);
    				check_image_file_for_webp_converter_custom($img_real, $webp_on_page);
    				
    				preg_match('/(data-src)=("[^"]*")/i', $img_tag, $img[$img_tag]); // data-src					
    				$img_real= str_replace('"', '', $img[$img_tag][2]);
    				check_image_file_for_webp_converter_custom($img_real, $webp_on_page);
    				
    				preg_match('/(srcset)=("[^"]*")/i', $img_tag, $img[$img_tag]); // srcset
    				$srcset= explode(',', str_replace('"', '', $img[$img_tag][2]));
    				foreach($srcset as $src_item){
    				    $src_a= explode(' ', $src_item);
    				    if(isset($src_a[0]) && !empty($src_a[0])) {
    				        check_image_file_for_webp_converter_custom($src_a[0], $webp_on_page);
    				    } else {
    				        if(isset($src_a[1]) && !empty($src_a[1])) {
    				            check_image_file_for_webp_converter_custom($src_a[1], $webp_on_page);
    				        }
    				    }
    				}
    			}
    		}
    
    		preg_match_all('/url\(([^)]*)"?\)/iu', $output, $result);
    		if(count($result)){ // Search images in url css rules
    			foreach($result[1] as $img_tag)	{
    				if(stripos($img_real, 'data:')) continue;
    				$img_real= str_replace(['"',"'"], '', $img_tag);
    				check_image_file_for_webp_converter_custom($img_real, $webp_on_page);
    			}
    		}
    		
    		$webp_on_page['/webp/webp/']= '/webp/';
    		$webp_on_page['//webp/']= '/webp/';
    		$webp_on_page['.webp.webp']= '.webp';
    		
    		if(count($webp_on_page)) $output= str_replace(array_keys($webp_on_page), array_values($webp_on_page), $output);
    		$modx->cacheManager->set($cache_key, serialize($webp_on_page), 0, $options);
    	} else {
    		$webp_on_page= unserialize($cached_webp_on_page);
    		if(count($webp_on_page)){
    			$output= str_replace(array_keys($webp_on_page), array_values($webp_on_page), $output);
    		}
    	}
    	return '';
    }
    
} catch (Exception $e){
    $modx->log(1, $e);
}
Vladimir
29 апреля 2022, 08:08
0
Пытался так но не получается, никак не могу получить сами данные
$res = $modx->getObject('modTemplate', 8);
echo $res->getSource();
echo print_r(get_class_methods($res));
Vladimir
29 апреля 2022, 07:51
0
Главное чтобы при возвращении этого контента он был не обработан, чтобы все конструкции и вызовы были как есть
Евгений
29 апреля 2022, 02:19
0
Не получилось((
Не phpThumbOff, не phpThumbOn, не pThumb не понимают настройки качества для webP.
Мне кажется webP генерится по умолчанию с максимальным качеством, и это никак не поменять.
То есть наверно как-то можно, но у меня не получилось.
<picture>
    <source type="image/webp"
        srcset="[[+image_absolute:phpthumbon=`w=350&h=195&zc=C&q=50&f=webP`]], 
                [[+image_absolute:phpthumbon=`w=700&h=390&zc=C&q=50&f=webP`]] 2x">
    <img title="[[+pagetitle]]" alt="[[+pagetitle]]"
           src="[[+image_absolute:phpthumbon=`w=350&h=195&zc=C`]]" 
        srcset="[[+image_absolute:phpthumbon=`w=700&h=390&zc=C`]] 2x">
</picture>
Вэб пишная картинка получается в полтора раза тяжелее чем JPG. Весь смысл использования webP теряется.
Дима Сайт old см. профиль
29 апреля 2022, 01:46
+1
Сергей, тут читатели почитатели — программисты в основном, а они (мы) довольно прагматичны.

В лично моих глазах и Василий и Вы достойны всяческих похвал и почетных мест в зале/аллее славы MODX!

Теперь по теме:
Наверное, чтобы.избежать разночтений, я только хочу посоветовать для прагматичной точности ваших слов использовать вместо «стандартный парсер» или «MODX парсер» понятную всем здесь формулировку: modParser либо pdoParser. Где то здесь видел что вы считаете что сайтов на MODX без pdoTools в принципе почти нет и потому стандартный для вас это pdoParser.

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

Я сам недавно писал где то тут в комментах что с появлением fenom возрасла скорость, за счёт отказа от сниппета if и костылей в виде динамической генерации имени сниппета, которые описал Василий в своем недавнем посте. Вы мне в том комменте ответили что я не врубаю как это работает, а я имел ввиду только отказ от рекурсии изнутри.

Признаться честно, я фанат смешанного синтаксиса, потому что синтаксис MODX-тегов считаю очень крутым, простым и понятным.
Мне как разработчику безусловно нужна скорость итоговая, но и удобство и красота кода для меня не последние слова ;) я уверен и смарти в зумИксе не парсит изнутри наружу рекурсивно, так что тут с феномом не будет разницы.

Пользуясь случаем хочу всем, кто просвещает тут людей вроде меня, не готовых лезть под капот парсеров в силу недостатка скиллов, ещё раз сказать спасибо. Ведь находить нужные слова, ничего не перепутать и подобрать формулировки, чтобы небыло разночтений бывает очень не просто!
Evgeny
29 апреля 2022, 00:32
0
Спасибо!
Только один минус — буква «й» заменяется на символ «ĭ», хотя в таблице символов все нормально прописано:
'й'=>'j'
'Й'=>'j'
Андрей
28 апреля 2022, 23:03
0
Разобрался!
Нужно изменить request_param_id
Роман
28 апреля 2022, 22:39
0
Возможно как-то так, но лучше скопировать сниппет mFilter2 и там поправить.
{set $rows = '!mfilter2' | snippet : [
'return' => 'json',
] | json_decode : true}
{foreach $rows as $idx => $row}
    {set $idx[] = $row.id}
{/foreach}
Андрей
28 апреля 2022, 20:40
0
Если сниппет вызвать в шаблоне 404, тоже срабатывает, но остается на ней после авторизации.
Как сделать чтобы
site.ru/?Id=000&first_name=Name
обрабатывался, а не выдавал 404?
Андрей
28 апреля 2022, 20:22
0
Прикол )
Если в качестве страницы 404 указать главную, то работает.
Андрей
28 апреля 2022, 18:40
0
Вход работает с любой страницы кроме главной.
Кидает на адрес:
site.ru/?Id=000&first_name=Name&last_name=Name&username=Name&auth_date=000&hash=000
Sergey (Sentinel)
28 апреля 2022, 18:26
0
а, ну там запятая наверное
'filters' => $filters ~ ',ms|vendor:vendors,
parent:parents',
Евгений
28 апреля 2022, 18:25
0
мне нужны ids с текущего листинга а не все
Евгений
28 апреля 2022, 17:32
0
ну так сниппет же 2 раза отработает, работать будет в два раза больше
Константин
28 апреля 2022, 17:18
0
Спасибо, попробовал так, но пустая страница и ошибка:
Unexpected token '~' in expression in e014f8071b522126681529ed92e5b3d5 line 377

Ругается на этот символ ~, я так понял
Роман
28 апреля 2022, 17:07
0
Разницы нет. Сначала делаете выборку c IDS.
Евгений
28 апреля 2022, 16:53
0
у меня не msearche2 а mfilter2, там сложная выборка по фильтру
Роман
28 апреля 2022, 15:28
0
Ну тогда, как написал выше.
Евгений
28 апреля 2022, 15:24
0
не хотелось бы сниппет трогать