Поиск кода в шаблонах и чанках
20 июля 2021, 11:19
<?php $query = 'FormIt'; $output = []; $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; }
Читать дальше