Александр

Александр

С нами с 07 мая 2013; Место в рейтинге пользователей: #361
Денис
11 декабря 2018, 19:19
5
+5
Судя по исходникам просто так не выйдет.
Создайте плагин и повесьте на событие OnManagerPageBeforeRender
После вставьте следующий код:
<?php
switch ($modx->event->name) {
	case 'OnManagerPageBeforeRender':
        if($controller->config['controller'] == "mgr/orders") {
            if ($miniShop2 = $modx->getService('miniShop2')) {
                $modx->controller->addHtml('<style>.x-grid3-col-order-product-image img {width:40px;display:block;}</style>');
                $modx->controller->addHtml('
                    <script>
                        Ext.onReady(function(){
                            var originalGetColumns = miniShop2.grid.OrderProducts.prototype.getColumns;
                            miniShop2.config["default_thumb"] = miniShop2.config["defaultThumb"];
                            Ext.override(miniShop2.grid.OrderProducts,{
                                getColumns: function () {
                                	var imgFields = [ "product_thumb", "product_image" ];
                                    var columns = originalGetColumns.apply(this);
                                    for(var i=0; i<columns.length; i++){
                                    	if(imgFields.indexOf(columns[i]["dataIndex"]) != -1){
                                    		columns[i]["renderer"] = miniShop2.utils.renderImage;
                                    		columns[i]["id"] = "order-product-image";
                                    	}
                                    }
                                    return columns;
                                }
                            });
                        });
                    </script>
                ');
            }
        }
    break;
}

Если в системной настройке ms2_order_product_fields указан product_thumb или product_image, то вы увидите уже не ссылку, а картинку.
Наумов Алексей
29 августа 2018, 11:23
2
+1
Есть такое решение у меня:

1) Создаем TV changeTemplate и назначаем его категориям.
2) Создает плагин changeTemplate, на событие OnDocFormRender (код ниже)
3) Теперь в TV мы можем написать:
«2» — всем дочерним ресурсам будет назначен шаблон 2
«2,3» — первый уровень дочерних ресурсов будет с шаблоном 2, второй уровень и далее — с шаблоном 3
ну и т.д., «2,3,4»
4) Но данный плагин сработает на все, в том числе и на категории, а не только на товары, если это нужно исправить — внесите изменения в код.

<?php
/**
* =========================
* ChangeTemplate
* =========================
*
* Plugin for MODX Revolution
* Set which template is inherited by children 
* documents of a certain parent document
*
* Author:
* Marc Loehe (boundaryfunctions)
* marcloehe.de
*
* Modified by:
* Lorenzo Stanco <lorenzo.stanco@gmail.com>
* Lorenzostanco.com
*
* Usage:
*
* 1. Paste this as new plugin and connect it to system event
* 'OnDocFormRender'.
*
* 2. Assign a new TV 'changeTemplate' to each template
* for which you want to define the default children template.
*
* 3. Set the newly created TV to input type "Text" 
*
* 4. Open a document and in the 'changeTemplate' TV type a 
* comma separated list of template IDs.
*
* 5. Have fun!
*
*/
 
// Check Event
if ($modx->event->name == 'OnDocFormRender' && $mode == modSystemEvent::MODE_NEW) {
   
  $id = empty($_REQUEST['id']) ? false : $_REQUEST['id'];
  $id = empty($id) ? (empty($_REQUEST['parent']) ? false : $_REQUEST['parent']) : $_REQUEST['parent'];
  // Get current document ID
  if ($id) {
 
    // Document Chain
    $resources = array($id);
 
    // Get parent ID
    foreach ($modx->getParentIds($id, 10, array('context' => $_REQUEST['context_key'])) as $parentId) {
      if ($parentId) array_push($resources, $parentId);
    }
     
    // Search changeTemplate in the chain
    $level = 0;
    $childTemplates = array();
    foreach ($resources as $resourceId) {
      $resource = $modx->getObject('modResource', $resourceId);
      if ($childTemplatesTV = $resource->getTVValue('changeTemplate')) {
         
        // Create template array for each tree level
        $childTemplates = @explode(',', $childTemplatesTV);
        if (empty($childTemplates)) break;
        foreach ($childTemplates as $k => $v) $childTemplates[$k] = intval(trim($v));
         
        break;
 
      }
 
      $level++;
 
    }
 
    // Set template based on tree level
    if (!empty($childTemplates)) {
      $useTemplate = $childTemplates[$level];
      if (!empty($useTemplate)) {
        
        // Set default template
        if (isset($modx->controller)) {
          $modx->controller->setProperty('template', $useTemplate);
        } else { // modX < 2.2.0
          $_REQUEST['template'] = $useTemplate;
        }
 
      }
    }
 
  }
 
}
Наумов Алексей
01 февраля 2018, 16:46
4
+4
hook для Formit, отсылает сообщения через sms.ru, вызываем перед хуком email:

Предварительно создаем настройки
sms_ru_api_id — api ключ, который дадут при регистрации на сайте
manager_phone — номер телефона получателя

<?php
// API id
$api_id = $modx->getOption('sms_ru_api_id', null, null);
if(empty($api_id)) {
    $modx->log(xPDO::LOG_LEVEL_ERROR,'SMS.RU hook: empty API ID!.');
    // так как это hook, то даже в случае неудачи возвращаем true
    return true;
}

// Support phone number
$phone = $modx->getOption('manager_phone', null, null);
if(empty($phone)) {
    // так как это hook, то даже в случае неудачи возвращаем true
    return true;
}

$ch = curl_init("https://sms.ru/sms/send");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(

    "api_id"        =>  $api_id,
    "to"            =>  $phone,
    "text"      =>  "ТЕКСТ СООБЩЕНИЯ",

));
$body = curl_exec($ch);
curl_close($ch);

return true;
Володя
14 декабря 2017, 16:22
2
+1
в связанных комбиках слушать select и выставлять в зависимые комбики нужный параметр.
listeners: {
  select: {
    fn: function (r) {
       this.handleChange();
    },
    scope: this
    }
}
Если связей много то можно навесить общую функцию и в ней выставлять нужные поля.

handleChange: function (change) {
        var f = this.fp.getForm();
        var _field1 = f.findField('field1');
        var _field2 = f.findField('field2');

        _field2.baseParams.param = _field1.getValue();
	//перегрузить стор
        _field2.store.load();
    }
Ilya Ev
26 октября 2017, 18:47
1
+1
в муках родился запрос, делюсь думаю будет полезно, ктото спрашивал тоже. Вроде работает
'leftJoin' => '{

		        "Pprice" : {

			"class" : "cfField",

			"alias" : "Pprice",

			"on" : "Pprice.city_id = ' ~ $_modx->getPlaceholder('cf.current_city.id') ~ ' AND Pprice.placeholder = CONCAT(\'[pre]\', msProduct.id, \'_price[/pre]\')"
		}
	}',
'select' => '{ "Pprice" : "Pprice.value" }',
'where' => '{"Pprice.value:>":"0"}'
исключает все товары города у которых не выставлены цены.

Остальное тоже решил. Кроме переключения города по ссылке без домена. Буду надеется автор добавит данную возможность в пакет.
Роман Ильин
12 сентября 2017, 23:09
12
+2
Сниппет для удаления старых версий:

<?php
/**
 * versionCleanX
 *
 * @author Scott Pronych, September 27, 2013
 *
 * DESCRIPTION
 *
 * For use with VersionX to delete old content
 *
 * PROPERTIES:
 *
 * &contentType - can be resource, chunk, plugin, snippet, template, or templatevar
 * &maxVersions - integer value for max number of versions you would like to keep
 *
 * USAGE:
 *
 * [[!versionCleanX? &contentType=`resource` &maxVersions=`10`]]
 *
 */
 
$cx_type = $modx->getOption('contentType', $scriptProperties, 'resource');
$cx_max = (int) $modx->getOption('maxVersions', $scriptProperties, 5);
 
