Vladimir

Vladimir

С нами с 25 июня 2021; Место в рейтинге пользователей: #283
Vladimir
04 июля 2022, 15:35
0
Спасибо всем кто помог. Вот код работает проверил. Можно конечно было лучше сделать, особенно в случае создание и автоматом добавления групп ресурсов по брендам, но так и не смог быстро найти способ проверить все группы ресурсов на имеющиеся и если нет то создать а потом всё собрать и указать в словарь.
<?php

$brensList = array('Zuff', 'Пульс', 'ON', 'Dominator', 'FB', 'Актех', 'Вожак', 'Зверь');

$q=$modx->newQuery('msProductOption', array('key:=' => 'brand', 'value:IN' => $brensList));

$q->prepare();
$q->stmt->execute();
$res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);


$brendsGroups = array(
    'Zuff' => 7,
    'Пульс' => 8,
    'ON' => 9,
    'Dominator' => 10,
    'FB' => 11,
    'Актех' => 3,
    'Вожак' => 6,
    'Зверь' => 14
);




foreach ($res as $k => $v) {

    $currentProductBrand = $v['msProductOption_value'];
    $docId = $v['msProductOption_product_id'];
    $newGroup = $brendsGroups[$currentProductBrand];
    $resource = $modx->getObject('modResource', $docId);
    if(!$resource->isMember($newGroup)){
        $resource->joinGroup($newGroup);
    }

}
Vladimir
04 июля 2022, 14:00
0
У меня есть 1 вариант, но он костыльный, пройтись по всем товарам, и положить их в спец группу ресурсов по бренду, и потом эту группу указать
Vladimir
23 июня 2022, 12:45
0
Вывод вообще для всех
<?php
if(empty($price)){
    return '';
}

$pdoFetch = $modx->getService('pdoFetch');
$group = $pdoFetch->getObject('msdUserGroup', array(), array(
    'loadModels' => 'msdiscount',
    'leftJoin' => array(
        'modUserGroupMember' => array('class' => 'modUserGroupMember', 'on' => 'modUserGroupMember.user_group = msdUserGroup.id')
    ),
    'groupby' => 'msdUserGroup.id',
    'sortby' => 'CAST(`msdUserGroup`.`discount` AS DECIMAL(13,3))',
    'sortdir' => 'desc',
    'select' => 'discount',
));

if (isset($group['discount'])) {
    
    return (((int)$price * (100 - (int)$group['discount'] )/100));
}

return '';
Vladimir
23 июня 2022, 12:34
0
Как вывести скидку для всех тоже хз
Vladimir
23 июня 2022, 12:06
0
Пока нет ответа со встроенным решением, сделал такой сниппет
[[!getProductDiscountPrice? &price=`[[*price]]`]]
.
<?php
// Если не указан &uid=``, то выбираем для текущего юзера
if(empty($price)){
    return '';
}

if (empty($uid)) {$uid = $modx->user->id;}

$pdoFetch = $modx->getService('pdoFetch');
$group = $pdoFetch->getObject('msdUserGroup', array('modUser.id' => $uid), array(
    'loadModels' => 'msdiscount',
    'leftJoin' => array(
        'modUserGroupMember' => array('class' => 'modUserGroupMember', 'on' => 'modUserGroupMember.user_group = msdUserGroup.id'),
        'modUser' => array('class' => 'modUser', 'on' => 'modUser.id = modUserGroupMember.member AND modUser.id = '.$uid),
    ),
    'groupby' => 'msdUserGroup.id',
    'sortby' => 'CAST(`msdUserGroup`.`discount` AS DECIMAL(13,3))',
    'sortdir' => 'desc',
    'select' => 'discount',
));



if (isset($group['discount'])) {
    
    return (((int)$price * (100 - (int)$group['discount'] )/100));
}

return '';
Vladimir
23 июня 2022, 11:58
0
Такой очевидный вопрос, но в доках нет решения
Vladimir
21 мая 2022, 12:52
0
Если модифицировать так, то это ужасно ведь, нет?

switch ($modx->event->name) {
    case 'OnWebPagePrerender':
        
        $jsToRegisterPath = 'assets/fl.js';
        
        $output = &$modx->resource->_output;
        
        $regTxtJs = "<script defer src='{$jsToRegisterPath}'></script></body>";
        
        $output = str_replace('</body>',$regTxtJs,$output);

        break;
}
Vladimir
15 мая 2022, 20:22
0
Пробовал так
switch ($modx->event->name) {
case 'OnWebPageComplete':
//Получаем доступ к готовому DOM дереву
$output = $modx->resource->getContent();
$modx->log(1, output );
break;
}

