Наверх

Шпаргалки по MODX RSS

Поиск кода в шаблонах и чанках

20 июля 2021, 11:19

<?php
$query = 'FormIt';

$output = [];

$snippets = $modx->getCollection('modSnippet', ['snippet:LIKE' => '%' . $query . '%']);
foreach ($snippets as $snippet) {
    $output[] = sprintf('<p>Snippet <a href="/manager/?a=element/snippet/update&id=%s">%s</a></p>', $snippet->id, $snippet->name);
}

$templates = $modx->getCollection('modTemplate', ['content:LIKE' => '%' . $query . '%']);
foreach ($templates as $template) {
    $output[] = sprintf('<p>Template <a href="/manager/?a=element/template/update&id=%s">%s</a></p>', $template->id, $template->templatename);
}

$chunks = $modx->getCollection('modChunk', ['snippet:LIKE' => '%' . $query . '%']);
foreach ($chunks as $chunk) {
    $output[] = sprintf('<p>Chunk <a href="/manager/?a=element/chunk/update&id=%s">%s</a></p>', $chunk->id, $chunk->name);
}

$resources = $modx->getCollection('modResource', ['content:LIKE' => '%' . $query . '%']);
foreach ($resources as $resource) {
    $output[] = sprintf('<p>Resource <a href="/manager/?a=resource/update&id=%s">%s</a></p>', $resource->id, $resource->pagetitle);
}

print implode(PHP_EOL, $output);

Читать дальше

Отправка писем через API MailGun

09 июня 2021, 16:00

Хук для FormIt — emailAPI вместо стандартного email

<?php
$tpl = $modx->getOption('emailTpl',$hook->formit->config,'');

/* get from name */
$emailFrom = $modx->getOption('emailFrom',$hook->formit->config,'');
if (empty($emailFrom)) {
    $emailFrom = !empty($fields['email']) ? $fields['email'] : $modx->getOption('emailsender');
}
$emailFromName = $modx->getOption('emailFromName',$hook->formit->config,$emailFrom);

/* get subject */
$useEmailFieldForSubject = $modx->getOption('emailUseFieldForSubject',$hook->formit->config,true);
if (!empty($fields['subject']) && $useEmailFieldForSubject) {
    $subject = $fields['subject'];
} else {
    $subject = $modx->getOption('emailSubject',$hook->formit->config,'');
}

/* check email to */
$emailTo = $modx->getOption('emailTo',$hook->formit->config,'');
$emailToName = $modx->getOption('emailToName',$hook->formit->config,$emailTo);
if (empty($emailTo)) {
    $hook->addError('emailTo',$modx->lexicon('formit.email_no_recipient'));
    $modx->log(modX::LOG_LEVEL_ERROR,'[FormIt] '.$modx->lexicon('formit.email_no_recipient'));
    return false;
}

/* compile message */
$origFields = $fields = $hook->getValues();

/** @var pdoFetch $pdoFetch */
$fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true);
$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true);
if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) {
    $pdoFetch = new $pdoClass($modx, []);
} else {
    return false;
}
$message = $pdoFetch->getChunk($tpl, $fields);


$apiUrl = 'https://api.eu.mailgun.net/v3/domain.ru/messages';

$client = $modx->getService('rest', 'rest.modRest');

$headers = ['Authorization' => 'Basic ' . base64_encode('api:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')];
$data = [
    'from' => $emailFromName . ' <' . $emailFrom . '>',
    'to' => $emailTo,
    'subject' => $subject,
    'html' => $message
];



/* cc */
$emailCC = $modx->getOption('emailCC',$hook->formit->config,'');
if (!empty($emailCC)) {
    $emailCCName = $modx->getOption('emailCCName',$hook->formit->config,'');
    $emailCC = explode(',',$emailCC);
    $emailCCName = explode(',',$emailCCName);
    $data['cc'] = array_shift($emailCCName) . ' <' . array_shift($emailCC) . '>';
}

