Поиск кода в шаблонах и чанках
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;
}
Читать дальше
RSS
Объектная