Vladimir

Vladimir

С нами с 25 июня 2021; Место в рейтинге пользователей: #243
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);
    }

}
04 июля 2022, 14:00
0
У меня есть 1 вариант, но он костыльный, пройтись по всем товарам, и положить их в спец группу ресурсов по бренду, и потом эту группу указать
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 '';
23 июня 2022, 12:34
0
Как вывести скидку для всех тоже хз
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 '';
23 июня 2022, 11:58
0
Такой очевидный вопрос, но в доках нет решения
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;
}
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>
А это получается что я получаю именно контент самого ресурса а не контент шаблона перед рендером
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';
03 мая 2022, 11:25
0
Можно как их оптимизировать разом? вверху полу рабочий скрипт, собирает все картинки но выдаёт ошибку, мол плохие картинки. Использовать phpthumbof и так далее через тэги, нет не выход, с ними постоянно проблемы с кэшем, что делает только хуже, по этому нужно сделать чтобы все существующие картинки прогнал через сам себя встроенный phpthumb, великолепно справляется со своей работой, в качестве плагина на загрузку файлов
03 мая 2022, 11:02
0
Есть у кого-нибудь идеи?
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);
29 апреля 2022, 08:38
0
$res = $modx->getObject('modTemplate', 7);
echo $res->getContent();
Оказалось что шаблон который я просил был пустым, сори
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);
}
29 апреля 2022, 08:08
0
Пытался так но не получается, никак не могу получить сами данные
$res = $modx->getObject('modTemplate', 8);
echo $res->getSource();
echo print_r(get_class_methods($res));
29 апреля 2022, 07:51
0
Главное чтобы при возвращении этого контента он был не обработан, чтобы все конструкции и вызовы были как есть
01 апреля 2022, 18:57
0
Подскажите пожалуйста, как допустим в очередь поставить на исполнение мой снипет, в снипете разные вещи, такие как допустим добавления минишоп товара, создание и заполнения опций, тех которые нет, создать, как записать в очередь мой снипет(созданный в админке или в файле)?
23 марта 2022, 11:56
0
Ошибка в посте, и происходит после кода как у вас, я читал доки.
16 марта 2022, 09:35
0
В шапке сайта сделал так {$modx->lexicon->load('sitetranslation:default')} и заработало