Но получаю не полностью сам контент страницы, а часть покрайней мере так в консоли, видел в консоле 1 вызов [[++settings_version]]

То есть какой-то сжатый кусок, сама страница дефолтная от установки modx'a, но получаю сжатый такой кусок в таком виде. Сохранил вывод с
$modx->resource->getContent();
в файл.

<p>You have successfully installed MODX Revolution [[++settings_version]]!</p>
<p>Now that MODX is installed you can login to the manager to create your templates, manage content and install third party extras to add functionality to your website.</p>
<h2>New to MODX?</h2>
<p>Pages on a MODX site are called <a href="https://docs.modx.com/current/en/building-sites/resources">Resources</a>, and are visible on the left-hand side of the manager in the Resources tab. Resources can be nested under other resources, making it easy to create a tree of resources. There are different types of resources for different use cases.</p>
<p>Building your website is done through a combination of <strong>Templates</strong>, <strong>Template Variables</strong>, <strong>Chunks</strong>, <strong>Snippets</strong> and <strong>Plugins</strong>. Collectively these are known as <strong>Elements</strong>, and can also be found in the left-hand side of the manager, in the Elements tab.</p>
<p><a href="https://docs.modx.com/current/en/building-sites/elements/templates">Templates</a> contain the outer markup of any page. Each resource can only be assigned to a single template at a time. By adding <a href="https://docs.modx.com/current/en/building-sites/elements/template-variables">Template Variables</a> to a template, you can add custom fields for any resource using that particular template.</p>
<p>With <a href="https://docs.modx.com/current/en/building-sites/elements/chunks">Chunks</a> you can share parts of the markup, such as a header, across different templates. <a href="https://docs.modx.com/current/en/building-sites/elements/snippets">Snippets</a> are pieces of PHP that return dynamic content, such as summaries of other resources or the current date. With snippets, you will often use Chunks to mark up the pieces of content it returns, instead of mixing the PHP and HTML.</p>
<p>Finally, <a href="https://docs.modx.com/current/en/extending-modx/plugins">Plugins</a> enable more advanced features by hooking into the extensive events system provided by MODX.</p>
<p>To learn more about MODX, be sure to check out the <a href="https://docs.modx.com/current/en/getting-started">Getting Started</a> section in the official documentation.</p>
А это получается что я получаю именно контент самого ресурса а не контент шаблона перед рендером
Vladimir
03 мая 2022, 12:18
0
Кстати да заработало, можно кратко почему оно не работало из консоли? типо из-за прав? но ведь оно работало как плагин. Конечно сделал не так всё как вы сказали, но для компании для которой нужно всё быстро и чтоб работало сойдёт, да и пока нет знаний чтобы сделать как вы сказали

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

define('MODX_API_MODE', true);
require dirname(dirname((__FILE__))) . '/index.php';



$BASE_PATH = dirname(dirname((__FILE__)));
$CORE_PATH = "{$BASE_PATH}/core/";


$dir_name = "{$BASE_PATH}/media";

$phpThumb = $modx->getService('modphpthumb', 'modPhpThumb', "{CORE_PATH}model/phpthumb/", array());

function optimezieImg($pathToImage, $phpThumb){
    global $modx;
    $params = array();
    if (exif_imagetype($pathToImage) == IMAGETYPE_JPEG)
    {

        $params = array(
            'w' => 1920,
            'f' => 'jpeg',
            'q' => 80,
        );

    }
    elseif (exif_imagetype($pathToImage) == IMAGETYPE_PNG)
    {

        $params = array(
            'w' => 1920,
            'f' => 'png',
            'q' => 80,
        );

    }
    elseif (exif_imagetype($pathToImage) == IMAGETYPE_GIF)
    {
        return;
    }
    
    
    
    $phpThumb->setSourceFilename($pathToImage);

    foreach ($params as $k => $v)
    {
        $phpThumb->setParameter($k, $v);
    }

    if ($phpThumb->GenerateThumbnail())
    {
        if (!$phpThumb->renderToFile($pathToImage))
        {
            $modx->log(1, 'Ошибка сохранения изображения в [' . $pathToImage . ']');
        }
    }
    else
    {
        $modx->log(1, print_r($phpThumb->debugmessages, 1));
    }    
}



$directoryIterator = new RecursiveDirectoryIterator($dir_name);
$iteratorOverIterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);

$allowedExts = array('jpg','png','jpeg');

