Про это лучше у Василия Наумкина спросить, его компоненты, я их особо не ковырял.

Оплатить можно напрямую в PayPal на ящик info@modxclub.ru с указанием «За доступ к репозиторию» и логина в Клубе.

я про то что бы у вас покупку оплатить через PayPal.

Документации нет. Есть только куча статей здесь и возможность задавать вопросы. Про PayPal отвечал вам здесь, пока ничего не поменялось, никто не заказывал. Для поиска у нас используется modSearch, но пока он еще не перекрывает все потребности, надо четче обрисовывать какие он вам задачи должен выполнять.

На сайте, который я сопровождаю, есть страничка с галереями видео, размещенного на youtube. Изначально я сделал ее с использованием MIGX, но на днях выяснилось, что постоянно добавляются новые видеофайлы. Вариант с ручным добавлением перестал нравиться. Галереи организованы на youtube в виде плейлистов, и это позволяет строить их на сайте динамически, сразу из youtube. Здесь хорошо описано, как получить список видеороликов из плейлиста по его идентификатору. Теперь на сайте достаточно просто хранить массив идентификаторов списков видео, и при пополнении коллекции на youtube это будет автоматически отражаться на сайте.

В шаблоне Smarty это может выглядеть так: {$albums=json_decode($modx->resource->getTVValue('video_gallery'),1)} {* список идентификаторов плейлистов } {foreach $albums as $album} <h2>{$album.title}</h2> {$params=['list_id'=>$album.list_id]} {processor action='web/youtube/getlist' ns=modxsite params=$params assign=items} <ul> {foreach $items.object as $item} <li class="item"> <a class="fancybox fancybox.iframe" title="{$item.title}" href="http://www.youtube.com/embed/{$item.url}?autoplay=1" rel="gallery_{$album.MIGX_id}"></a> <div class="img"> <img src="{thumb input="{$item.imgs.all[0]}" options='w=280&h=185&zc=1'}" alt="{$item.title}"> </div> </li> {/foreach} </ul> {/foreach} Код процессора: <?php /*

  • Получить список последних видео заданного плейлиста
  • @param string $list_id идентификатор плейлиста
  • @param int $limit по сколько позиций обрабатывать (не всегда нужно содержимое всего плейлиста)
  • @param int $cache_life время жизни кеша в секундах (чтобы не получить бан IP за рилтайм запросы)
  • @return array список найденных видео, не более $limit штук */

class modWebYoutubeGetlistProcessor extends modProcessor{ // Ключ для запросов protected $api_key = 'ВАШ-API-KEY';

public function initialize(){
    $this->setDefaultProperties(array(
        'list_id'   => '',
        'limit'=>50,
        'cache_life'=>3600
    ));
    return parent::initialize();
}

public function process() {
    # файл, содержащий копию ленты
    $cache_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . $this->getProperty('list_id') . '.json';


    # специальный адрес, отвечающий за выдачу фида
    $url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet'
        . '&playlistId=' . $this->getProperty('list_id')
        . '&maxResults=' . $this->getProperty('limit')
        . '&key=' . $this->api_key;

    # если кеш устарел...
    if (time() - @filemtime($cache_file) >= $this->getProperty('cache_life')) {
        # ...пытаемся обновить его
        $buf = file_get_contents($url);
        # в случае успеха запишем в файл обновлённые данные
        # проверка на пустоту нужна для того, чтобы не запороть кеш при ошибке
        if ($buf) file_put_contents($cache_file, $buf);
    }

    # если фид получить не удалось...
    if (empty($buf)) {
        # ...просто берём содержимое из кеша
        $buf = file_get_contents($cache_file);
    }

    # декодируем JSON данные
    $json = json_decode($buf, 1);
    $arr = array();

    # если данных нет — на выход
    if (empty($json['items'])) {
        return $this->failure('', $arr);
    }

    # перебор доступных значений
    foreach ($json['items'] as $v) {
        $t = array(
            'title' => $v['snippet']['title'], # название
            'desc'  => $v['snippet']['description'], # описание
            'url'   => $v['snippet']['resourceId']['videoId'], # адрес
        );

        # изображения
        if (isset($v['snippet']['thumbnails'])) {
            $t['imgs']['all'] = array();
            foreach ($v['snippet']['thumbnails'] as $name => $item) {
                $t['imgs']['all'][] = $item['url'];
                $wh = $item['width'] . 'x' . $item['height'];
                $t['imgs'][$wh][0] = $item['url'];
            }
        }
        $arr[] = $t;
    }
    return $this->success('',$arr);
}    

}