/* bcc */
$emailBCC = $modx->getOption('emailBCC',$hook->formit->config,'');
if (!empty($emailBCC)) {
    $emailBCCName = $modx->getOption('emailBCCName',$hook->formit->config,'');
    $emailBCC = explode(',',$emailBCC);
    $emailBCCName = explode(',',$emailBCCName);
    $data['bcc'] = array_shift($emailBCCName) . ' <' . array_shift($emailBCC) . '>';
}

$response = $client->post($apiUrl, $data, $headers)->process();

return !empty($response['id']);

Читать дальше

mSearch2 с поиском по точному вхождению

27 мая 2021, 15:53

loadClass('msearch4', MODX_CORE_PATH . 'components/msearch4/model/msearch4/', false, true)) {return false;}
$mSearch4 = new mSearch4($modx, $scriptProperties);
$mSearch4->pdoTools->setConfig($scriptProperties);
$mSearch4->pdoTools->addTime('pdoTools loaded.');

if (empty($queryVar)) {$queryVar = 'query';}
if (empty($parentsVar)) {$parentsVar = 'parents';}
if (empty($minQuery)) {$minQuery = $modx->getOption('index_min_words_length', null, 3, true);}
if (empty($htagOpen)) {$htagOpen = '';}
if (empty($htagClose)) {$htagClose = '';}
if (empty($outputSeparator)) {$outputSeparator = "\n";}
if (empty($plPrefix)) {$plPrefix = 'mse2_';}
$returnIds = !empty($returnIds);
$fastMode = !empty($fastMode);

$class = 'modResource';
$found = array();
$output = null;
$query = !empty($_REQUEST[$queryVar])
	? $mSearch4->getQuery(rawurldecode($_REQUEST[$queryVar]))
	: '';

if (empty($resources)) {
	if (empty($query) && isset($_REQUEST[$queryVar])) {
		$output = $modx->lexicon('mse2_err_no_query');
	}
	elseif (empty($query) && !empty($forceSearch)) {
		$output = $modx->lexicon('mse2_err_no_query_var');
	}
	elseif (!empty($query) && !preg_match('/^[0-9]{2,}$/', $query) && mb_strlen($query,'UTF-8') < $minQuery) {
		$output = $modx->lexicon('mse2_err_min_query');
	}

	$modx->setPlaceholder($plPrefix.$queryVar, $query);

	if (!empty($output)) {
		return !$returnIds
			? $output
			: '';
	}
	elseif (!empty($query)) {
        $decodedQuery = str_replace(' ', '%', rawurldecode($_REQUEST[$queryVar]));
		$q = $modx->newQuery('modResource');
		$q->leftJoin('msProductData', 'Data', 'modResource.id = Data.id');
		$q->where([
			[
				'deleted' => false,
				'published' => true,
			],
			[
				'pagetitle:LIKE' => '%' . $decodedQuery . '%',
				'OR:longtitle:LIKE' => '%' . $decodedQuery . '%',
				'OR:description:LIKE' => '%' . $decodedQuery . '%',
				'OR:introtext:LIKE' => '%' . $decodedQuery . '%',
				'OR:content:LIKE' => '%' . $decodedQuery . '%',
				'OR:Data.article:LIKE' => '%' . $decodedQuery . '%'
			]
		]);
		$q->select('`modResource`.`id`');
		if ($q->prepare() && $q->stmt->execute()) {
        	$exact = $q->stmt->fetchAll(PDO::FETCH_COLUMN);
        }
		
		$found = $mSearch4->Search($query);
		$ids = array_merge($exact, array_keys($found));
		$resources = implode(',', $ids);
		if (empty($ids)) {
			if ($returnIds) {
				return '';
			}
			elseif (!empty($query)) {
				$output = $modx->lexicon('mse2_err_no_results');
			}
			if (!empty($tplWrapper) && !empty($wrapIfEmpty)) {
				$output = $mSearch4->pdoTools->getChunk(
					$tplWrapper,
					array(
						'output' => $output,
						'total' => 0,
						'query' => $query,
						'parents' => $modx->getPlaceholder($plPrefix.$parentsVar),
					),
					$fastMode
				);
			}
			if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) {
				$output .= '<pre class="mSearchLog">' . print_r($mSearch4->pdoTools->getTime(), 1) . '</pre>';
			}
			if (!empty($toPlaceholder)) {
				$modx->setPlaceholder($toPlaceholder, $output);
				return;
			}
			else {
				return $output;
			}
		}
	}
}
elseif (strpos($resources, '{') === 0) {
	$found = $modx->fromJSON($resources);
	$resources = implode(',', array_keys($found));
	unset($scriptProperties['resources']);
}
/*----------------------------------------------------------------------------------*/
if (empty($returnIds)) {
	// Joining tables
	$leftJoin = array(
		'mseIntro' => array(
			'class' => 'mseIntro',
			'alias' => 'Intro',
			'on' => $class . '.id = Intro.resource'
		)
	);
	// Fields to select
	$resourceColumns = !empty($includeContent)
		? $modx->getSelectColumns($class, $class)
		: $modx->getSelectColumns($class, $class, '', array('content'), true);
	$select = array(
		$class => $resourceColumns,
		'Intro' => 'intro'
	);
	$groupby = $class.'.id, Intro.intro';
} else {
	$leftJoin = array();
	$select = array($class . 'id');
	$groupby = $class.'.id';
}