$files = array();

foreach ($iteratorOverIterator as $file) {
    
    if ($file->isFile()) {
        $currentFileExt = pathinfo($file->getFilename(), PATHINFO_EXTENSION);
        if(in_array($currentFileExt, $allowedExts)){
            array_push($files, $file->getPathname());
        }
    } 
}

foreach ($files as $file) {
    
    optimezieImg($file, $phpThumb);
    
}


echo 'Done';
Vladimir
03 мая 2022, 11:25
0
Можно как их оптимизировать разом? вверху полу рабочий скрипт, собирает все картинки но выдаёт ошибку, мол плохие картинки. Использовать phpthumbof и так далее через тэги, нет не выход, с ними постоянно проблемы с кэшем, что делает только хуже, по этому нужно сделать чтобы все существующие картинки прогнал через сам себя встроенный phpthumb, великолепно справляется со своей работой, в качестве плагина на загрузку файлов
Vladimir
03 мая 2022, 11:02
0
Есть у кого-нибудь идеи?
Vladimir
02 мая 2022, 11:31
0
Сделал так, но вылезают такие ошибки, хотя при загрузке как через плагин всё работает
imagesx(): supplied resource is not a valid Image resource
[2022-05-02 13:55:35] (ERROR @ core/model/phpthumb/phpthumb.class.php : 4045) PHP warning: imagesy(): supplied resource is not a valid Image resource
[2022-05-02 13:55:35] (ERROR @ core/model/phpthumb/phpthumb.class.php : 3370) PHP warning: imagecolortransparent(): supplied resource is not a valid Image resource
[2022-05-02 13:55:35] (ERROR @ core/model/phpthumb/phpthumb.class.php : 4475) PHP warning: imagecopy(): supplied resource is
. Путь выдаёт правильный прям от корня хоста до картинки
<?php

$dir_name = MODX_BASE_PATH."media";


function optimezieImg($pathToImage){
    global $modx;
    $params = array();
    if (exif_imagetype($pathToImage) == IMAGETYPE_JPEG)
    {

        $params = array(
            'w' => 1920,
            'f' => 'jpeg',
            'q' => 80,
        );

    }
    elseif (exif_imagetype($pathToImage) == IMAGETYPE_PNG)
    {

        $params = array(
            'w' => 1920,
            'f' => 'png',
            'q' => 80,
        );

    }
    elseif (exif_imagetype($pathToImage) == IMAGETYPE_GIF)
    {
        return;
    }

    $phpThumb = $modx->getService('modphpthumb', 'modPhpThumb', MODX_CORE_PATH . 'model/phpthumb/', array());
    $phpThumb->setSourceFilename($pathToImage);

    foreach ($params as $k => $v)
    {
        $phpThumb->setParameter($k, $v);
    }

    if ($phpThumb->GenerateThumbnail())
    {
        if (!$phpThumb->renderToFile($pathToImage))
        {
            $modx->log(1, 'Ошибка сохранения изображения в [' . $pathToImage . ']');
        }
    }
    else
    {
        $modx->log(1, print_r($phpThumb->debugmessages, 1));
    }    
}


function get_all_directory_and_files($dir){
 
     $dh = new DirectoryIterator($dir);   
     // Dirctary object 
     foreach ($dh as $item) {
         if (!$item->isDot()) {
            if ($item->isDir()) {
                get_all_directory_and_files("$dir/$item");
            } else {
                $currentFileExt = pathinfo($dir . "/" . $item->getFilename(), PATHINFO_EXTENSION);
                if($currentFileExt == 'jpg' || $currentFileExt == 'png' || $currentFileExt == 'jpeg'){
                    optimezieImg($dir . "/" . $item->getFilename());
                }
            }
         }
      }
   }
 
  # Call function 
  
get_all_directory_and_files($dir_name);
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
Главное чтобы при возвращении этого контента он был не обработан, чтобы все конструкции и вызовы были как есть
Vladimir
01 апреля 2022, 18:57
0
Подскажите пожалуйста, как допустим в очередь поставить на исполнение мой снипет, в снипете разные вещи, такие как допустим добавления минишоп товара, создание и заполнения опций, тех которые нет, создать, как записать в очередь мой снипет(созданный в админке или в файле)?
Vladimir
23 марта 2022, 11:56
0
Ошибка в посте, и происходит после кода как у вас, я читал доки.
Vladimir
16 марта 2022, 09:35
0
В шапке сайта сделал так {$modx->lexicon->load('sitetranslation:default')} и заработало