return 'modWebYoutubeGetlistProcessor'; Структура возвращаемого списка: [object] => Array ( [0] => Array ( [title] => Обработка мебельного фасада первым слоем высокоглянцевого лака [desc] => Описание видео [url] => Lx-QWKgVLLg [imgs] => Array ( [all] => Array ( [0] => https://i.ytimg.com/vi/Lx-QWKgVLLg/default.jpg [1] => https://i.ytimg.com/vi/Lx-QWKgVLLg/mqdefault.jpg [2] => https://i.ytimg.com/vi/Lx-QWKgVLLg/hqdefault.jpg )

					[120x90] => Array
						(
							[0] => https://i.ytimg.com/vi/Lx-QWKgVLLg/default.jpg
						)

					[320x180] => Array
						(
							[0] => https://i.ytimg.com/vi/Lx-QWKgVLLg/mqdefault.jpg
						)

					[480x360] => Array
						(
							[0] => https://i.ytimg.com/vi/Lx-QWKgVLLg/hqdefault.jpg
						)

				)

		)

	[1] => Array
		(
			[title] => Покрытие мебельного фасада высокоглянцевой эмалью, второй этап.
	. . . Результат можно посмотреть здесь.

Сразу скажу, что без хака xPDO такого не умеет делать. Дело в том, что при перечислении нескольких таблиц в конструкции DELETE FROM надо явно указывать из каких именно перечисленных таблиц надо выполнить удаление. То есть вот классический запрос удаления записей из одной таблицы: DELETE FROM table; Такой запрос средствами xPDO строится запросто. $q = $modx->newQuery('class_name'); $q->command('DELETE'); $q->prepare() ->execute(); А вот при перечислении таблиц SQL-конструкция выглядит так: DELETE table1, table2 FROM table1, table2, table3 Так вот этого перечисления table1, table2 xPDO не умеет делать. Перечисление выполняется только в случае команд SELECT и UPDATE. А при DELETE ничего не подставляется. В общем, после нескольких экспериментов я пришел вот к такому коду: <?php print '<pre>';

$table = $modx->getTableName("modTemplateVarResource");

$q = $this->modx->newQuery("modTemplateVarResource");

$q->setClassAlias('');

$q->innerJoin('modResource', 'Resource');

$q->query['command']= "DELETE {$table}";

$q->where(array( "tmplvarid" => 11, ));

$s = $q->prepare();

$s->execute(); На выходе получается вот такой работающий SQL: DELETE modx_site_tmplvar_contentvalues FROM modx_site_tmplvar_contentvalues JOIN modx_site_content Resource ON .`contentid` = `Resource`.`id` WHERE ( `modx_site_tmplvar_contentvalues`.`tmplvarid` = 11) И вот здесь два момента: 1. Не получается использовать $q->command(«DELETE {$table}»); Дело в том, что xPDO переводит это в верхний регистр, а так как название таблицы формируется с наклонными кавычками (что мускулом воспринимается с учетом регистра), то мы получим сообщение об отсутствующей таблице. DELETE `MODX_SITE_TMPLVAR_CONTENTVALUES` FROM `modx_site_tmplvar_contentvalues` JOIN `modx_site_content` `Resource` ON .contentid = Resource.id WHERE ( modx_site_tmplvar_contentvalues.tmplvarid = 11 ) Array ( [0] => 42S02 [1] => 1109 [2] => Unknown table 'MODX_SITE_TMPLVAR_CONTENTVALUES' in MULTI DELETE ) 2. Нельзя забывать про сброс алиаса $q->setClassAlias(''), иначе у нас условия пойдут с несуществующим алиасом таблицы. DELETE modx_site_tmplvar_contentvalues FROM modx_site_tmplvar_contentvalues JOIN modx_site_content Resource ON modTemplateVarResource.contentid = Resource.id WHERE ( modx_site_tmplvar_contentvalues.tmplvarid = 11 AND modx_site_tmplvar_contentvalues.value = '9999999999999999999' ) Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column 'modTemplateVarResource.contentid' in 'on clause' ) P.S. зачем мне такое вообще нужно было? Мне надо было удалить ТВшки только определенных документов, а для этого или надо было все ID-шники сначала получать, затем в IN(...) скармливать (а я такое не люблю), или формировать конструкцию WHERE EXISTS или еще что-то в подобном виде.

а если сделать выбор — хочешь оплати подписку, хочешь отдельно пакеты оплачивай?

Лайфхак, чтобы json нормально работал без ошибок в смарти надо проьелы поставить { «isfolder»: «1» }

Топик: pdoMenu + Smarty

Ошибка возникает. Вот этот вариант работает нормально: {block name="sub_menu"} {if $navdata = $modx->runSnippet("pdoMenu", [ 'parents' => $modx->resource->parent, 'level' => 1, 'where' => json_encode([ "isfolder" => 1 ]) ])} <nav class="sub-menu">{$navdata}</nav> {/if} {/block}

Топик: pdoMenu + Smarty