$GLOBALS['count'] = 1;
$GLOBALS['total'] = 0;
$GLOBALS['deleted'] = 0;
$GLOBALS['page_total'] = 0;
$GLOBALS['page_deleted'] = 0;
$GLOBALS['page_name'] = '';
$GLOBALS['prev_content_id'] = 0;
$GLOBALS['prev_version_id'] = 0;
 
switch ($cx_type) {
    case 'chunk':
        $name = 'name';
        break;
    case 'plugin':
        $name = 'name';
        break;
    case 'snippet':
        $name = 'name';
        break;
    case 'template':
        $name = 'templatename';
        break;
    case 'templatevar':
        $name = 'name';
        break;
    default:
        $name = 'title';
        $cx_type = 'resource';
}
 
$GLOBALS['db_name'] = 'modx_versionx_' . $cx_type;
 
function delete_row ($id) {
    global $modx;
    $query = "DELETE FROM `" . $GLOBALS['db_name'] . "` WHERE version_id = '" . $id . "'";
    $result = $modx->query($query);
    if (!is_object($result)) return false;
    else {
        $GLOBALS['deleted']++;
        $GLOBALS['page_deleted']++;
        $GLOBALS['page_total']++;
        $GLOBALS['total']++;
        $GLOBALS['count']++;
        return true;
    }
}
 
function log_row () {
    $GLOBALS['data'] .= '<tr><td>' . $GLOBALS['page_name'] . '</td><td>' . $GLOBALS['page_total'] . '</td><td>' . $GLOBALS['page_deleted'] . "</td></tr>\n";
    $GLOBALS['page_deleted'] = 0;
    $GLOBALS['page_total'] = 1;
    $GLOBALS['count'] = 1;
}
 
$query = "SELECT version_id, content_id, " . $name . " AS page_title FROM `" . $GLOBALS['db_name'] . "` ORDER BY content_id ASC, version_id DESC";
 
$GLOBALS['data'] = '';
$output = 'An error occurred: ';
$versionx = $modx->query($query);
if (!is_object($versionx)) {
   return $output . 'query error ' . print_r($modx->errorInfo(), true);
}
else {
 
while($row = $versionx->fetch(PDO::FETCH_ASSOC)) {
    // New content_id so reset
    if ($prev_content_id == 0) {
        $prev_content_id = $row['content_id'];
        $prev_version_id = $row['version_id'];
        $GLOBALS['total']++;
        $GLOBALS['page_total']++;
        $GLOBALS['count']++;
        $GLOBALS['page_name'] = $row['page_title'];
    }
    elseif ($prev_content_id != $row['content_id']) {
        if ($GLOBALS['count'] > $cx_max) {
            if (!delete_row($prev_version_id)) return $output .  'deleting row for ' . $GLOBALS['page_name'] . ' Row: ' . $prev_content_id . ' ' . print_r($modx->errorInfo(), true);
            $GLOBALS['page_total']--;
 
        }
        else {
            $GLOBALS['total']++;
            $GLOBALS['count']++;
        }
        log_row();
        $prev_content_id = $row['content_id'];
        $prev_version_id = $row['version_id'];
        $GLOBALS['page_name'] = $row['page_title'];
    }
    // Content count is over the max so delete previous row
    elseif ($GLOBALS['count'] > $cx_max) {
            delete_row($prev_version_id);
            $prev_content_id = $row['content_id'];
            $prev_version_id = $row['version_id'];
    }
    else {
        $GLOBALS['count']++;
        $GLOBALS['page_total']++;
        $GLOBALS['total']++;
        $prev_content_id = $row['content_id'];
        $prev_version_id = $row['version_id'];
    }
}
log_row();
 
if ($GLOBALS['data'] != '') {
$output = '<h3>VersionX Cleanup for ' . $GLOBALS['db_name'] . '</h3>
<p>Total records: <strong>' . $GLOBALS['total'] . '</strong>
Total deleted: <strong>' . $GLOBALS['deleted'] . '</strong></p>
<table class="table table-striped">
<thead>
<tr>
<th>Page name</th>
<th>Total found</th>
<th>Deleted</th>
</tr>
</thead>
<tbody>
' . $GLOBALS['data'] .  '</tbody></table>
';
}
else $output = 'Error: no data found.';
}
 