// Add custom parameters
foreach (array('leftJoin', 'select') as $v) {
	if (!empty($scriptProperties[$v])) {
		$tmp = $modx->fromJSON($scriptProperties[$v]);
		if (is_array($tmp)) {
			$$v = array_merge($$v, $tmp);
		}
	}
	unset($scriptProperties[$v]);
}

// Default parameters
$default = array(
	'class' => $class,
	'leftJoin' => $leftJoin,
	'select' => $select,
	'groupby' => $groupby,
	'return' => !empty($returnIds)
		? 'ids'
		: 'data',
	'fastMode' => $fastMode,
	'nestedChunkPrefix' => 'msearch4_',
);
if (!empty($resources)) {
	$default['resources'] = is_array($resources)
		? implode(',', $resources)
		: $resources;
}

// Merge all properties and run!
$mSearch4->pdoTools->setConfig(array_merge($default, $scriptProperties), false);
$mSearch4->pdoTools->addTime('Query parameters are prepared.');
$rows = $mSearch4->pdoTools->run();

$log = '';
if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) {
	$log .= '<pre class="mSearchLog">' . print_r($mSearch4->pdoTools->getTime(), 1) . '</pre>';
}

// Processing results
if (!empty($returnIds)) {
	$modx->setPlaceholder('mSearch.log', $log);
	if (!empty($toPlaceholder)) {
		$modx->setPlaceholder($toPlaceholder, $rows);
		return '';
	}
	else {
		return $rows;
	}
}
elseif (!empty($rows) && is_array($rows)) {
	$output = array();
	foreach ($rows as $k => $row) {
		// Processing main fields
		$row['weight'] = isset($found[$row['id']]) ? $found[$row['id']] : '';
		$row['intro'] = $mSearch4->Highlight($row['intro'], $query, $htagOpen, $htagClose);

		$row['idx'] = $mSearch4->pdoTools->idx++;
		$tplRow = $mSearch4->pdoTools->defineChunk($row);
		$output[] .= empty($tplRow)
			? $mSearch4->pdoTools->getChunk('', $row)
			: $mSearch4->pdoTools->getChunk($tplRow, $row, $fastMode);
	}
	$mSearch4->pdoTools->addTime('Returning processed chunks');
	if (!empty($toSeparatePlaceholders)) {
		$output['log'] = $log;
		$modx->setPlaceholders($output, $toSeparatePlaceholders);
	}
	else {
		$output = implode($outputSeparator, $output) . $log;
	}
}
else {
	$output = $modx->lexicon('mse2_err_no_results') . $log;
}