$query = "OPTIMIZE TABLE `" . $GLOBALS['db_name'] . "`";
$versionx = $modx->query($query);
if (!is_object($versionx)) {
   $output = 'Optimize error ' . print_r($modx->errorInfo(), true) . $output;
}
 
return $output;


Вызывать так:
[[!versionCleanX? &contentType=`resource` &maxVersions=`10`]]
Николай Загумённов
02 сентября 2017, 12:19
2
+2
Хочу поделиться сниппетом, аналог pdoField, так как я часто пользуюсь pdoField.

Сниппет getLocalizatorField

<?php
$sp = &$scriptProperties;

$resource_id = $modx->getOption('resource_id', $sp, $modx->resource->id);
$field = $modx->getOption('field', $sp, 'pagetitle');
$key = $modx->getOption('key', $sp, $modx->getOption('cultureKey'));

$q = $modx->newQuery( "localizatorContent" );
$q->where( array( "`resource_id` = '" . $resource_id . "'", "`key` = '" . $key . "'" ) );
$q->select( array( $field ) );
$s = $q->prepare();  // print $q->toSQL(); die;
$s->execute();
$array = $s->fetch(PDO::FETCH_ASSOC);
$field_value = $array[$field];

return $field_value;
Вызов:

{'getLocalizatorField' | snippet : [ 
       'resource_id' => 20,
       'field' => 'content'
 ]}
Василий Столейков
05 февраля 2017, 17:13
2
0
Спасибо, очень полезно на будущее!
Я уже вывел логику из класса, выкинул всё лишнее и использую сниппет goo_gl следующим образом:
<?php
$key = '__API__'; // Ваш API ключ

define('API_KEY', $key);
define('API_URL', 'https://www.googleapis.com/urlshortener/v1');
 
// создаём cURL соединение
$curl_connection = curl_init(
    sprintf('%s/url?key=%s', API_URL, API_KEY)
);
// попросить cURL возвращать данные, а не выводить
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
// создадим данные для перекодировки в JSON
$requestData = array(
   'longUrl' => $input
);
// изменим тип запроса на POST
curl_setopt($curl_connection, CURLOPT_POST, true);
// установим тип контента JSON
curl_setopt($curl_connection, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
// передадим данные JSON в тело POST запроса
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, json_encode($requestData));
// выполним запрос
$data = curl_exec($curl_connection);
curl_close($curl_connection);
// перекодирум и возвратим данные
$response = json_decode($data, true);

// return $response['longUrl']; // Длинная ссылка
return $response['id'];


Использую его как модификатор:
{$url|goo_gl}
Алексей Федоров
08 января 2017, 20:48
2
+3
Сталкивался)) Вот инструкция, помогает получить больше информации об источнике ошибки. Почему modx без пинка в виде правки кода это не делает понять не могу до сих пор
Sergey
15 сентября 2016, 09:40
1
+2
Расписано здесь.

Слегка модифицировал:
public function toJSON($array) {
        $encoded= '';
        if ( is_array($array) ) {
            if (!function_exists('json_encode')) {
                if (@ include_once (XPDO_CORE_PATH . 'json/JSON.php')) {
                    $json = new Services_JSON();
                    $encoded= $json->encode($array);
                }
            } else {
                $encoded= json_encode($array);
	            if (json_last_error() == JSON_ERROR_UTF8)
	                {   $array = self::arrayEncodeUTF8($array);
                        $encoded= json_encode($array); }
            }
          }
        return $encoded;
    }

    public static function arrayEncodeUTF8($array)
    {   foreach($array as $key => $value)
        {   if (!is_array($value))
            {   if (is_string($value))
                { json_encode($value);
                  if (json_last_error() == JSON_ERROR_UTF8)
                  { $array[$key] = iconv('CP1251', 'UTF-8', $value); }
                }
            } else { $array[$key] = self::arrayEncodeUTF8($value); }
        }
        return $array;
    }
— Win,XAMPP, PHP 7