// Return output
if (!empty($tplWrapper) && (!empty($wrapIfEmpty) || !empty($output))) {
	$output = $mSearch4->pdoTools->getChunk(
		$tplWrapper,
		array(
			'output' => $output,
			'total' => $modx->getPlaceholder($mSearch4->pdoTools->config['totalVar']),
			'query' => $modx->getPlaceholder($plPrefix.$queryVar),
			'parents' => $modx->getPlaceholder($plPrefix.$parentsVar),
		),
		$fastMode
	);
}

if (!empty($toPlaceholder)) {
	$modx->setPlaceholder($toPlaceholder, $output);
}
else {
	return $output;
}

Читать дальше

Изменение заголовка ресурса в админке на лету (OnDocFormRender)

03 июня 2020, 17:20

switch ($modx->event->name) {
    case 'OnDocFormRender':
        if ($mode != 'upd') return;
		if ($event = $modx->getObject('Event', ['resource_id' => $resource->id])) {
			$modx->controller->addHtml('<script>Ext.onReady(function(){
				setTimeout(function(){
					Ext.getCmp("modx-resource-pagetitle").setValue("' . addslashes($event->title) . '");
					Ext.getCmp("modx-resource-description").setValue("' . addslashes(strip_tags($event->description)) . '");
				}, 300);
			});</script>');
		}
        break;
}

Читать дальше

Зависимые комбобоксы в форме ExtJS

01 июня 2020, 11:24

Чтобы обновить список внутри одного комбобокса, нужно добавить listener в другой комбобокс:

listeners   : {
	'select'    : {
		fn          : function(tf, nv, ov) {
			Ext.getCmp('mycomponent-panel-object-model_id').reset();
			Ext.getCmp('mycomponent-panel-object-model_id').baseParams.brand_id = tf.getValue();
			Ext.getCmp('mycomponent-panel-object-model_id').getStore().load();
		},
		scope       : this
	}
}

Читать дальше

Combobox в виде динамических чекбоксов

01 июня 2020, 11:19

Поля в форме:

{   /* При изменении значения этого комбобокса будут перестраиваться чекбоксы */
	xtype           : 'mycomponent-combo-select',
	fieldLabel      : _('mycomponent.select'),
	name            : 'select_id',
	anchor          : '99%',
	allowBlank      : false,
	listeners       : {
		'select'    : {
			fn          : function(tf, nv, ov) {
				if (Ext.get('mycomponent-checkbox-dynamic')) {
					Ext.get('mycomponent-checkbox-dynamic').parent().parent().remove();
				}
				Ext.getCmp('mycomponent-panel-checkboxes-panel').add({
					xtype       : 'mycomponent-checkbox-dynamic',
					fieldLabel  : _('mycomponent.checkboxes'),
					id          : 'mycomponent-panel-checkbox-dynamic',
					anchor      : '99%',
					select_id   : tf.value
				});
				Ext.getCmp('mycomponent-panel-checkboxes-panel').doLayout();
			},
			scope       : this
		},

Читать дальше

Костыль для кеширования mFilter

13 декабря 2019, 09:08

Вызов mFilter2 только если кеша нет:
{var $get = ($.get | toJSON) | md5}
{* Проверяем, есть ли фильтр уже в кеше *}
{if !$filter = $_modx->cacheManager->get('msearch4/settings/' ~ $get ~ '/filters')}
    {set $filter = $_modx->runSnippet('!mFilter2', [
        'class' => 'msProduct',
        'parents' => $_modx->resource.id,
        'element' => 'msProducts',
    ])}

    {* Сохраняем фильтр в кеш *}
    {set $null = $_modx->cacheManager->set('msearch4/settings/' ~ $get ~ '/filters', $filter)}
{/if}

{* Подключаем JS-скрипты и прописываем config на странице *}
{'!mFilterJS' | snippet}

{* Показываем фильтр из кеша *}
{$filter}

Читать дальше

Парсинг новостей с картинками для сайта

17 июня 2019, 16:07

<?php
$url = 'https://site.ru/type/news';

require_once(MODX_CORE_PATH . 'components/simplehtmldom/simple-html-dom.php');
$html = file_get_html($url);
$teasers = $html->find('.teaser');
$news = [];
foreach ($teasers as $teaser) {
    $link = $teaser->find('a', 0);
    $date = $teaser->find('.date', 0);
    $parser = date_create_from_format('d.m.y', trim($date->plaintext));
    $publishedon = date_format($parser, 'Y-m-d');
    $news[] = ['link' => 'https://site.ru' . $link->href, 'publishedon' => $publishedon, 'pagetitle' => $link->plaintext];
}
foreach ($news as $page) {
    $page['parent'] = 15;
    $html = file_get_html($page['link']);
    $content = $html->find('.body', 0);
    $imgs = $content->find('img');
    foreach ($imgs as $img) {
        if (strpos($img->src, 'http') !== false) {
            $url = $img->src;
        } else {
            $url = 'https://site.ru' . $img->src;
        }
        $name = md5(uniqid()) . '.' . pathinfo($url, PATHINFO_EXTENSION);
        $path = MODX_BASE_PATH . 'assets/images/archive/' . $name;
        file_put_contents($path, file_get_contents($url));
        $img->src = '/assets/images/archive/' . $name;
        if (!isset($page['img']) || !$page['img']) {
            $page['tv1'] = $img->src;
        }
    }
    if ($olds = $content->find('.field-field-old-filename',0)) {
        $olds->outertext = '';
    }
    $page['content'] = $content->innertext;
    if (!$res = $modx->getObject('modResource', ['parent' => $page['parent'], 'pagetitle' => $page['pagetitle'], 'publishedon' => strtotime($page['publishedon'])])) {
        if ($count = $modx->getCount('modResource', ['parent' => $page['parent'], 'pagetitle' => $page['pagetitle']])) {
            $page['alias'] = $page['pagetitle'] . '-' . $count;
            print $page['alias'] . ' - ';
        }
        $response = $modx->runProcessor('resource/create', $page);
        if ($response->isError()) {
            echo '<p>' . $page['pagetitle'] . '</p>';
            return $modx->error->failure($response->getMessage());
        } else {
            echo '<p>Resource created</p>';
        }
    } else {
        echo '<p>Resource found</p>';
    }
}

Читать дальше

Правила сервера для MODX Cloud

23 мая 2019, 16:34

location ~* \.(?:ico|css|js|jpe?g|png|gif|svg|pdf|mov|mp4|mp3|woff)$ {
    try_files $uri $uri/ @modx-rewrite;     
    expires 7d;
    add_header Pragma public;
    add_header Cache-Control "public";
    gzip_vary on;
}
if ($scheme != "https") {
    return 301 https://www.webslite.com$request_uri;
}
if ($host != "www.groepenkastmontagenoord.nl") {
    rewrite ^ https://www.webslite.com$request_uri permanent;
}
location / {
    try_files $uri $uri/ @modx-rewrite;
}
location = /robots.txt {
    try_files $uri $uri/ @modx-rewrite;
}

Читать дальше

Удалить все вирусы, найденные ai-bolit'ом

25 апреля 2019, 20:09

<?php
@ini_set('display_errors', 1);
echo 'Start' . PHP_EOL;
$report_file = __DIR__ . '/report.json';
if (!file_exists($report_file)) {
    echo 'Report not found' . PHP_EOL;
    return;
}
$report_json = file_get_contents($report_file);
if (!$report = json_decode($report_json, true)) {
    echo 'Can not decode JSON' . PHP_EOL;
    return;
}
if (isset($report['php_malware'])) {
    foreach ($report['php_malware'] as $php_malware) {
        echo $php_malware['fn'] . PHP_EOL;
        //unlink($php_malware['fn']);
    }
} else {
    echo 'Php Malware not found' . PHP_EOL;
}
if (isset($report['js_malware'])) {
    foreach ($report['js_malware'] as $js_malware) {
        echo $js_malware['fn'] . PHP_EOL;
        //unlink($js_malware['fn']);
    }
} else {
    echo 'JS Malware not found' . PHP_EOL;
}

Читать дальше

Авторизация

через сервис Loginza:


Шаблоны MODX

1 2 Дальше »

Объектная
модель
MODX